/********************************************************
*
* 文 件 名： DeviceRelayDataProcess.c
* 版权说明： 北京交控科技有限公司
* 创建时间： 2012-09-21
* 作    者： 联锁组
* 功能描述： 设备间数据管理
* 函数包括：
* 使用注意：
* 修改记录：
*
********************************************************/


#include "DeviceRelayDataProcess.h"
#include "EnvelopeManageAPI.h"
#include "EnvelopeManage.h"
#include "SignalConfigDataManage.h"
#include "../SGBJ/SGBJConfigDataManage.h"
#include "InterlockCommonManage.h"
#include "../Section/PhysicalSectionConfigDataManage.h"
#include "AxisAssertManage.h"
#include "AxisAssertDataPrepare.h"
#include "dquCIInit.h"

/*信号机继电器延时驱动时间(周期)*/
#define SIG_RELAY_DRV_DELAY_TIME ((UINT32)3)

void SpksRelayToPhySecFlockStatus(void);
UINT8 GetCloseSignaleColor(const UINT8 color);

/* @brief 判断所有占用物理区段是否均有占用计轴区段 */
static void IsOccPhyHasOccAc(void);


/*
* 功能描述： 驱动指定道岔ID继电器
* 参数说明： void
* 返回值  ： 无
*/
static void DriveSwitchRelayState(const UINT16 switchId, const UINT8 driveSwitchPos);
/* zt 删除单轨相关代码 2022-02-15 */
/******************************信号机相关继电器处理****************************/



/******************************OC道岔设备输出处理****************************/

/*
* 功能描述： OC道岔设备输出处理
* 参数说明： void
* 返回值  ： void
*/
void OcSwitchDeviceOutput(void)
{
	UINT16 switchCurSum = 0u;	 /*道岔总数目*/
	UINT8 localCiId = 0u;         /*本地联锁ID*/

	UINT16 switchId = 0u;	     /*道岔ID*/
	UINT8 belongCiId = 0u;        /*道岔所属联锁ID*/
	UINT16 ii = 0u;               /*循环索引*/

	UINT8 curSwitchPos = SWITCH_POSITION_INVALID;		/*道岔当前位置*/
	UINT8 driveSwitchPos = SWITCH_DRIVE_POS_INVALID;	/*驱动道岔位置*/
	UINT8 curExpDrvSwitchPos = SWITCH_DRIVE_POS_INVALID;	/*本周期期望驱动道岔位置*/
	UINT8 preExpDrvSwitchPos = SWITCH_DRIVE_POS_INVALID;	/*上周期期望驱动道岔位置*/

	UINT8 timeState = CI_TIME_NO;						/*驱动道岔超时状态*/

	UINT8 switDrivPeakTimeState = SWIT_DRIV_PEAK_TIME_FALSE;	/*道岔驱动高峰期状态*/

	UINT8 preSwitchDrivingState = SWIT_DRIV_IDLE_TIME;	/*之前的道岔驱动状态*/
	UINT8 curSwitchDrivingState = SWIT_DRIV_IDLE_TIME;	/*当前的道岔驱动状态*/

	UINT8 SwitchDanCaoPosition = SWITCH_POSITION_INVALID;/*道岔单操位置*/
	UINT8 lineIdentity = GetCiFunctionSwitchConfig(LINE_RAILWAY_TYPE_CONF);/*获取线路标识:0x55:城轨交通；0xAA:单轨交通*/
	UINT32 curNum = Get2oo2CurCycleNum();
	UINT8 chSwitchJichaState = 0U;/*道岔挤岔状态*/

	switchCurSum = GetSwitchCurSum();					/*获取道岔总数*/
	localCiId = GetSystemParaLocalCiId();				/*获取本机联锁ID*/


	/*单操道岔逻辑处理*/
	for (ii = 0u; ii < switchCurSum; ii++)
	{
		switchId = GetSwitchId(ii); 					 /*获取道岔ID*/

		if ((0u < switchId) && (switchId < SWITCH_SUM_MAX))
		{
			belongCiId = GetSwitchBelongCiId(switchId); 	 /*获取道岔所属联锁ID*/

			if ((belongCiId == localCiId) && (0u != localCiId))
			{
				SwitchDanCaoPosition = GetSwitchDanCaoPostition(switchId);

				if (SwitchDanCaoPosition == SWITCH_POSITION_DINGWEI)
				{/*道岔驱动到定位*/
					(void)SetSwitchExpDrvPosition(switchId, SWITCH_DRIVE_POS_DINGWEI);
				}
				else if (SwitchDanCaoPosition == SWITCH_POSITION_FANWEI)
				{/*道岔驱动到反位*/
					(void)SetSwitchExpDrvPosition(switchId, SWITCH_DRIVE_POS_FANWEI);
				}/* zt 删除单轨相关代码 2022-02-15 */
				else
				{
					/*什么也不做*/
				}
			}
		}
	}/*for*/

	/*道岔期望驱动位置处理*/
	for (ii = 0u; ii < switchCurSum; ii++)
	{
		switchId = GetSwitchId(ii); 					 /*获取道岔ID*/

		if ((0u < switchId) && (switchId < SWITCH_SUM_MAX))
		{
			belongCiId = GetSwitchBelongCiId(switchId); 	 /*获取道岔所属联锁ID*/

			if ((belongCiId == localCiId) && (0u != localCiId))
			{
				curSwitchPos = GetSwitchCurPosition(switchId);/*获取道岔当前位置*/

				curExpDrvSwitchPos = GetSwitchExpDrvPosition(switchId);/*获取当前期望驱动的位置*/

				/* zt 删除单轨相关代码 2022-02-15 */
				if (((curSwitchPos == SWITCH_POSITION_DINGWEI) && (curExpDrvSwitchPos == SWITCH_DRIVE_POS_DINGWEI))
					|| ((curSwitchPos == SWITCH_POSITION_FANWEI) && (curExpDrvSwitchPos == SWITCH_DRIVE_POS_FANWEI))
					)
				{/*道岔驱动到位或集中控制时采集到JTYJa 吸起或GZJ落下或驱动TYJ吸起*/
					(void)SetSwitchExpDrvPosition(switchId, SWITCH_DRIVE_POS_INVALID);/*既然已驱动到位,可设置期望驱动位置为无效*/
				}
			}
		}

	}/*for*/

	/*道岔驱动状态更新*/
	for (ii = 0u; ii < switchCurSum; ii++)
	{
		switchId = GetSwitchId(ii);							/*获取道岔ID*/

		if ((0u < switchId) && (switchId < SWITCH_SUM_MAX))
		{
			belongCiId = GetSwitchBelongCiId(switchId);		/*获取道岔所属联锁ID*/

			if ((belongCiId == localCiId) && (0u != localCiId))
			{

				curExpDrvSwitchPos = GetSwitchExpDrvPosition(switchId);/*获取当前期望驱动的位置*/

				preExpDrvSwitchPos = GetSwitchPreExpDrvPosition(switchId);/*获取之前期望驱动的位置*/

				preSwitchDrivingState = GetSwitchDrivingState(switchId);/*获取之前的实际驱动状态*/

				if (SWITCH_DRIVE_POS_INVALID == curExpDrvSwitchPos)
				{/*当前期望驱动位置无效*/
					SetSwitchDrivingState(switchId, SWIT_DRIV_IDLE_TIME);/*设置道岔驱动状态为空闲*/
				}
				else
				{/*当前期望驱动位置有效*/
					if (curExpDrvSwitchPos == preExpDrvSwitchPos)
					{/*检查道岔移动是否已经超时*//* zt 删除单轨相关代码 2022-02-15 */
						if (CI_TRADITION_RAILWAY == lineIdentity)
						{  /*城市交通*/
							timeState = SystemOverTimeCheck(GetSwitchMoveStartCycNum(switchId), GetSystemParaSwDrvCuoFengCnt());
						}
						else
						{
							/*不做处理*/
						}

						if (CI_TIME_NO == timeState)
						{/*道岔尚未被驱动*/
							if (SWIT_DRIV_IDLE_TIME == preSwitchDrivingState)
							{/*之前的道岔驱动状态为空闲*/
								SetSwitchDrivingState(switchId, SWIT_DRIV_WAIT_TIME);/*道岔需要被驱动,尚未开始动作,一般情况下,之前道岔驱动状态为空闲状态,故设置道岔驱动状态为等待*/
							}
							else if (SWIT_DRIV_PEAK_TIME == preSwitchDrivingState)
							{/*之前的道岔驱动状态为高峰*/
								SetSwitchDrivingState(switchId, SWIT_DRIV_PEAK_TIME);/*道岔需要被驱动,尚未开始动作,某些情况下,之前道岔驱动状态已为高峰状态,故依然设置道岔驱动状态为高峰*/

								switDrivPeakTimeState = SWIT_DRIV_PEAK_TIME_TRUE;/*设置道岔驱动高峰期状态为TRUE,表示需要驱动的道岔当中已有道岔处于驱动高峰状态*/
							}
							else
							{
								/*不做处理*/
							}
						}
						else if (CI_TIME_IN == timeState)
						{/*道岔被驱动,正处于错峰期*/
							SetSwitchDrivingState(switchId, SWIT_DRIV_PEAK_TIME);/*道岔需要被驱动,已开始动作,无论之前道岔驱动状态如何,均设置道岔驱动状态为高峰*/

							switDrivPeakTimeState = SWIT_DRIV_PEAK_TIME_TRUE;/*设置道岔驱动高峰期状态为TRUE,表示需要驱动的道岔当中已有道岔处于驱动高峰状态*/
						}
						else if (CI_TIME_OUT == timeState)
						{/*道岔被驱动,已度过错峰期*/
							SetSwitchDrivingState(switchId, SWIT_DRIV_FLAT_TIME);/*道岔需要被驱动,已开始动作并超时,无论之前道岔驱动状态如何,均设置道岔驱动状态为平缓*/
						}
						else
						{
							/*什么也不做*/
						}
					}
					else
					{
						SetSwitchDrivingState(switchId, SWIT_DRIV_WAIT_TIME);/*设置道岔驱动状态为等待*/
					}
				}
			}
		}
	}/*for*/

	/*错峰驱动道岔逻辑处理*/
	for (ii = 0u; ii < switchCurSum; ii++)
	{
		switchId = GetSwitchId(ii); 					 /*获取道岔ID*/

		if ((0u < switchId) && (switchId < SWITCH_SUM_MAX))
		{
			belongCiId = GetSwitchBelongCiId(switchId); 	 /*获取道岔所属联锁ID*/

			if ((belongCiId == localCiId) && (0u != localCiId))
			{
				curExpDrvSwitchPos = GetSwitchExpDrvPosition(switchId);

				curSwitchDrivingState = GetSwitchDrivingState(switchId);

				/*道岔驱动状态处理*/
				if (SWIT_DRIV_IDLE_TIME == curSwitchDrivingState)
				{/*道岔驱动状态为空闲*/
					/*清除当前驱动状态*/
					SetSwitchDrivePostion(switchId, SWITCH_DRIVE_POS_INVALID);
				}
				else if (SWIT_DRIV_WAIT_TIME == curSwitchDrivingState)
				{/*道岔驱动状态为等待*/
					if (SWIT_DRIV_PEAK_TIME_FALSE == switDrivPeakTimeState)
					{/*当前没有道岔处于驱动高峰状态*/
						SetSwitchDrivePostion(switchId, curExpDrvSwitchPos);/*因为没有其他道岔处于驱动高峰状态,开始驱动道岔*/

						SetSwitchDrivingState(switchId, SWIT_DRIV_PEAK_TIME);/*开始驱动道岔,因此设置道岔为驱动高峰状态*/

						switDrivPeakTimeState = SWIT_DRIV_PEAK_TIME_TRUE;/*设置道岔驱动高峰期状态为TRUE,表示需要驱动的道岔当中已有道岔处于驱动高峰状态*/
					}
					else
					{
						SetSwitchDrivePostion(switchId, SWITCH_DRIVE_POS_INVALID);
					}
				}
				else if (SWIT_DRIV_PEAK_TIME == curSwitchDrivingState)
				{/*道岔驱动状态为高峰*/
					SetSwitchDrivePostion(switchId, curExpDrvSwitchPos);

					switDrivPeakTimeState = SWIT_DRIV_PEAK_TIME_TRUE;/*设置道岔驱动高峰期状态为TRUE,表示需要驱动的道岔当中已有道岔处于驱动高峰状态*/
				}
				else if (SWIT_DRIV_FLAT_TIME == curSwitchDrivingState)
				{/*道岔驱动状态为平缓*/
					SetSwitchDrivePostion(switchId, curExpDrvSwitchPos);/*驱动平缓状态下继续驱动道岔*/
				}
				else
				{
					/*什么也不做*/
				}
			}
		}
	}/*for*/

	/*驱动道岔继电器驱采处理*/
#if 0	
	for (ii = 0u; ii < switchCurSum; ii++)
	{
		switchId = GetSwitchId(ii);

		if ((0u < switchId) && (switchId < SWITCH_SUM_MAX))
		{
			belongCiId = GetSwitchBelongCiId(switchId);

			if ((belongCiId == localCiId) && (0u != localCiId))
			{
				/*驱动继电器处理*/

				/*获得驱动位置*/
				driveSwitchPos = GetSwitchDrivePostion(switchId);
				/* zt 删除单轨相关代码 2022-02-15 */
				if (CI_TRADITION_RAILWAY == lineIdentity)
				{  /*城市交通*/
					DriveSwitchRelayState(switchId, driveSwitchPos);
				}
				else
				{
				}


			}

		}

	}/*for*/
#endif

	/*本周期将行结束,设置上周期期望驱动位置*/
	for (ii = 0u; ii < switchCurSum; ii++)
	{
		switchId = GetSwitchId(ii); 					 /*获取道岔ID*/

		if ((0u < switchId) && (switchId < SWITCH_SUM_MAX))
		{
			belongCiId = GetSwitchBelongCiId(switchId); 	 /*获取道岔所属联锁ID*/

			if ((belongCiId == localCiId) && (0u != localCiId))
			{
				curExpDrvSwitchPos = GetSwitchExpDrvPosition(switchId);

				/*设置上周期期望驱动位置*/
				SetSwitchPreExpDrvPosition(switchId, curExpDrvSwitchPos);
			}

		}
	}/*for*/

	/*清除本周期期望驱动位置,因为双动道岔的原因,所以"设置上周起期望驱动位置"必须与"清除本周期期望驱动位置"代码分离*/
	for (ii = 0u; ii < switchCurSum; ii++)
	{
		switchId = GetSwitchId(ii); 					 /*获取道岔ID*/

		if ((0u < switchId) && (switchId < SWITCH_SUM_MAX))
		{
			belongCiId = GetSwitchBelongCiId(switchId); 	 /*获取道岔所属联锁ID*/

			if ((belongCiId == localCiId) && (0u != localCiId))
			{
				/*清除本周期期望驱动位置*/
				(void)SetSwitchExpDrvPosition(switchId, SWITCH_DRIVE_POS_INVALID);

				/*清除本周期驱动超时位置*/
				SetSwitchDrivOvtmDrvPosition(switchId, SWITCH_DRIVE_POS_INVALID);
			}

		}
	}/*for*/

	 /* zt 删除单轨相关代码 2022-02-15 */

	/*本周起将行结束，设置道岔最近一次驱动有效位置*/
	for (ii = 0U; ii < switchCurSum; ii++)
	{
		switchId = GetSwitchId(ii); 					 /*获取道岔ID*/
		if ((0u < switchId) && (switchId < SWITCH_SUM_MAX))
		{
			belongCiId = GetSwitchBelongCiId(switchId); 	 /*获取道岔所属联锁ID*/
			if ((belongCiId == localCiId) && (0u != localCiId))
			{
				driveSwitchPos = GetSwitchDrivePostion(switchId);
				if ((SWITCH_DRIVE_POS_DINGWEI == driveSwitchPos) || (SWITCH_DRIVE_POS_FANWEI == driveSwitchPos))
				{
					(void)SetSwitchLastValidDrvPos(switchId, driveSwitchPos);
					(void)SetSwitchLastValidPosDrivCycNum(switchId, curNum);
				}

				chSwitchJichaState = GetSwitchPrompylyAlarmInfo(switchId);
				/*只有静态红闪和动态红闪可以设置，其他设置不了一直为0*/
				SetSwitchJichaState(switchId, chSwitchJichaState);
			}
		}
	}
}





/******************************OC道岔设备输入处理****************************/
/*
* 功能描述： 获取OC道岔设备状态
* 参数说明：
		UINT16 switchId：道岔id
* 返回值  ：
*			((UINT8)0x01)    道岔定位
*			((UINT8)0x02)    道岔反位
*			((UINT8)0x04)    道岔四开
*			((UINT8)0x08)    道岔移动
*/
UINT8 GetOcSwitchState(UINT16 switchId)
{
	UINT8 rtnSwitchState = 0u;
	UINT16 belongOcId = 0u;       /*道岔所属oc ID*/
	UINT16 i = 0u;
	UINT8 k = 0U;
	UINT8 BoardStateErrCheck = 0U; /*板卡存在故障检查*/
	UINT8 BoardStateOtherErrCheck = 0U; /*板卡仅仅存在开盖、封连检查*/
	UINT8 BoardStateOpenCapCheck = 0U; /*板卡存在开盖状态检查*/
	UINT8 flagFind = 0u;
	UINT16 indexFind = 0u;
	UINT8 switchBlockLinkState = 0u; /*封连报警状态*/
	UINT8 switchBoardNum = 0U;
	belongOcId = GetSwitchBelongOcId(switchId);/*获取道岔所属Oc id*/

	if ((0u < belongOcId) && (OC_SUM_MAX > belongOcId))
	{
		/*m_OcToCiOrginDataArr[belongOcId].OcDevices*/
		for (i = 0u; i < m_SwitchNum; i++)
		{
			if (m_Switches[i].DeviceId == switchId)
			{
				flagFind = 1u;
				indexFind = i;
				break;
			}
		}
	}
	if (1u == flagFind)
	{
		rtnSwitchState = m_Switches[indexFind].DeviceState;
		switchBoardNum = m_Switches[indexFind].BoardNum;
		for (k = 0; k < switchBoardNum; k++)
		{
			if (0u != m_Switches[indexFind].BoardState[k])
			{
				BoardStateErrCheck++;
				if (0u == (m_Switches[indexFind].BoardState[k] & OC_SWITCH_OTHER_BJ_STATE))
				{
					BoardStateOtherErrCheck++;
					if (OC_SWITCH_OPEN_CAP_STATE == m_Switches[indexFind].BoardState[k])
					{
						BoardStateOpenCapCheck++;
					}
					else
					{
						; /*不处理*/
					}
				}
				else
				{
					; /*不处理*/
				}
			}
			else
			{
				; /*不处理*/
			}
		}
		/*如道岔板卡状态均有问题，则置道岔状态为四开*/
		if (BoardStateErrCheck == switchBoardNum)
		{
			/*设置四开*/
			rtnSwitchState = OC_SWITCH_POSITION_SIKAI;

			/*设置道岔故障标志*/
			SetSwitchFaultState(m_Switches[indexFind].DeviceId, SWITCH_FAULT_STATE_YES);

			/*获取取消封连状态*/
			switchBlockLinkState = GetCancelOrRcvrBlockLinkSta();

			/*存在板卡只有封连、开盖报警*/
			if (0u != BoardStateOtherErrCheck)
			{
				/*板卡状态有一系是开盖状态*/
				if (0u != BoardStateOpenCapCheck)
				{
					/*设置采集状态*/
					rtnSwitchState = m_Switches[indexFind].DeviceState;
				}
				/*说明存在封连*/
				else
				{
					if (CANCEL_SWITCH_BLOCK_LINK == switchBlockLinkState)
					{
						/*设置采集状态*/
						rtnSwitchState = m_Switches[indexFind].DeviceState;
					}
				}
			}
			/*存在其他报警*/
			else
			{
				/*不做处理*/
			}
		}
		else
		{
			/*设置道岔故障标志*/
			SetSwitchFaultState(m_Switches[indexFind].DeviceId, SWITCH_FAULT_STATE_NO);
		}
	}
	switch (rtnSwitchState)
	{
	case OC_SWITCH_POSITION_DINGWEI:
		rtnSwitchState = SWITCH_POSITION_DINGWEI;
		break;
	case OC_SWITCH_POSITION_FANWEI:
		rtnSwitchState = SWITCH_POSITION_FANWEI;
		break;
	case OC_SWITCH_POSITION_SIKAI:
		rtnSwitchState = SWITCH_POSITION_SIKAI;
		break;
	case OC_SWITCH_POSITION_MOVE:
		rtnSwitchState = SWITCH_POSITION_MOVE;
		break;
	default:
		rtnSwitchState = SWITCH_POSITION_SIKAI;
		break;
	}
	return rtnSwitchState;
}

/*
* 功能描述： OC道岔设备采集状态->逻辑状态
* 参数说明： void
* 返回值  ： void
*/
void OcSwitchDeviceInput(void)
{
	UINT16 switchCurSum = 0u;	 /*道岔总数目*/
	switchCurSum = GetSwitchCurSum();					/*获取道岔总数*/

	/*设置所有道岔单独位置*/
	SetAllSingleSwitchCurPosition(switchCurSum);
	
	/*设置道岔当前逻辑位置*/
	UpdataSwitchCurPostion(switchCurSum);

	/*根据道岔当前逻辑位置选择清理相关内容*/
	ClearSwitchMessageByCurPostion(switchCurSum);
}

/******************************OC信号机设备输出处理****************************/
/*
* 功能描述： OC信号机设备输出处理
* 参数说明： void
* 返回值  ： void
*/
void OcSignalDeviceOutput(void)
{
	UINT16 signalCurSum = 0u; /*信号机总数目*/
	UINT8 localCiId = 0u; /*本地联锁ID*/
	UINT8 belongCiId = 0u; /*信号机所属联锁ID*/
	UINT16 signalId = 0u; /*信号机ID*/
	UINT8 curDrvColor = 0u; /*信号机当前驱动颜色*/
	UINT8 curShowColor = 0u; /*信号机当前显示颜色*/
	UINT16 ii = 0u; /*循环索引*/
	UINT8 signalIsfushiFlag = 0u;
	UINT8 overTimeCheckResult = 0U;/*超时检查结果*/
	UINT32 signalDriOpenStartCyc = 0U;/*信号机驱动开放起始周期*/
	UINT32 signalDriOpenTimeCount = 0U;/*信号机驱动开放超时计数*/
	UINT32 signalDriCloseStartCyc = 0U;/*信号机驱动关闭起始周期*/
	UINT32 signalDriCloseTimeCount = 0U;/*信号机驱动关闭超时计数*/
	UINT8 driveRetVal = 0U;
	UINT8 jkjRelayValidFlag = 0u;

	signalCurSum = GetSignalCurSum(); /*获取信号机总数*/
	localCiId = GetSystemParaLocalCiId(); /*获取本机联锁ID*/

	/*处理信号机*/
	for (ii = 0u; ii < signalCurSum; ii++)
	{
		signalId = 0u; /*信号机ID*/
		belongCiId = 0u; /*信号机所属联锁ID*/
		curDrvColor = 0u; /*信号机当前驱动颜色*/

		signalId = GetSignalId(ii); /*获取信号机ID*/
		belongCiId = GetSignalBelongCiId(signalId); /*获取信号机所属联锁ID*/

		if ((0u != localCiId) && (belongCiId == localCiId) && (0u < signalId) && (signalId <= SIGNAL_SUM_MAX))
		{
			/***处理超时驱动***/
			curDrvColor = GetSignalCurDriveColor(signalId);  /*获取信号机当前驱动颜色*/

			if (SIGNAL_DRIVECOLOUR_NULL == curDrvColor)
			{/*信号机驱动无效*/
				jkjRelayValidFlag = GetCiJkjFlag();
				curShowColor = GetSignalCurColor(signalId);
				if (((SIGNAL_SHOWCOLOUR_REDYELLOW == curShowColor) || (SIGNAL_SHOWCOLOUR_RED_WHITE == curShowColor)) &&
					(JKJ_REYLAY_VALID == jkjRelayValidFlag))
				{
					/*引导信号开放时间在应急盘有效之后，人工办理引导信号开放，不执行驱动*/
				}
				else
				{
					driveRetVal = DriveSignalClose(signalId);  /*驱动信号机关闭*/
					if (CI_ERROR == driveRetVal)
					{
					}
				}
			}

			curDrvColor = GetSignalCurDriveColor(signalId);  /*获取信号机当前驱动颜色*/

			if ((SIGNAL_DRIVECOLOUR_RED == curDrvColor) || (SIGNAL_DRIVECOLOUR_REDCLOSE == curDrvColor))
			{/*信号机关闭*/

				signalDriCloseStartCyc = GetSignalDriveCloseStartCycNum(signalId);
				signalDriCloseTimeCount = GetSystemParaSignalCloseCyc();
				overTimeCheckResult = SystemOverTimeCheck(signalDriCloseStartCyc,signalDriCloseTimeCount);
				if (CI_TIME_OUT == overTimeCheckResult)
				{/*信号机关闭超时*/
					signalIsfushiFlag = GetSignalIsfushiFlag(signalId);
					if(SIGNALTYPE_FUSHI_YES != signalIsfushiFlag)/*复示信号机驱动关闭超时，不宕机*/
					{
					/*xxxxx宕机 信号机关闭超时*/
					SetPlatOverFlag(); /*设置平台宕机*/

					SetErrorData(EFUNC_PLAT_OVER, CI_DEVICE_TYPE_SIGNAL, signalId, ETYPE_SIG_CLOSE_OVER_TIME, curDrvColor, ESEND_LEVEL_ZERO);/*记录宕机故障码*/
					}
				}
			}
			else
			{/*信号机开放状态*/
				signalDriOpenStartCyc = GetSignalDriveOpenStartCycNum(signalId);
				signalDriOpenTimeCount = GetSystemParaSignalOpenCyc();
				overTimeCheckResult = SystemOverTimeCheck(signalDriOpenStartCyc,signalDriOpenTimeCount);
				if (CI_TIME_OUT == overTimeCheckResult)
				{/*信号开放状态*/

					driveRetVal = DriveSignalClose(signalId);/*驱动信号机关闭*/
					if (CI_ERROR == driveRetVal)
					{
						/*驱动信号关闭失败*/
					}
				}
			}


			/***处理信号机驱动继电器***/
#if 0
			if (SIGNAL_VIRTUAL_NO == signalVirtualAttr)
			{/*非虚拟信号机才进行驱动继电器动作*/
				/*驱动信号机相关继电器执行点灯*/
				if (CI_ERROR == SetSignalRelayState(signalId))
				{

				}
			}
#endif

			/*如果本周期驱动的颜色和上一周期驱动的颜色不同，则更新上一变化驱动的颜色*/
			if (GetSignalCurDriveColor(signalId) != GetSignalPreDriveColor(signalId))
			{
				(void)SetSignalPreChangedDriveColor(signalId, GetSignalPreDriveColor(signalId));
			}

			/*保存之前显示颜色，对虚拟信号机而言相当于根据逻辑状态驱动继电器状态*/
			(void)SetSignalPreDriveColor(signalId, GetSignalCurDriveColor(signalId));
		}

	}
}



/******************************OC信号机设备输入处理****************************/

/*
* 功能描述： 获取OC信号机设备颜色
* 参数说明：
		UINT16 signalId：信号机id
* 返回值  ： void
*/
UINT8 GetOcSignalColor(UINT16 signalId)
{
	UINT8 rtnSigColor = SIGNAL_SHOWCOLOUR_INVALID;
	UINT8 belongOcId = 0u;       /*信号机所属oc ID*/
	UINT16 i = 0u;
	UINT8 flagFind = 0u;
	UINT16 indexFind = 0u;
	UINT8 sigPreDriveColor = 0u;/*信号机之前驱动的颜色*/
	UINT8 sigCurShowColor = 0u;/*信号机当前显示的颜色*/
	UINT8 sigColorLevel = 0u;/*信号机颜色级别*/
	UINT8 funSwitchGreenYellow = GetCiFunctionSwitchConfig(CI_FUNCTION_SWITCH_SHOW_SIGNAL_GreenYellow);/*显示绿黄功能开关是否打开*/
	UINT8 ciType = GetLocalCiType();
	UINT8 signalState = 0U;
	UINT16 bufIndex = 0U;
	UINT8 funSwitchALLCloseUseBlue = GetCiFunctionSwitchConfig(FUNC_SWITCH_ZX_ALLCLOSE_USEBLUE);/*杭德正线灭灯均转蓝灯功能开关*/
	UINT8 chBlueDsFlag = FLAG_UNSET;
	bufIndex = GetSignalConfigBufIndex(signalId);  /*获取道岔数组下标*/
	belongOcId = (UINT8)GetSignalBelongOcId(signalId);/*获取信号机所属Oc id*/

	if ((0u < belongOcId) && (OC_SUM_MAX> belongOcId))
	{
		/*m_OcToCiOrginDataArr[belongOcId].OcDevices*/
		for (i = 0u; i < m_SignalNum; i++)
		{
			if (CI_SIGNAL_MAX > i)
			{
				if (m_Signals[i].DeviceId == signalId)
				{
					flagFind = 1u;
					indexFind = i;
					break;
				}
				else
				{
				    ;
				}
			}
			else
			{
			    ;
			}
		}

	}
	else
	{
	    ;
	}
	if (1u == flagFind)
	{
		/*增加处理OC信号机A系B系执行板状态都异常，置信号机状态为红断*/
		if ((0u != m_Signals[indexFind].BoardState[0]) && (0u != m_Signals[indexFind].BoardState[1]))
		{
			SetOcSignalStartCycNum(m_Signals[indexFind].DeviceId, 0);
			rtnSigColor = GetOcBoardFaultSignalColor(m_Signals[indexFind].DeviceId, belongOcId);
		}
        else
		{
			/*清除报警信息*/
			SetSignalBoardState(m_Signals[indexFind].DeviceId, OC_SIGNAL_BOARD_FAULT_NO);

			/*采集到蓝灯断丝转为蓝灯处理*/
			signalState = m_Signals[indexFind].DeviceState;
			if ((OC_SIGNAL_SHOWCOLOR_BLUE_BREAK == signalState) && (CI_TYPE_CLD != ciType))
			{
				signalState = OC_SIGNAL_SHOWCOLOR_BLUE;
				chBlueDsFlag = FLAG_SET;
				SignalDataStru[bufIndex].BlueDsBreakFlag = SIGNAL_DS_BREAK_YES;
			}
			else
			{
				; /*不处理*/
			}

			/*如果是灭灯*/
			if (OC_SIGNAL_SHOWCOLOR_ALL_CLOSE == signalState)/*如果是灭灯*/
			{
				/*如果是灭灯，获取之前驱动的颜色*/
				sigPreDriveColor = GetSignalPreDriveColor(m_Signals[indexFind].DeviceId);

				sigColorLevel = GetSignalColorLevel(sigPreDriveColor);

				if ((SIGNAL_LIGHT_EXTICT_STATE_NO == sigColorLevel) && 
					((FUNC_SWITCH_OFF == funSwitchGreenYellow)&&(FUNC_SWITCH_OFF == funSwitchALLCloseUseBlue)))
				{
					/*清亮灯OC全灭容忍计时*/
					SetOcSignalStartCycNum(m_Signals[indexFind].DeviceId, 0);
					/*信号机颜色为灭灯才这么处理*/
					if (SIGNAL_SHOWCOLOUR_INVALID == sigPreDriveColor)
					{
						rtnSigColor = SIGNAL_SHOWCOLOUR_REDCLOSE;
					}
					else
					{
						rtnSigColor = sigPreDriveColor;
					}
				}
				else
				{
						/*设置当前颜色*/
						rtnSigColor = SetSignalColorOcAllOff(m_Signals[indexFind].DeviceId);

				}

#if 0
				/*如果之前驱动的黄灭或者红灭或者绿灭*/
				if ((SIGNAL_DRIVECOLOUR_YELLOWCLOSE == sigPreDriveColor) ||
					(SIGNAL_DRIVECOLOUR_REDCLOSE == sigPreDriveColor) ||
					(SIGNAL_DRIVECOLOUR_GREENCLOSE == sigPreDriveColor))
				{
					rtnSigColor = sigPreDriveColor;
				}
				else if (SIGNAL_SHOWCOLOUR_INVALID == sigPreDriveColor)
				{
					rtnSigColor = SIGNAL_SHOWCOLOUR_RED;
				}
				else
				{
					rtnSigColor = SIGNAL_SHOWCOLOUR_RED;
				}
#endif
			}
			else if ((OC_SIGNAL_SHOWCOLOR_BLUE == signalState) &&
				((FUNC_SWITCH_ON == funSwitchGreenYellow)||(FUNC_SWITCH_ON == funSwitchALLCloseUseBlue)) &&(CI_TYPE_CLD != ciType))
			{
				/*如果采集蓝灯 非车辆段 显示绿黄灯或正线灭灯均点蓝灯开关打开，获取变化之前驱动的颜色*/
				sigPreDriveColor = GetSignalPreDriveColor(m_Signals[indexFind].DeviceId);

				sigColorLevel = GetSignalColorLevel(sigPreDriveColor);
				/*清亮灯OC全灭容忍计时*/
				SetOcSignalStartCycNum(m_Signals[indexFind].DeviceId, 0);
				if (FLAG_UNSET == chBlueDsFlag)
				{
					/*本周期采集非蓝断 清亮正线蓝灯断丝标志*/
					SignalDataStru[bufIndex].BlueDsBreakFlag = SIGNAL_DS_BREAK_NO;
				}
				if (SIGNAL_LIGHT_EXTICT_STATE_NO == sigColorLevel)
				{
					/*信号机颜色为灭灯才这么处理*/
					if (SIGNAL_SHOWCOLOUR_INVALID == sigPreDriveColor)
					{
						rtnSigColor = SIGNAL_SHOWCOLOUR_RED;
					}
					else
					{
						rtnSigColor = sigPreDriveColor;
					}
				}
				else
				{
					/*设置当前颜色*/
					rtnSigColor = GetSignalCurColor(m_Signals[indexFind].DeviceId);

				}
			}
			else
			{
					/*清亮灯OC全灭容忍计时*/
					SetOcSignalStartCycNum(m_Signals[indexFind].DeviceId, 0);
					sigPreDriveColor = GetSignalPreDriveColor(m_Signals[indexFind].DeviceId);
					sigCurShowColor = GetSignalCurColor(m_Signals[indexFind].DeviceId);
				switch (signalState)
				{/*把oc信号机颜色转成计算机信号机显示颜色*/
				case OC_SIGNAL_SHOWCOLOR_RED:
					rtnSigColor = SIGNAL_SHOWCOLOUR_RED;
					break;
				case OC_SIGNAL_SHOWCOLOR_YELLOW:
					if ((FUNC_SWITCH_ON == funSwitchGreenYellow) &&
						((SIGNAL_DRIVECOLOUR_GREENYELLOW == sigPreDriveColor)|| (SIGNAL_DRIVECOLOUR_DOUBLE_YELLOW == sigPreDriveColor)
							|| (SIGNAL_DRIVECOLOUR_RED == sigPreDriveColor) || (SIGNAL_DRIVECOLOUR_GREEN == sigPreDriveColor)))
					{
						rtnSigColor = sigCurShowColor;
					}
					else
					{
						rtnSigColor = SIGNAL_SHOWCOLOUR_YELLOW;
					}
					break;
				case OC_SIGNAL_SHOWCOLOR_REDYELLOW:
					rtnSigColor = SIGNAL_SHOWCOLOUR_REDYELLOW;
					break;
				case OC_SIGNAL_SHOWCOLOR_GREEN:
					if ((FUNC_SWITCH_ON == funSwitchGreenYellow) &&
						((SIGNAL_DRIVECOLOUR_GREENYELLOW == sigPreDriveColor) || (SIGNAL_DRIVECOLOUR_DOUBLE_GREEN == sigPreDriveColor) || (SIGNAL_DRIVECOLOUR_RED == sigPreDriveColor)))
					{
						rtnSigColor = sigCurShowColor;
					}
					else
					{
						rtnSigColor = SIGNAL_SHOWCOLOUR_GREEN;
					}
					break;
				case OC_SIGNAL_SHOWCOLOR_WHITE:
					rtnSigColor = SIGNAL_SHOWCOLOUR_WHITE;
					break;
				case OC_SIGNAL_SHOWCOLOR_YELLOW2:
					rtnSigColor = sigCurShowColor;
					break;
				case OC_SIGNAL_SHOWCOLOR_GREEN2:
					rtnSigColor = sigCurShowColor;
					break;
				case OC_SIGNAL_SHOWCOLOR_REDWHITE:
					rtnSigColor = SIGNAL_SHOWCOLOUR_RED_WHITE;
					break;
				case OC_SIGNAL_SHOWCOLOR_BLUE:
					rtnSigColor = SIGNAL_SHOWCOLOUR_RED;
					break;
				case OC_SIGNAL_SHOWCOLOR_GREENYELLOW:
					rtnSigColor = SIGNAL_SHOWCOLOUR_GREENYELLOW;
					break;
				case OC_SIGNAL_SHOWCOLOR_DOUBLEYELLOW:
					rtnSigColor = SIGNAL_SHOWCOLOUR_DOUBLE_YELLOW;
					break;
				case OC_SIGNAL_SHOWCOLOR_DOUBLEGREEN:
					rtnSigColor = SIGNAL_SHOWCOLOUR_DOUBLE_GREEN;
					break;
				case OC_SIGNAL_SHOWCOLOR_RED_BREAK:
					rtnSigColor = SIGNAL_SHOWCOLOUR_REDBREAK;
					break;
				case OC_SIGNAL_SHOWCOLOR_YELLOW_BREAK:
					rtnSigColor = SIGNAL_SHOWCOLOUR_YELLOWBREAK;
					break;
				case OC_SIGNAL_SHOWCOLOR_GREEN_BREAK:
					rtnSigColor = SIGNAL_SHOWCOLOUR_GREENBREAK;
					break;
				case OC_SIGNAL_SHOWCOLOR_WHITE_BREAK:
					rtnSigColor = SIGNAL_SHOWCOLOUR_WHITEBREAK;
					break;
				case OC_SIGNAL_SHOWCOLOR_BLUE_BREAK:
					/* 修改:by pfq 2022.03.28 解决车辆段设置蓝灯断丝后信号机黑显的问题，蓝灯断丝后转红断*/
					/*正线蓝断已转为蓝灯*/
					rtnSigColor = SIGNAL_SHOWCOLOUR_REDBREAK;
					break;
				case OC_SIGNAL_SHOWCOLOR_YELLOW_2_BREAK:
					rtnSigColor = SIGNAL_SHOWCOLOUR_YELLOWBREAK;
					break;
				case OC_SIGNAL_SHOWCOLOR_GREEN_2_BREAK:
					rtnSigColor = SIGNAL_SHOWCOLOUR_GREENBREAK;
					break;
				case OC_SIGNAL_SHOWCOLOR_DL_OVERLOAD:
				case OC_SIGNAL_SHOWCOLOR_DY_OVERLOAD:
				case OC_SIGNAL_SHOWCOLOR_DLDY_OVERLOAD:
				case OC_SIGNAL_SHOWCOLOR_DY_ZERO:
					rtnSigColor = SIGNAL_SHOWCOLOUR_REDBREAK;
					break;
				default:
					/*by cgh 20230703 YF0083-772:OC给rc的信号机状态为非法值（bb），rc信号机灰显改为红断*/
					rtnSigColor = SIGNAL_SHOWCOLOUR_REDBREAK;
					break;
					}
				}
		}
	}
	return rtnSigColor;
}
/*
* 功能描述： 信号机双系板卡故障，信号机当前设置颜色
* 参数说明：
		UINT16 signalId：信号机id
		UINT8 ocId  OC ID
* 返回值  ： 信号机颜色
*/
UINT8 GetOcBoardFaultSignalColor(UINT16 signalId, UINT8 ocId)
{
	UINT8 stateSignalOpen = 0u;
	UINT8 transmitState = 0u;
	UINT8 rtnSigColor = 0u;
	UINT8 sigPreDriveColor = 0u;
	UINT8 sigMaintainState = 0u;
	transmitState = GetCiTransmitState(CI_SYSTEM_TYPE_OC, ocId);
	/*通信正常*/
	if(TRANSMIT_STATE_GOOD == transmitState)
	{
		/*设置报警信息*/
		SetSignalBoardState(signalId,OC_SIGNAL_BOARD_FAULT_YES);
		stateSignalOpen = GetSignalLightExtinctState(signalId);
		/*CBTC灭灯模式&&信号机不在维修点灯状态 不影响正常使用--WGY 20220705*/
		sigMaintainState = GetSignalMaintainState(signalId);
		sigPreDriveColor = GetSignalPreDriveColor(signalId);
		if((SIGNAL_LIGHT_EXTICT_STATE_NO == stateSignalOpen)&&(MAINTAIN_STATE_NO == sigMaintainState))
		{
			/*如果是灭灯，获取之前驱动的颜色*/
			
			/*之前驱动无效*/
			if (SIGNAL_SHOWCOLOUR_INVALID == sigPreDriveColor)
			{
				rtnSigColor = SIGNAL_SHOWCOLOUR_REDCLOSE;
			}
			else
			{
				rtnSigColor = sigPreDriveColor;
			}
		}
		else
		{
			/*设置红断*/
			rtnSigColor = SIGNAL_SHOWCOLOUR_REDBREAK;
		}
	}
	/*通信异常*/
	else
	{
		/*取消报警*/
		SetSignalBoardState(signalId,OC_SIGNAL_BOARD_FAULT_NO);
		/*设置红断*/
		rtnSigColor = SIGNAL_SHOWCOLOUR_REDFAULT;

	}
	return rtnSigColor;
}

/*
* 功能描述： 信号机亮灯情况下，OC给全灭，信号机颜色设置
* 参数说明：
		UINT16 signalId：信号机id
* 返回值  ： 信号机颜色
*/
UINT8 SetSignalColorOcAllOff(const UINT16 signalId)
{
	/*变量初始化*/
	UINT8 signalCurColor = 0u;
	UINT8 rtnSigColor = SIGNAL_SHOWCOLOUR_REDBREAK;
	UINT32 signalCycNum = 0u;
	UINT32 curCycNum = 0u;
	UINT8 checkCycOut = 0u;
	UINT8 preDriveColor = 0u;
	UINT32 signalRongrenNum = 0u;
	UINT8 funSwitchGreenYellow = GetCiFunctionSwitchConfig(CI_FUNCTION_SWITCH_SHOW_SIGNAL_GreenYellow);/*显示绿黄功能开关是否打开*/
	UINT8 funSwitchALLCloseUseBlue = GetCiFunctionSwitchConfig(FUNC_SWITCH_ZX_ALLCLOSE_USEBLUE);/*杭德正线灭灯均转蓝灯功能开关*/
	UINT16 bufIndex = GetSignalConfigBufIndex(signalId);  /*获取信号机数组下标*/
	if (SIGNAL_SUM_MAX > bufIndex)
	{
		/*获取当前颜色，因为信号机当前颜色未更新，即是获取上一周期颜色*/
		signalCurColor = GetSignalCurColor(signalId);
		curCycNum = Get2oo2CurCycleNum();

		/*在容忍时间内设置当前颜色为上一周期颜色*/
		signalCycNum = GetOcSignalStartCycNum(signalId);
		/*获取系统参数中配置的OC信号机全灭容忍时间*/
		signalRongrenNum = GetSigCollectRongernCount();
		checkCycOut = SystemOverTimeCheck(signalCycNum, signalRongrenNum);
		/*未计时*/
		if (CI_TIME_NO == checkCycOut)
		{
			/*设置颜色*/
			rtnSigColor = signalCurColor;
			SetOcSignalStartCycNum(signalId, curCycNum);
		}
		/*超时*/
		else if (CI_TIME_OUT == checkCycOut)
		{
			/*获取之前驱动颜色*/
			preDriveColor = GetSignalPreDriveColor(signalId);
			debug_infor_printf((const)"ALL CLOSE curCyc%d,   SignalStartCycNum%d preDriveColor:%d \n.", curCycNum, signalCycNum, preDriveColor);

			switch (preDriveColor)
			{
			case SIGNAL_DRIVECOLOUR_RED:
				/*设置红断*/
				rtnSigColor = SIGNAL_SHOWCOLOUR_REDBREAK;
				break;
			case SIGNAL_DRIVECOLOUR_YELLOW:
				/*设置黄断*/
				rtnSigColor = SIGNAL_SHOWCOLOUR_YELLOWBREAK;
				break;
			case SIGNAL_DRIVECOLOUR_DOUBLE_YELLOW:
			case SIGNAL_DRIVECOLOUR_GREENYELLOW:
				/*双黄 绿黄驱动中 全灭设置黄断*/
				rtnSigColor = SIGNAL_SHOWCOLOUR_YELLOWBREAK;
				break;
			case SIGNAL_DRIVECOLOUR_DOUBLE_GREEN:
				/*双绿全灭设置绿断*/
				rtnSigColor = SIGNAL_SHOWCOLOUR_GREENBREAK;
				break;
			case SIGNAL_DRIVECOLOUR_GREEN:
				/*设置绿断*/
				rtnSigColor = SIGNAL_SHOWCOLOUR_GREENBREAK;
				break;
				/*红黄、红白*/
			case SIGNAL_DRIVECOLOUR_REDYELLOW:
			case SIGNAL_DRIVECOLOUR_RED_WHITE:
				/*设置红断*/
				rtnSigColor = SIGNAL_SHOWCOLOUR_REDBREAK;
				break;
			case SIGNAL_DRIVECOLOUR_WHITE:
				/*设置白断*/
				rtnSigColor = SIGNAL_SHOWCOLOUR_WHITEBREAK;
				break;
			case SIGNAL_DRIVECOLOUR_GREENCLOSE:
			case SIGNAL_DRIVECOLOUR_YELLOWCLOSE:
				/*绿黄全灭设置 绿黄灯开关打开或杭德时设置蓝断 获取之前驱动颜色*/
				if ((FUNC_SWITCH_ON == funSwitchGreenYellow) || (FUNC_SWITCH_ON == funSwitchALLCloseUseBlue))
				{
					rtnSigColor = preDriveColor;
					SignalDataStru[bufIndex].BlueDsBreakFlag = SIGNAL_DS_BREAK_YES;
				}
				else
				{
					rtnSigColor = SIGNAL_SHOWCOLOUR_REDBREAK;
				}
				break;
			case SIGNAL_DRIVECOLOUR_GREENYELLOWCLOSE:
				/*绿黄全灭设置 绿黄灯开关打开时设置蓝断*/
				if (FUNC_SWITCH_ON == funSwitchGreenYellow)
				{
					rtnSigColor = preDriveColor;
					SignalDataStru[bufIndex].BlueDsBreakFlag = SIGNAL_DS_BREAK_YES;
				}
				else
				{
					rtnSigColor = SIGNAL_SHOWCOLOUR_REDBREAK;
				}
				break;
			case SIGNAL_DRIVECOLOUR_REDCLOSE:
				/*杭德开关打开时设置蓝断*/
				if (FUNC_SWITCH_ON == funSwitchALLCloseUseBlue)
				{
					rtnSigColor = preDriveColor;
					SignalDataStru[bufIndex].BlueDsBreakFlag = SIGNAL_DS_BREAK_YES;
				}
				else
				{
					rtnSigColor = SIGNAL_SHOWCOLOUR_REDBREAK;
				}
				break;
			default:
				/*红灭等状态 此处不可达分支*/
				break;
			}
		}
		else
		{
			/*设置颜色*/
			rtnSigColor = signalCurColor;
		}
	}
	else
	{
		rtnSigColor = SIGNAL_SHOWCOLOUR_REDBREAK; /*信号机ID非法*/
	}
	return rtnSigColor;
}

/*
* 功能描述： OC信号机设备采集状态->逻辑状态
* 参数说明： void
* 返回值  ： void
*/
void OcSignalDeviceInput(void)
{
	UINT16 signalCurSum = 0u;	/*信号机总数目*/
	UINT16 signalId = 0u;	    /*信号机ID*/
	UINT8 localCiId = 0u;
	UINT16 ii = 0u;
	UINT8 belongCiId = 0u;       /*信号机所属联锁ID*/
	UINT8 signalVirtualAttr = 0u;
	UINT8 signalCurColor = 0u;	/*信号机当前显示颜色*/
	UINT8 signalPreDrvColor = 0u;/*信号机之前驱动颜色*/
	UINT16 signalDetainRelayId = 0u;/*信号机硬线扣车1 ID*/
	UINT16 detainCutRelayId = 0u; /*扣车旁路继电器1 ID*/
	UINT8 relayBelongCIId = 0u;
	UINT16 signalDetainRelayId_2 = 0u;/*信号机硬线扣车2 ID*/
	UINT8 DetainRelayId_2BelongCIId = 0u;
	UINT16 detainCutRelayId_2 = 0u; /*扣车旁路继电器2 ID*/
	UINT8 cheakdetain_1 = CI_ERROR;
	UINT8 cheakdetain_2 = CI_ERROR;
	UINT8 sigOpenCloseState = 0u;
	UINT8 sigPreOpenCloseState = 0u;
	UINT32 diffColorCycNum = 0u;
	UINT32 curCycNum = 0U;
	UINT8 driveRetVal = 0U;
	UINT8 signalDetainBtnActFlag = SIGNAL_ZFS_BTN_ACT_FLAG_NO;   /*扣车按钮1激活标志*/
	UINT8 funcswitchZfsBtn = 0U;         /*是否为自复式按钮*/
	UINT8 addCiToCiCmdFlag = CI_ERROR;   /*是否给相邻联锁发命令*/
	UINT32 signalDriveNewSigStartCyc = 0u;  /*信号机驱动新信号起始周期号*/
	UINT32 signalDiffCyc = 0U; /*信号开放颜色不一致周期*/
	UINT8 cFuncRet = 0U;

	curCycNum= Get2oo2CurCycleNum();
	signalCurSum = GetTotalSignalCurNum();      /*获取信号机总数*/
	localCiId = GetSystemParaLocalCiId();       /*获取本机联锁ID*/
	funcswitchZfsBtn = GetCiFunctionSwitchConfig(FUNC_ZIFUSHI_BUTTON);

	/*处理信号机*/
	for (ii = 0u; ii < signalCurSum; ii++)
	{
		signalId = GetSignalId(ii);
		belongCiId = GetSignalBelongCiId(signalId);
		signalVirtualAttr = GetSignalVirtualAttr(signalId);  /*获取信号机虚拟属性*/
		cheakdetain_1 = CI_ERROR; /*判断扣车之前先将检查标志置为不扣*/
		cheakdetain_2 = CI_ERROR;

		addCiToCiCmdFlag = CI_ERROR;
		/*获取扣车继电器1 */
		signalDetainRelayId = GetSignalDetainRelayId(signalId);
		relayBelongCIId = GetRelayBelongCiId(signalDetainRelayId);/*扣车继电器1所属联锁ID*/
		detainCutRelayId = GetSignalDetainCutRelayId(signalId);

		if (FUNC_SWITCH_ON != funcswitchZfsBtn)  /*非自复式扣车按钮处理*/
		{
			/*扣车继电器2 状态获取*/
			signalDetainRelayId_2 = GetSignalDetainRelayId_2(signalId);
			DetainRelayId_2BelongCIId = GetRelayBelongCiId(signalDetainRelayId_2);
			detainCutRelayId_2 = GetSignalDetainCutRelayId_2(signalId);
			/*扣车继电器属于本联锁*/
			if (relayBelongCIId == localCiId)
			{
				if ((0u != signalDetainRelayId) && (UINT16_MAX != signalDetainRelayId))
				{
					cheakdetain_1 = CheakDeatainState(detainCutRelayId, signalDetainRelayId);
					addCiToCiCmdFlag = CI_SUCCESS;

					cFuncRet = GetFstDetBtnCollTolerateRet(signalId);  /*获取扣车按钮1采集容忍结果*/
					if (CI_SUCCESS == cFuncRet)
					{
						cheakdetain_1 = CI_ERROR;  /*未超时，设置影响扣车无效*/
					}
					else
					{
						/*超时，不处理*/
					}
				}
			}
			else
			{
				/*无操作*/
			}
			if (DetainRelayId_2BelongCIId == localCiId)
			{
				if ((0u != signalDetainRelayId_2) && (UINT16_MAX != signalDetainRelayId_2))
				{
					/*硬线扣车继电器2 有效*/
					cheakdetain_2 = CheakDeatainState(detainCutRelayId_2, signalDetainRelayId_2);
					addCiToCiCmdFlag = CI_SUCCESS;

					cFuncRet = GetSndDetBtnCollTolerateRet(signalId);  /*获取扣车按钮2采集容忍结果*/
					if (CI_SUCCESS == cFuncRet)
					{
						cheakdetain_2 = CI_ERROR;  /*未超时，设置影响扣车无效*/
					}
					else
					{
						/*超时，不处理*/
					}
				}
			}
			else
			{
			}
		}
		else  /*自复式扣车按钮处理*/
		{
			if ((relayBelongCIId == localCiId) || (belongCiId == localCiId))
			{
				SignalZfsDetainBtnPro(signalId);
				SignalZfsCancelDetainBtnPro(signalId);
				SignalZfsDetainCutBtnPro(signalId);
				signalDetainBtnActFlag = GetSignalDetainBtnActFlag(signalId);
				if (SIGNAL_ZFS_BTN_ACT_FLAG_NO != signalDetainBtnActFlag)
				{
					cheakdetain_1 = CI_SUCCESS;
				}
				else
				{
					cheakdetain_1 = CI_ERROR;
				}
				addCiToCiCmdFlag = CI_SUCCESS;
			}
			else
			{
				/*不处理*/
			}
		}

		if ((0u != localCiId) && (belongCiId == localCiId) && (0u < signalId) && (SIGNAL_SUM_MAX >= signalId))
		{
			/*获取信号机显示颜色*/
			if (SIGNAL_VIRTUAL_YES == signalVirtualAttr)
			{/*虚拟信号机当前显示颜色为之前驱动颜色*/
				signalCurColor = GetSignalPreDriveColor(signalId);
			}
			else if (SIGNAL_VIRTUAL_NO == signalVirtualAttr)
			{
				signalCurColor = GetOcSignalColor(signalId);/*获取OC信号机颜色*/
			}
			else
			{
				/*不要处理*/
			}


			/*设置信号机驱动无效*/
			signalDriveNewSigStartCyc = GetSignalDriveNewSigStartCycNum(signalId);
			if (signalDriveNewSigStartCyc == curCycNum)
			{
				/*当前周期有驱动信号机，此处不再设置驱动无效*/
			}
			else
			{
				/*设置信号机驱动无效*/
				SetSignalCurDriveColor(signalId, SIGNAL_DRIVECOLOUR_NULL);
			}

			/*设置当前显示颜色*/
			OcSetSignalCurColor(signalId, signalCurColor);

			/*如果信号机当前是开放的，并且之前也是驱动开放，但是驱动颜色和当前颜色不同，驱关闭*/
			sigOpenCloseState = GetSignalOpenCloseState(signalCurColor);
			if (SIGNAL_OPEN == sigOpenCloseState)
			{
				signalPreDrvColor = GetSignalPreDriveColor(signalId);/*获取信号机之前驱动颜色*/
				sigPreOpenCloseState = GetSignalOpenCloseState(signalPreDrvColor);
				if ((SIGNAL_OPEN == sigPreOpenCloseState) && (signalPreDrvColor != signalCurColor))
				{/*之前驱动开放且和当前开放颜色不同*/
					diffColorCycNum = GetSignalDiffColorOpenStartCyc(signalId);
					curCycNum = Get2oo2CurCycleNum();
					if (0u == diffColorCycNum)
					{
						(void)SetSignalDiffColorOpenStartCyc(signalId, Get2oo2CurCycleNum());/*设置信号机驱动开放颜色不等于当前开放颜色起始周期*/
					}
					else
					{
						/*判断是否超过容忍周期数*/
						if (SIGNAL_DRIVECOLOUR_GREENYELLOW == signalPreDrvColor)
						{
							/*驱动绿黄采用较长时间 红转绿黄/双绿/双黄本就采用开放时间检查 蓝或绿转绿黄也采用该时间*/
							signalDiffCyc = GetSystemParaSignalOpenCyc();
						}
						else
						{
							signalDiffCyc = (UINT32)SIGNAL_RELAY_ACTION_TIMEMAX;
						}
						if ((curCycNum - diffColorCycNum) >= signalDiffCyc)
						{/*超时*/
							driveRetVal = DriveSignalClose(signalId);/*驱动关闭*/
							if (CI_ERROR == driveRetVal)
							{
								/*驱动信号关闭失败*/
							}	

							(void)SetSignalDiffColorOpenStartCyc(signalId, 0u);/*清空信号机驱动开放颜色不等于当前开放颜色起始周期*/
						}
						else
						{
							/*没有超时，继续容忍，不做处理*/
						}
					}
				}
				else
				{
					(void)SetSignalDiffColorOpenStartCyc(signalId, 0u);/*清空信号机驱动开放颜色不等于当前开放颜色起始周期*/
				}
			}
			else
			{
					(void)SetSignalDiffColorOpenStartCyc(signalId, 0u);/*清空信号机驱动开放颜色不等于当前开放颜色起始周期*/
			}

			/*设置信号机硬线扣车状态*/
			if ((CI_SUCCESS == cheakdetain_1) || (CI_SUCCESS == cheakdetain_2))
			{
				SetSignalRelayDetainFlag(signalId, SIGNAL_RELAY_DETAIN_YES);
			}
			else
			{
				if (((relayBelongCIId == localCiId) || (UINT16_MAX == signalDetainRelayId) || (0u == signalDetainRelayId)) &&
					((DetainRelayId_2BelongCIId == localCiId) || (UINT16_MAX == signalDetainRelayId_2) || (0u == signalDetainRelayId_2)))
				{
					SetSignalRelayDetainFlag(signalId, SIGNAL_RELAY_DETAIN_NO);
				}
				else
				{
					/*此分支本集中区不扣，非本集中区的扣车按钮，交由相邻集中区命令设置、取消扣车标志*/
				}
			}
		}
		/*信号机不是本联锁*/
		else if ((0u != localCiId) && (belongCiId != localCiId) && (0u < signalId) && (SIGNAL_SUM_MAX >= signalId))
		{
			if (CI_SUCCESS == addCiToCiCmdFlag)
			{
				/*向其它联锁发送设置信号机硬线扣车状态*/
				if ((CI_SUCCESS == cheakdetain_1) || (CI_SUCCESS == cheakdetain_2))
				{
					/*添加扣车*/
					AddCiSendToCiCmdInfo((UINT8)CI_CMD_KOUCHE_DETAIN, signalId, SIGNAL_DETAIN_CI_RELAY_YES, belongCiId);
				}
				else
				{
					/*添加未扣车*/
					AddCiSendToCiCmdInfo((UINT8)CI_CMD_KOUCHE_DETAIN, signalId, SIGNAL_DETAIN_CI_RELAY_NO, belongCiId);
				}
			}
			else
			{
				/*不发送*/
			}
		}
		else
		{
		  /*无操作*/
		}
	}
}

/*
* 功能描述： 自复式扣车按钮处理
* 参数说明： const UINT16 signalId 信号机ID
* 返回值  ： 无
*/
void SignalZfsDetainBtnPro(const UINT16 signalId)
{
	UINT16 detainBtnRelayId = 0U;    /*扣车按钮采集继电器1ID*/
	UINT8 localCiId = 0U;   /*本地联锁ID*/
	UINT8 detainRelayBelongCiId = 0U;    /*扣车按钮采集继电器1所属CI*/
	UINT8 detainRelayCollState = 0U;     /*扣车按钮采集继电器1状态*/
	UINT8 relayDetainValidFlag = 0U;     /*硬线扣车有效标志*/
	UINT32 cycnow = 0U;     /*当前周期*/
	UINT32 zfsBtnRelayCollCycNum = 0U;   /*自复式按钮继电器采集周期*/
	UINT32 zfsBtnRelayFaultCycNum = 0U;  /*自复式按钮继电器故障判断周期*/
	UINT32 detainBtnPressCycNum = 0U;    /*扣车按钮1按下周期*/
	UINT8 btnPressValidTime = CI_TIME_NO;   /*按钮按下时间是否达到有效时间*/
	UINT8 btnPressFaultTime = CI_TIME_NO;   /*按钮按下时间是否达到故障时间*/
	UINT8 detainBtnErrorFlag = SIGNAL_ZFS_BTN_ERR_FLAG_NO;	

	detainBtnRelayId = GetSignalDetainRelayId(signalId);
	localCiId = GetSystemParaLocalCiId();
	detainRelayBelongCiId = GetRelayBelongCiId(detainBtnRelayId);

	/*继电器ID有效，继电器属于本联锁*/
	if ((0U != detainBtnRelayId) && (UINT16_MAX != detainBtnRelayId)                
		&& (localCiId == detainRelayBelongCiId) && (0U != detainRelayBelongCiId))   
	{
		relayDetainValidFlag = GetCiFunctionSwitchConfig(FUNC_RELAY_DETAIN_VALID_FLAG);
		detainRelayCollState = GetRelayCollState(detainBtnRelayId);   /*获取扣车按钮继电器1采集状态*/

		if (((DOWN_VALID == relayDetainValidFlag) && (RELAY_STATE_DOWN == detainRelayCollState)) 
			|| ((UP_VALID == relayDetainValidFlag) && (RELAY_STATE_UP == detainRelayCollState)))
		{
			detainBtnPressCycNum = GetDetainBtnPressCycNum(signalId);
			if (0U == detainBtnPressCycNum)
			{
				cycnow = Get2oo2CurCycleNum();
				SetDetainBtnPressCycNum(signalId, cycnow);  /*设置按钮按下周期*/
			}
		}
		else
		{
			SetDetainBtnPressCycNum(signalId, 0U);
		}
		
		detainBtnPressCycNum = GetDetainBtnPressCycNum(signalId);
		zfsBtnRelayCollCycNum = GetSelfButCollCount();
		btnPressValidTime = SystemOverOrEqualTimeCheck(detainBtnPressCycNum, zfsBtnRelayCollCycNum);
		detainBtnErrorFlag = GetSignalDetainBtnErrFlag(signalId);

		/*按钮按下时间达到判断采集有效时间且未故障，设置扣车按钮激活有效*/
		if ((CI_TIME_OUT == btnPressValidTime) && (SIGNAL_ZFS_BTN_ERR_FLAG_YES != detainBtnErrorFlag))
		{
			SetSignalDetainBtnActFlag(signalId, SIGNAL_ZFS_BTN_ACT_FLAG_YES);  /*扣车按钮1激活*/
		}
		else
		{
			/*不处理*/
		}

		zfsBtnRelayFaultCycNum = GetSelfButErrCount();
		btnPressFaultTime = SystemOverTimeCheck(detainBtnPressCycNum, zfsBtnRelayFaultCycNum);
		if (CI_TIME_OUT == btnPressFaultTime)
		{
			SetSignalDetainBtnErrFlag(signalId, SIGNAL_ZFS_BTN_ERR_FLAG_YES);
		}
		else
		{
			SetSignalDetainBtnErrFlag(signalId, SIGNAL_ZFS_BTN_ERR_FLAG_NO);
		}
	}
	else
	{
		/*不处理*/
	}
}

/*
* 功能描述： 自复式取消扣车按钮处理
* 参数说明： const UINT16 signalId 信号机ID
* 返回值  ： 无
*/
void SignalZfsCancelDetainBtnPro(const UINT16 signalId)
{
	UINT16 wSignalIdIndex = 0U;  /*信号机数组下标*/
	UINT16 cancelDetainBtnRelayId = 0U;     /*取消扣车按钮采集继电器ID*/
	UINT8 localCiId = 0U;   /*本地联锁ID*/
	UINT8 cancelDetainRelayBelongCiId = 0U;     /*取消扣车按钮采集继电器所属CI*/
	UINT32 zfsBtnRelayCollCycNum = 0U;    /*自复式按钮继电器采集周期*/
	UINT32 zfsBtnRelayFaultCycNum = 0U;   /*自复式按钮继电器故障判断周期*/
	UINT32 zfsBtnRelayErrTrigCycNum = 0U;   /*自复式按钮继电器误触发判断周期*/
	UINT32 cancelDetainBtnPressCycNum = 0U;    /*取消扣车按钮正常按下周期*/
	UINT32 cancelDetErrTrigPressCycNum = 0U;    /*取消扣车按钮误触发按下周期*/
	UINT8 cancelDetainBtnValidFlag = SIGNAL_CANCEL_DETAIN_VALID_NO;  /*取消扣车按钮有效标志*/
	UINT8 btnPressValidTime = CI_TIME_NO;   /*按钮按下时间是否达到有效时间*/
	UINT8 btnPressFaultTime = CI_TIME_NO;   /*按钮按下时间是否达到故障时间*/
	UINT8 btnPressErrTrigTime = CI_TIME_NO;   /*按钮按下时间是否达到误触发时间*/
	UINT8 detainBtnErrorFlag = SIGNAL_ZFS_BTN_ERR_FLAG_NO;   /*扣车按钮故障标志*/

	wSignalIdIndex = GetSignalConfigBufIndex(signalId);

	if (SIGNAL_SUM_MAX > wSignalIdIndex)
	{
		cancelDetainBtnRelayId = GetSignalCancelDetainBtnRelayId(signalId);
		localCiId = GetSystemParaLocalCiId();
		cancelDetainRelayBelongCiId = GetRelayBelongCiId(cancelDetainBtnRelayId);

		if ((0U != cancelDetainBtnRelayId) && (UINT16_MAX != cancelDetainBtnRelayId) && (localCiId == cancelDetainRelayBelongCiId) && (0U != localCiId))
		{
			/***** 1.处理取消扣车按钮正常/误触发按下周期和采集继电器落下状态 *****/
			DetZfsCancelBtnPressStateProc(signalId, cancelDetainBtnRelayId);

			/***** 2.处理取消扣车按钮有效标志 *****/
			DetZfsCancelBtnActFlagProc(signalId, cancelDetainBtnRelayId);

			/***** 3.处理扣车按钮激活标志和取消扣车按钮有效标志 *****/
			cancelDetainBtnValidFlag = GetCancelDetainBtnValidFlag(signalId);
			cancelDetainBtnPressCycNum = GetCancelDetainBtnPressCycNum(signalId);
			zfsBtnRelayCollCycNum = GetSelfButCollCount();
			btnPressValidTime = SystemOverTimeCheck(cancelDetainBtnPressCycNum, zfsBtnRelayCollCycNum);  /*判断取消按钮正常按下时间是否达到有效时间*/
			zfsBtnRelayFaultCycNum = GetSelfCancelButErrCount();
			btnPressFaultTime = SystemOverTimeCheck(cancelDetainBtnPressCycNum, zfsBtnRelayFaultCycNum);  /*判断取消按钮正常按下时间是否达到故障时间*/
			detainBtnErrorFlag = GetSignalDetainBtnErrFlag(signalId);  /*获取扣车按钮故障标志*/

			if ((SIGNAL_CANCEL_DETAIN_VALID_YES == cancelDetainBtnValidFlag) && (CI_TIME_OUT == btnPressValidTime) && (CI_TIME_OUT != btnPressFaultTime))
			{
				/*取消扣车按钮有效且按钮按下时间达到判断采集有效时间且未达到故障判断时间，设置扣车按钮激活标志无效，设置取消扣车按钮无效*/
				SetSignalDetainBtnActFlag(signalId, SIGNAL_ZFS_BTN_ACT_FLAG_NO);
				SetCancelDetainBtnValidFlag(signalId, SIGNAL_CANCEL_DETAIN_VALID_NO);
			}
			else if ((SIGNAL_ZFS_BTN_ERR_FLAG_NO != detainBtnErrorFlag) && ((CI_TIME_OUT != btnPressValidTime) || (CI_TIME_OUT == btnPressFaultTime)))
			{
				/*扣车按钮故障且（取消扣车按钮按下时间未达到判断采集有效时间或达到故障判断时间），设置扣车按钮激活标志有效*/
				SetSignalDetainBtnActFlag(signalId, SIGNAL_ZFS_BTN_ACT_FLAG_YES);
			}
			else
			{
				/*不处理*/
			}

			/***** 4.处理取消扣车按钮故障标志 *****/
			cancelDetErrTrigPressCycNum = GetCancelDetErrTrigPressCycNum(signalId);
			zfsBtnRelayErrTrigCycNum = GetSelfCancelButErrTriggerCount();
			btnPressErrTrigTime = SystemOverTimeCheck(cancelDetErrTrigPressCycNum, zfsBtnRelayErrTrigCycNum);  /*判断取消按钮误触发按下时间是否达到误触发时间*/

			if ((CI_TIME_OUT == btnPressFaultTime) || (CI_TIME_OUT == btnPressErrTrigTime))
			{
				/*取消扣车按钮正常按下时间达到判断故障有效时间或取消扣车按钮误触发按下时间达到判断误触发有效时间，设置取消扣车按钮故障标志有效*/
				SetSignalCancelDetainBtnErrFlag(signalId, SIGNAL_ZFS_BTN_ERR_FLAG_YES);
			}
			else
			{
				SetSignalCancelDetainBtnErrFlag(signalId, SIGNAL_ZFS_BTN_ERR_FLAG_NO);
			}
		}
		else
		{
			/*继电器ID错误/非本联锁，不处理*/
		}
	}
	else
	{
		/*入参非法，不处理*/
	}
}

/*
* 功能描述： 自复式取消扣车按钮按下状态处理
* 参数说明： const UINT16 wSignalId 信号机ID
*            const UINT16 wCancelDetBtnRelayId 取消扣车按钮采集继电器ID
* 返回值  ： 无
* Created By LQ 2024.05.09
*/
void DetZfsCancelBtnPressStateProc(const UINT16 wSignalId, const UINT16 wCancelDetBtnRelayId)
{
	UINT16 wSignalIdIndex = 0U;  /*信号机数组下标*/
	UINT16 wRelayIdIndex = 0U;  /*继电器数组下标*/
	UINT8 cCancelDetRelayCollState = 0U;  /*取消扣车按钮采集继电器状态*/
	UINT8 cDetainBtnActFlag = SIGNAL_ZFS_BTN_ACT_FLAG_NO;  /*扣车按钮激活标志*/
	UINT8 cCancelDetRelayDownState = SIGNAL_RELAY_ERROR_DOWN_YES;  /*取消扣车按钮采集继电器落下状态*/
	UINT32 dwCancelDetBtnPressCycNum = 0U;  /*取消扣车按钮正常按下周期*/
	UINT32 dwCancelDetErrTrigPressCycNum = 0U;  /*取消扣车按钮误触发按下周期*/
	UINT32 dwCurCycNum = 0U;  /*当前周期*/
	UINT16 wRelayBelongOcId = 0U;  /*继电器所属OC*/
	UINT8 cOcCommState = TRANSMIT_STATE_BAD;  /*与OC通信状态*/
	UINT8 cABoardState = RELAY_BOARD_FAULT_YES;  /*A系板卡状态*/
	UINT8 cBBoardState = RELAY_BOARD_FAULT_YES;  /*B系板卡状态*/

	wSignalIdIndex = GetSignalConfigBufIndex(wSignalId);
	wRelayIdIndex = GetRelayConfigBufIndex(wCancelDetBtnRelayId);

	if ((SIGNAL_SUM_MAX > wSignalIdIndex) && ( RELAY_SUM_MAX > wRelayIdIndex))
	{
		cCancelDetRelayCollState = GetRelayCollState(wCancelDetBtnRelayId);  /*获取取消扣车按钮继电器1采集状态*/

		if (RELAY_STATE_UP == cCancelDetRelayCollState)
		{
			/** 继电器吸起，更新取消扣车按钮正常/误触发按下周期 **/
			cDetainBtnActFlag = GetSignalDetainBtnActFlag(wSignalId);
			cCancelDetRelayDownState = GetCancelDetainRelayDownState(wSignalId);  /*获取取消扣车按钮采集继电器落下状态*/
			dwCancelDetBtnPressCycNum = GetCancelDetainBtnPressCycNum(wSignalId);  /*获取取消扣车按钮正常按下时间*/
			dwCancelDetErrTrigPressCycNum = GetCancelDetErrTrigPressCycNum(wSignalId);  /*获取取消扣车按钮误触发按下时间*/
			dwCurCycNum = Get2oo2CurCycleNum();

			if ((SIGNAL_ZFS_BTN_ACT_FLAG_YES == cDetainBtnActFlag) && (SIGNAL_RELAY_ERROR_DOWN_NO == cCancelDetRelayDownState))
			{
				/** 扣车按钮激活标志有效且上周期取消扣车按钮采集继电器落下状态为正常落下（与OC通信正常且存在一系板卡状态正常），更新取消扣车按钮正常按下时间 **/
				if ((0U == dwCancelDetBtnPressCycNum) && (0U == dwCancelDetErrTrigPressCycNum))
				{
					SetCancelDetainBtnPressCycNum(wSignalId, dwCurCycNum);  /*设置取消扣车按钮正常按下时间为当周期（误触发和正常按下不同时存在）*/
				}
				else
				{
					/*不处理*/
				}
			}
			else
			{
				/** 扣车按钮激活标志无效或上周期取消扣车按钮采集继电器落下状态非正常落下（与OC通信中断或两系板卡状态均故障），更新取消扣车按钮误触发按下时间 **/
				if ((0U == dwCancelDetBtnPressCycNum) && (0U == dwCancelDetErrTrigPressCycNum))
				{
					SetCancelDetErrTrigPressCycNum(wSignalId, dwCurCycNum);  /*设置取消扣车按钮误触发按下时间为当周期（误触发和正常按下不同时存在）*/
				}
				else
				{
					/*不处理*/
				}
			}
		}
		else
		{
			/** 继电器落下，更新取消扣车按钮采集继电器落下状态 **/
			wRelayBelongOcId = GetRelayBelongOCId(wCancelDetBtnRelayId);
			cOcCommState = GetCiTransmitState(CI_SYSTEM_TYPE_OC, (UINT8)wRelayBelongOcId);  /*获取与OC通信状态*/
			cABoardState = GetRelayACollBoardState(wCancelDetBtnRelayId);  /*获取A系板卡状态*/
			cBBoardState = GetRelayBCollBoardState(wCancelDetBtnRelayId);  /*获取B系板卡状态*/

			if ((TRANSMIT_STATE_GOOD == cOcCommState) && ((RELAY_BOARD_FAULT_NO == cABoardState) || (RELAY_BOARD_FAULT_NO == cBBoardState)))
			{
				/*OC通信正常且有一系板卡状态正常，设置继电器正常落下*/
				SetCancelDetainRelayDownState(wSignalId, SIGNAL_RELAY_ERROR_DOWN_NO);
			}
			else
			{
				/*OC通信异常或两系板卡状态均故障，设置继电器通信异常落下*/
				SetCancelDetainRelayDownState(wSignalId, SIGNAL_RELAY_ERROR_DOWN_YES);
			}

			/** 继电器落下，清除取消扣车按钮正常按下周期和误触发按下周期 **/
			SetCancelDetainBtnPressCycNum(wSignalId, 0U);
			SetCancelDetErrTrigPressCycNum(wSignalId, 0U);
		}
	}
	else
	{
		/*入参非法，不处理*/
	}
}

/*
* 功能描述： 自复式取消扣车按钮激活标志处理
* 参数说明： const UINT16 wSignalId 信号机ID
*            const UINT16 wCancelDetBtnRelayId 取消扣车按钮采集继电器ID
* 返回值  ： 无
* Created By LQ 2024.05.09
*/
void DetZfsCancelBtnActFlagProc(const UINT16 wSignalId, const UINT16 wCancelDetBtnRelayId)
{
	UINT16 wSignalIdIndex = 0U;  /*信号机数组下标*/
	UINT16 wRelayIdIndex = 0U;  /*继电器数组下标*/
	UINT8 cDetainBtnActFlag = SIGNAL_ZFS_BTN_ACT_FLAG_NO;  /*扣车按钮激活标志*/
	UINT8 cDetainValidFlag = 0U;  /*硬线扣车有效标志*/
	UINT16 wDetainBtnRelayId = 0U;  /*扣车按钮采集继电器ID*/
	UINT8 cDetainRelayCollState = 0U;  /*扣车按钮采集继电器状态*/
	UINT8 cDetainBtnErrorFlag = SIGNAL_ZFS_BTN_ERR_FLAG_NO;  /*扣车按钮故障标志*/
	UINT8 cCancelDetRelayCollState = 0U;  /*取消扣车按钮采集继电器状态*/
	UINT8 cCancelDetRelayDownState = SIGNAL_RELAY_ERROR_DOWN_YES;  /*取消扣车按钮采集继电器落下状态*/

	wSignalIdIndex = GetSignalConfigBufIndex(wSignalId);
	wRelayIdIndex = GetRelayConfigBufIndex(wCancelDetBtnRelayId);

	if ((SIGNAL_SUM_MAX > wSignalIdIndex) && (RELAY_SUM_MAX > wRelayIdIndex))
	{
		cDetainBtnActFlag = GetSignalDetainBtnActFlag(wSignalId);  /*获取扣车按钮激活标志*/
		cDetainValidFlag = GetCiFunctionSwitchConfig(FUNC_RELAY_DETAIN_VALID_FLAG);  /*获取影响扣车有效标志*/
		wDetainBtnRelayId = GetSignalDetainRelayId(wSignalId);
		cDetainRelayCollState = GetRelayCollState(wDetainBtnRelayId);  /*获取扣车按钮采集继电器状态*/
		cDetainBtnErrorFlag = GetSignalDetainBtnErrFlag(wSignalId);
		cCancelDetRelayCollState = GetRelayCollState(wCancelDetBtnRelayId);  /*获取取消扣车按钮采集继电器状态*/
		cCancelDetRelayDownState = GetCancelDetainRelayDownState(wSignalId);  /*获取取消扣车按钮采集继电器落下状态*/

		if ((SIGNAL_ZFS_BTN_ACT_FLAG_YES == cDetainBtnActFlag) && (((DOWN_VALID == cDetainValidFlag) && (RELAY_STATE_UP == cDetainRelayCollState))
			|| ((UP_VALID == cDetainValidFlag) && (RELAY_STATE_DOWN == cDetainRelayCollState)) || (SIGNAL_ZFS_BTN_ERR_FLAG_YES == cDetainBtnErrorFlag))
			&& (RELAY_STATE_DOWN == cCancelDetRelayCollState) && (SIGNAL_RELAY_ERROR_DOWN_NO == cCancelDetRelayDownState))
		{
			/*扣车按钮激活有效且(扣车按钮抬起或故障)且取消扣车按钮采集继电器落下且为正常落下，设置取消扣车按钮有效*/
			SetCancelDetainBtnValidFlag(wSignalId, SIGNAL_CANCEL_DETAIN_VALID_YES);
		}
		else if (((((DOWN_VALID == cDetainValidFlag) && (RELAY_STATE_UP != cDetainRelayCollState))
			|| ((UP_VALID == cDetainValidFlag) && (RELAY_STATE_DOWN != cDetainRelayCollState)))
			&& (SIGNAL_ZFS_BTN_ERR_FLAG_YES != cDetainBtnErrorFlag)) || (SIGNAL_RELAY_ERROR_DOWN_NO != cCancelDetRelayDownState))
		{
			/*（扣车按钮未抬起且未故障）或取消扣车按钮采集继电器非正常落下，设置取消扣车按钮无效*/
			SetCancelDetainBtnValidFlag(wSignalId, SIGNAL_CANCEL_DETAIN_VALID_NO);
		}
		else
		{
			/*不处理*/
		}
	}
	else
	{
		/*入参非法，不处理*/
	}
}

/******************************OC spks指示灯输出处理****************************/
/*
* 功能描述： OC spks指示灯和spks旁路指示灯输出处理
* 参数说明： void
* 返回值  ： void
*/
void SpksDisplayDrivOutput(void)
{
	UINT16 spksCurSum = 0u;       /*spks当前总数目，默认为每个spks都有指示灯*/
	UINT8 tmpCutRelayColState = 0u;  /*spks旁路继电器状态*/
	UINT16 spksDisplayId = 0u;      /*spks指示灯继电器ID*/
	UINT16 spksId = 0u;             /*spks ID*/
	UINT16 cutSpksId = 0u;		   /*spks旁路按钮继电器 ID*/
	UINT16 cutSpksDisplayId = 0u;      /*spks旁路指示灯继电器ID*/
	UINT16 ii = 0u;                 /*循环索引*/
	UINT8  chLocalCiId = 0u;          /*本地联锁ID*/
	UINT8  devBlongCiId = 0u;       /*设备所属联锁ID*/
	UINT32 spksflockStartNum = 0u;
	UINT32 dwSpksIndicDelayCount = 0u;
	UINT8 checkCycOut = 0u;
	UINT8 cSpksState = 0U;

	spksCurSum = GetSpksSum();     /*获取spks数量，默认为每个spks都有对应的指示灯*/
	chLocalCiId = GetSystemParaLocalCiId(); /*获取本地联锁ID*/

	/*先处理总spks管辖的户外指示灯，置总SPKS驱分SPKS表示灯状态*/
	for(ii = 0u; ii < spksCurSum; ii++)
	{
		spksId = GetSpksIdByIndex(ii);      /*获取本集中区的spks ID*/
		devBlongCiId = GetSpksBelongCiId(spksId);  /*获取设备所属联锁ID*/
		if(chLocalCiId == devBlongCiId)
		{
			TotalSpksOutsideDisPlayProc(spksId);/*对总spks管辖的spks室外指示灯做处理*/
		}
	}

	for (ii = 0u; ii < spksCurSum; ii++)
	{
		spksId = GetSpksIdByIndex(ii);      /*获取本集中区的spks ID*/
		spksDisplayId = GetSpksDisRelayId(spksId); /*根据spks ID获取spks指示灯ID*/

		cutSpksId = GetSpksCutRelayId(spksId);        /*获取spks旁路按钮继电器ID*/
		cutSpksDisplayId = GetSpksCutDisRelayId(spksId); /*根据spks ID获取spks旁路指示灯ID*/

		devBlongCiId = GetSpksBelongCiId(spksId);  /*获取设备所属联锁ID*/

		if ((0u != cutSpksId) && (UINT16_MAX != cutSpksId))
		{
			tmpCutRelayColState = GetRelayCollState(cutSpksId);/*获取spks旁路按钮继电器状态*/
		}
		else
		{
			/*此spks没有spks旁路按钮继电器，不做处理*/
		}
		if (chLocalCiId == devBlongCiId)       /*只处理本联锁集中区*/
		{
			/*spks指示灯驱动*/
			if ((0u != spksDisplayId) && (UINT16_MAX != spksDisplayId))
			{
				/*spks指示灯继电器有效*/
				cSpksState = GetSpksState(spksId);
				if (SPKS_STATUS_YES == cSpksState)
				{
				     /*SPKS继电器落下后，需延时点灯*/
				    spksflockStartNum = GetSpksflockStartNum(spksId);/*获取SPKS封锁物理区段起始周期*/
					dwSpksIndicDelayCount = GetSpksIndicDelayCount();/*获取延时周期数*/
				    checkCycOut = SystemOverTimeCheck(spksflockStartNum,dwSpksIndicDelayCount);
					if (CI_TIME_OUT == checkCycOut)/*超时*/
					{
						(void)SetRelayDriveState(spksDisplayId, RELAY_STATE_UP); /*指示灯亮灯*/
					}
					else
					{
						(void)SetRelayDriveState(spksDisplayId,RELAY_STATE_DOWN); /*指示灯灭灯*/
					}
				}
				else
				{
					(void)SetRelayDriveState(spksDisplayId, RELAY_STATE_DOWN); /*指示灯灭灯*/
				}
			}
			else
			{
				/*此spks没有指示灯继电器，不处理*/
			}

			/*spks旁路指示灯驱动*/
			if ((0u != cutSpksDisplayId) && (UINT16_MAX != cutSpksDisplayId))
			{/*spks旁路按钮有效且旁路按钮指示灯继电器有效*/
				if (RELAY_STATE_UP == tmpCutRelayColState)
				{
					(void)SetRelayDriveState(cutSpksDisplayId, RELAY_STATE_UP); /*指示灯亮灯*/
				}
				else if (RELAY_STATE_DOWN == tmpCutRelayColState)
				{
					(void)SetRelayDriveState(cutSpksDisplayId, RELAY_STATE_DOWN); /*指示灯灭灯*/
				}
				else
				{
					(void)SetRelayDriveState(cutSpksDisplayId, RELAY_STATE_DOWN); /*指示灯灭灯*/
				}
			}
			else
			{
				/*此spks没有旁路按钮或者没有旁路按钮指示灯继电器，不处理*/
			}
			/*spks室外指示灯驱动*/
			spksflockStartNum = GetSpksflockStartNum(spksId);
			SpksOutsideDisPlayDriv(spksId,spksflockStartNum);
		}
		else
		{
			/*非本集中区设备不处理*/
		}
		SetDriveOutDisFlag(spksId,TOTALSPKSDRIVE_INVALID);
	}
}


/***********************OC SPKS关联的门禁解锁继电器输出处理****************************/
/*
* 功能描述： OC spks关联的门禁解锁输出处理
* 参数说明： void
* 返回值  ： void
*/
void SpksMenjinJSDrivOutput(void)
{
	UINT16 mjjsCurSum = 0U;       /*门禁继电器总数*/
	UINT16 curspksId = 0U;            /*spks ID*/
	UINT16 mjjsRalayId = 0U;          /*门禁解锁继电器 ID*/
	UINT16 ii = 0U;     /*循环索引*/
	UINT16 jj = 0U;      /*循环索引*/
	UINT8 currelSpkscount = 0U;      /*当前门禁继电器对应的SPKS数量*/
	UINT8 checkflag = 0U;
	UINT8 chRtn = CI_ERROR;
	UINT8 chBelongCIId = 0u;
	UINT16 chMJId = 0u;
	UINT8 localCIId = 0u;

	localCIId = GetSystemParaLocalCiId();
	/*获取当前联锁门禁解锁继电器的数量*/
	mjjsCurSum = GetMjjsSum();

	/*遍历门禁解锁继电器*/
	for (ii = 0u; ii < mjjsCurSum; ii++)
	{
		chMJId = GetMJIdByIndex(ii);
		chBelongCIId = GetMjBelongCIID(chMJId);

		/*只处理本联锁的门禁*/
		if (chBelongCIId == localCIId)
		{
			checkflag = 0u;   /*激活判断标志初始化*/
			mjjsRalayId = GetMjjsRelayId(chMJId);        /*获取对应的门禁解锁继电器ID*/
			currelSpkscount = GetSpksCountByMjID(chMJId);
			/*门禁解锁继电器有效*/
			if ((0u != mjjsRalayId) && (UINT16_MAX != mjjsRalayId))
			{
				/*遍历该门禁继电器关联的所有SPKS*/
				for (jj = 0u; jj < currelSpkscount; jj++)
				{

					curspksId = GetSpksIdByMjjsIndex(chMJId, jj);   /*获取对应的SPKSID*/
					/*是否存在激活的SPKS*/
					checkflag |= MJrelSpksMJStateProcess(curspksId);
				}
				/*SPKS已激活*/
				if (1u == checkflag)
				{
					chRtn = SetRelayDriveState(mjjsRalayId, RELAY_STATE_UP); /*门禁解锁继电器吸起*/
					if (CI_ERROR == chRtn)
					{
						;		/*设置继电器状态失败*/
					}
				}
				else
				{
					chRtn = SetRelayDriveState(mjjsRalayId, RELAY_STATE_DOWN); /*门禁解锁继电器*/
					if (CI_ERROR == chRtn)
					{
						;		/*设置继电器状态失败*/
					}
				}
			}
			else
			{
			}
		}
	}
}

/*
* 功能描述： 门禁关联spks是否激活的逻辑判断
* 参数说明： void
* 返回值  ： CI_SUCCESS  激活
*          CI_ERROR  未激活
*/
UINT8 MJrelSpksMJStateProcess(UINT16 spksId)
{
	UINT8 spksState = 0U;		     /*spks状态*/
	UINT8 spksCutState = 0U;        /*spks旁路状态*/
	UINT8  chLocalCiId = 0U;          /*本地联锁ID*/
	UINT8  devBlongCiId = 0U;       /*设备所属联锁ID*/

	UINT32 spksflockStartNum = 0U;  /*SPKS封锁起始周期*/
	UINT32 mjjsDelayCount = 0U;     /*门禁解锁延时周期*/
	UINT8 checkCycOut = 0U;         /*延时判断*/
	UINT8 retval = CI_ERROR;


	/*获取本地联锁ID*/
	chLocalCiId = GetSystemParaLocalCiId();
	/*获取SPKS按钮状态*/
	spksState = GetSpksState(spksId);
	/*获取SPKS旁路按钮状态*/
	spksCutState = GetSpksCutState(spksId);

	/*判断SPKS是否激活*/
	if ((SPKS_STATUS_YES == spksState) && (SPKS_CUT_NO == spksCutState))
	{
		devBlongCiId = GetSpksBelongCiId(spksId);  /*获取设备所属联锁ID*/
		if (chLocalCiId == devBlongCiId)       /*只处理本联锁集中区*/
		{
			/*延迟时间判断*/
			spksflockStartNum = GetSpksflockStartNum(spksId);/*获取SPKS封锁物理区段起始周期*/
			mjjsDelayCount = GetMjjsOpenDelayCount();/*获取门禁开启延时周期数*/
			checkCycOut = SystemOverTimeCheck(spksflockStartNum, mjjsDelayCount);
			if (CI_TIME_OUT == checkCycOut)/*超时*/
			{
				retval = CI_SUCCESS;

			}
			else
			{
				/*未激活*/
			}
		}
		else
		{
			/*非本联锁不处理*/
		}
	}
	else
	{
		/*返回失败*/
	}

	return retval;
}


/******************************OC esb指示灯输出处理****************************/
/*
* 功能描述： OC esb指示灯和esb旁路指示灯输出处理
* 参数说明： void
* 返回值  ： void
*/
void EsbDisplayDrivOutput(void)
{
	UINT16 esbCurSum = 0u;                /*esb当前总数目，默认为每个esb都有指示灯*/
	UINT16 esbCollId = 0u;		          /*esb采集继电器 ID*/
	UINT8 tmpCollRelayColState = 0u;      /*esb采集继电器状态*/
	UINT8 tmpCutRelayColState = 0u;       /*esb旁路继电器状态*/
	UINT16 esbDisplayRelayId = 0u;        /*esb指示灯继电器ID*/
	UINT16 esbPlatformDisRelayId = 0U;    /*esb站台指示灯继电器ID*/
	UINT16 cutEsbId = 0u;		          /*esb旁路按钮继电器 ID*/
	UINT16 cutEsbDisplayId = 0u;          /*esb旁路指示灯继电器ID*/
	UINT8  chLocalCiId = 0u;                /*本地联锁ID*/
	UINT16 esbId = 0u;                    /*esb ID*/
	UINT8  devBlongCiId = 0u;             /*设备所属联锁ID*/
	UINT16 ii = 0u;                       /*循环索引*/

	UINT8 esbState = ESB_STATE_VALID_NO;  /*紧急关闭状态*/
	UINT8 funcswitchZfsBtn = 0U;          /*自复式按钮开关*/

	esbCurSum = GetEsbSum();     /*获取esb数量，默认为每个esb都有对应的指示灯*/
	chLocalCiId = GetSystemParaLocalCiId(); /*获取本地联锁ID*/
	funcswitchZfsBtn = GetCiFunctionSwitchConfig(FUNC_ZIFUSHI_BUTTON);

	for (ii = 0u; ii < esbCurSum; ii++)
	{
		esbId = GetEsbId(ii);        /*获取本地esb ID*/
		esbCollId = GetEsbRelayId(esbId);        /*获取esb采集继电器ID*/
		tmpCollRelayColState = GetRelayCollState(esbCollId);/*获取esb采集继电器状态*/
		esbDisplayRelayId = GetEsbDisRelayId(esbId); /*根据esb ID获取esb指示灯ID*/
		esbPlatformDisRelayId = GetEsbPlatformDisRelayId(esbId); /*根据esb ID获取esb站台指示灯继电器ID*/

		cutEsbId = GetEsbCutRelayId(esbId);        /*获取esb旁路按钮继电器ID*/
		cutEsbDisplayId = GetEsbCutDisRelayId(esbId); /*根据esb ID获取esb旁路指示灯ID*/
		devBlongCiId = GetEsbBelongCiId(esbId); /*获取设备所属联锁ID*/

		if ((0u != cutEsbId) && (UINT16_MAX != cutEsbId))
		{
			tmpCutRelayColState = GetRelayCollState(cutEsbId);/*获取esb旁路按钮继电器状态*/
		}
		else
		{
			/*此esb没有esb旁路按钮继电器，不做处理*/
		}

		if (chLocalCiId == devBlongCiId)       /*只处理本联锁集中区*/
		{
			if (FUNC_SWITCH_ON == funcswitchZfsBtn)  /*自复式ESB指示灯继电器驱动处理*/
			{	
				esbState = GetEsbState(esbId);
				/*设置ESB指示灯亮灭状态*/
				if ((0u != esbDisplayRelayId) && (UINT16_MAX != esbDisplayRelayId))
				{
					if (ESB_STATE_VALID_YES == esbState)
					{
						(void)SetRelayDriveState(esbDisplayRelayId, RELAY_STATE_UP); /*紧急，驱动ESB指示灯亮灯*/
					}
					else
					{
						(void)SetRelayDriveState(esbDisplayRelayId, RELAY_STATE_DOWN); /*未紧急，驱动ESB指示灯灭灯*/
					}
				}
				else
				{
					/*没有ESB指示灯，不做处理*/
				}

				/*设置ESB站台指示灯亮灭状态*/
				if ((0u != esbPlatformDisRelayId) && (UINT16_MAX != esbPlatformDisRelayId))
				{
					/*设置ESB指示灯亮灭状态*/
					if (ESB_STATE_VALID_YES == esbState)
					{
						(void)SetRelayDriveState(esbPlatformDisRelayId, RELAY_STATE_UP); /*紧急，驱动ESB站台指示灯亮灯*/
					}
					else
					{
						(void)SetRelayDriveState(esbPlatformDisRelayId, RELAY_STATE_DOWN); /*未紧急，驱动ESB站台指示灯灭灯*/
					}
				}
				else
				{
					/*没有ESB站台指示灯，不做处理*/
				}
			}
			else if (FUNC_SWITCH_ESB_NINGXIANG_RAIL == funcswitchZfsBtn)
			{
				/*宁象市域铁路ESB指示灯继电器驱动处理*/
				EsbNXRailDisplayDrivOutput(esbId);
			}
			else
			{
				/*非自复式esb指示灯继电器驱动*/
				esbState = GetEsbState(esbId);
				/*设置ESB指示灯亮灭状态*/
				if ((0u != esbDisplayRelayId) && (UINT16_MAX != esbDisplayRelayId))
				{
					if (ESB_STATE_VALID_YES == esbState)
					{
						(void)SetRelayDriveState(esbDisplayRelayId, RELAY_STATE_UP); /*紧急，驱动ESB指示灯亮灯*/
					}
					else
					{
						(void)SetRelayDriveState(esbDisplayRelayId, RELAY_STATE_DOWN); /*未紧急，驱动ESB指示灯灭灯*/
					}
				}
				else
				{
					/*没有ESB指示灯，不做处理*/
				}

				/*设置ESB站台指示灯亮灭状态*/
				if ((0u != esbPlatformDisRelayId) && (UINT16_MAX != esbPlatformDisRelayId))
				{
					/*设置ESB指示灯亮灭状态*/
					if (ESB_STATE_VALID_YES == esbState)
					{
						(void)SetRelayDriveState(esbPlatformDisRelayId, RELAY_STATE_UP); /*紧急，驱动ESB站台指示灯亮灯*/
					}
					else
					{
						(void)SetRelayDriveState(esbPlatformDisRelayId, RELAY_STATE_DOWN); /*未紧急，驱动ESB站台指示灯灭灯*/
					}
				}
				else
				{
					/*没有ESB站台指示灯，不做处理*/
				}

				if ((0u != cutEsbDisplayId) && (UINT16_MAX != cutEsbDisplayId))
				{/*esb旁路按钮和旁路按钮指示灯继电器都有效*/
					if (RELAY_STATE_UP == tmpCutRelayColState)
					{
						(void)SetRelayDriveState(cutEsbDisplayId, RELAY_STATE_UP); /*指示灯亮灯*/
					}
					else if (RELAY_STATE_DOWN == tmpCutRelayColState)
					{
						(void)SetRelayDriveState(cutEsbDisplayId, RELAY_STATE_DOWN); /*指示灯灭灯*/
					}
					else
					{
						(void)SetRelayDriveState(cutEsbDisplayId, RELAY_STATE_DOWN); /*指示灯灭灯*/
					}
				}
				else
				{
					/*esb没有旁路按钮或者没有旁路按钮指示灯继电器，不做处理*/
				}
			}
		}
		else
		{
			/*非本集中区设备不处理*/
		}
	}
}



/******************************OC 扣车旁路指示灯输出处理****************************/
/*
* 功能描述： OC 扣车和扣车旁路指示灯输出处理
* 参数说明： void
* 返回值  ： void
*/
void DetainDisplayDrivOutput(void)
{
	UINT16 signalCurSum = 0u;  /*扣车旁路指示灯当前总数目*/
	UINT16 signalDetainRelayId = 0u;	/*扣车按钮继电器 ID*/
	UINT16 signalCutDetainRelayId = 0u;	/*扣车旁路按钮继电器 ID*/
	UINT16 cutDetainDisplayId = 0u;      /*扣车旁路指示灯继电器ID*/
	UINT16 signalDetainDisplayId = 0u;      /*扣车指示灯继电器ID*/
	UINT8  localCiId = 0u;          /*本地联锁ID*/
	UINT16 signalId = 0u;             /*信号机 ID*/
	UINT8  devBlongCiId = 0u;       /*设备所属联锁ID*/
	UINT8 cutRelayBelongCi = 0u;
	UINT8 cutBsRelayBelongCi = 0u;
	UINT8 detainRelayBelongCi = 0u;
	UINT8 detainBsRelayBelongCi = 0u;
	UINT16 ii = 0u;                 /*循环索引*/

	UINT16 signalDetainRelayId_2 = 0u;		  /*扣车按钮继电器2 ID */
	UINT16 signalCutDetainRelayId_2 = 0u;	  /*扣车旁路按钮继电器2 ID*/
	UINT16 cutDetainDisplayId_2 = 0u;         /*扣车旁路指示灯继电器2 ID*/
	UINT16 signalDetainDisplayId_2 = 0u;      /*扣车指示灯继电器2 ID*/

	UINT8 cutRelay_2BelongCi = 0u;
	UINT8 cutBsRelay_2BelongCi = 0u;
	UINT8 detainRelay_2BelongCi = 0u;
	UINT8 detainBsRelay_2BelongCi = 0u;

	UINT8 funcswitchZfsBtn = 0U;      /*自复式按钮开关*/

	signalCurSum = GetTotalSignalCurNum();     /*获取信号机数量*/
	localCiId = GetSystemParaLocalCiId(); /*获取本地联锁ID*/
	funcswitchZfsBtn = GetCiFunctionSwitchConfig(FUNC_ZIFUSHI_BUTTON);

	for (ii = 0u; ii < signalCurSum; ii++)
	{
		signalId = GetSignalId(ii);
		signalCutDetainRelayId = GetSignalDetainCutRelayId(signalId);        /*获取扣车旁路按钮继电器ID*/
		cutDetainDisplayId = GetSignalDetainCutDisRelayId(signalId); /*根据扣车继电器ID获取扣车指示灯ID*/

		signalDetainDisplayId = GetSignalDetainDisRelayId(signalId);
		signalDetainRelayId = GetSignalDetainRelayId(signalId);

		signalDetainRelayId_2 = GetSignalDetainRelayId_2(signalId);
		signalCutDetainRelayId_2 = GetSignalDetainCutRelayId_2(signalId);
		cutDetainDisplayId_2 = GetSignalDetainCutDisRelayId_2(signalId);
		signalDetainDisplayId_2 = GetSignalDetainDisRelayId_2(signalId);

		devBlongCiId = GetSignalBelongCiId(signalId);        /*获取设备所属联锁ID*/
		if (localCiId == devBlongCiId)       /*只处理本联锁集中区*/
		{
			if (FUNC_SWITCH_ON != funcswitchZfsBtn)
			{
				/*非自复式扣车按钮驱动表示灯处理*/
				DriveDetainBsRelay(signalId, signalCutDetainRelayId, cutDetainDisplayId, signalDetainRelayId, signalDetainDisplayId);
				DriveDetainBsRelay(signalId, signalCutDetainRelayId_2, cutDetainDisplayId_2, signalDetainRelayId_2, signalDetainDisplayId_2);
			}
			else
			{
				/*自复式扣车按钮驱动表示灯处理*/
				DriveZfsDetainBsRelay(signalId, signalDetainDisplayId, cutDetainDisplayId);
			}
		}
		else
		{
			if (FUNC_SWITCH_ON != funcswitchZfsBtn)/*非自复式扣车按钮驱动表示灯处理*/
			{
				/*获取继电器所属联锁*/
				detainRelayBelongCi = GetRelayBelongCiId(signalDetainRelayId);        /*扣车继电器所属CI*/
				detainBsRelayBelongCi = GetRelayBelongCiId(signalDetainDisplayId);    /*扣车表示灯所属CI*/
				detainRelay_2BelongCi = GetRelayBelongCiId(signalDetainRelayId_2);
				detainBsRelay_2BelongCi = GetRelayBelongCiId(signalDetainDisplayId_2);
				cutRelayBelongCi = GetRelayBelongCiId(signalCutDetainRelayId);   /*扣车旁路所属CI*/
				cutBsRelayBelongCi = GetRelayBelongCiId(cutDetainDisplayId);     /*扣车旁路表示灯所属CI*/
				/*所有继电器都属于本联锁*/
				if ((cutRelayBelongCi == localCiId) && (cutBsRelayBelongCi == localCiId) &&
					(detainRelayBelongCi == localCiId) && (detainBsRelayBelongCi == localCiId))
				{
					/*驱动表示灯处理*/
					DriveDetainBsRelay(signalId, signalCutDetainRelayId, cutDetainDisplayId, signalDetainRelayId, signalDetainDisplayId);
				}

				cutRelay_2BelongCi = GetRelayBelongCiId(signalCutDetainRelayId_2);
				cutBsRelay_2BelongCi = GetRelayBelongCiId(cutDetainDisplayId_2);
				/*所有继电器都属于本联锁*/
				if ((cutRelay_2BelongCi == localCiId) && (cutBsRelay_2BelongCi == localCiId) &&
					(detainRelay_2BelongCi == localCiId) && (detainBsRelay_2BelongCi == localCiId))
				{
					/*驱动表示灯处理*/
					DriveDetainBsRelay(signalId, signalCutDetainRelayId_2, cutDetainDisplayId_2, signalDetainRelayId_2, signalDetainDisplayId_2);
				}
			}
			else
			{
				/*自复式扣车按钮驱动表示灯处理*/
				DriveZfsDetainBsRelay(signalId, signalDetainDisplayId, cutDetainDisplayId);
			}
		}
	}
}

/*
* 功能描述： 驱动扣车指示灯、扣车旁路指示灯
* 参数说明：const UINT16 signalCutDetainRelayId, 扣车旁路继电器ID
*           const UINT16 cutDetainDisplayId, 扣车旁路表示灯继电器ID
*           const UINT16 signalDetainRelayId, 扣车继电器ID
*           const UINT16 signalDetainDisplayId, 扣车表示灯继电器ID
*           const UINT16 signalId, 信号机ID
*
* 返回值  ： 无
*
*/
void DriveDetainBsRelay(const UINT16 signalId, const UINT16 signalCutDetainRelayId, const UINT16 cutDetainDisplayId, const UINT16 signalDetainRelayId, const UINT16 signalDetainDisplayId)
{
	/*变量初始化*/
	UINT8 tmpCutRelayColState = 0u; /*旁路继电器采集状态*/
	UINT8 tmpCollRelayColState = 0u; /*扣车继电器采集*/
	UINT8 relayDetainValidFlag = 0u;
	UINT8 signalDetainFlag = 0u;  /*信号机扣车标志*/
	UINT8 relayDrivState = 0u;    /*继电器驱动状态*/
	UINT16 wTempRelayId = 0U;
	UINT8 cFuncRet = 0U;

	/*硬线扣车旁路按钮指示灯继电器驱动*/
	if ((0u != signalCutDetainRelayId) && (UINT16_MAX != signalCutDetainRelayId) && (0u != cutDetainDisplayId) && (UINT16_MAX != cutDetainDisplayId))
	{/*硬线扣车旁路继电器和扣车旁路按钮指示灯继电器都有效*/
		tmpCutRelayColState = GetRelayCollState(signalCutDetainRelayId);/*获取扣车旁路按钮继电器状态*/
		if (RELAY_STATE_UP == tmpCutRelayColState)
		{
			(void)SetRelayDriveState(cutDetainDisplayId, RELAY_STATE_UP); /*指示灯亮灯*/
		}
		else if (RELAY_STATE_DOWN == tmpCutRelayColState)
		{
			(void)SetRelayDriveState(cutDetainDisplayId, RELAY_STATE_DOWN); /*指示灯灭灯*/
		}
		else
		{
			(void)SetRelayDriveState(cutDetainDisplayId, RELAY_STATE_DOWN); /*指示灯灭灯*/
		}
	}
	else
	{
		/*此信号机没有扣车旁路按钮或者没有扣车旁路按钮指示灯，不做处理*/
	}

	/*硬线扣车按钮指示灯继电器驱动*/
	if ((0u != signalDetainRelayId) && (UINT16_MAX != signalDetainRelayId) && (0u != signalDetainDisplayId) && (UINT16_MAX != signalDetainDisplayId))
	{/*硬线扣车继电器和扣车按钮指示灯继电器都有效*/

		relayDetainValidFlag = GetCiFunctionSwitchConfig(FUNC_RELAY_DETAIN_VALID_FLAG);/*获取硬线扣车有效标志*/
		tmpCollRelayColState = GetRelayCollState(signalDetainRelayId);/*获取扣车继电器采集状态*/
		signalDetainFlag = GetSignalDetainFlag(signalId);            /*获取信号机扣车标志*/
		relayDrivState = GetRelayDriveState(signalDetainDisplayId);   /*获取扣车指示灯继电器驱动状态*/
		wTempRelayId = GetSignalDetainRelayId(signalId);
		if (wTempRelayId == signalDetainRelayId)
		{
			cFuncRet = GetFstDetBtnCollTolerateRet(signalId);  /*获取扣车按钮1采集容忍结果*/
		}
		else
		{
			cFuncRet = GetSndDetBtnCollTolerateRet(signalId);  /*获取扣车按钮2采集容忍结果*/
		}
		if (CI_SUCCESS != cFuncRet)
		{
			/*扣车按钮按下,扣车*/
			(void)SetRelayDriveState(signalDetainDisplayId, RELAY_STATE_UP); /*指示灯亮灯*/
		}
		else if (((UP_VALID == relayDetainValidFlag) && (RELAY_DRIVE_STATE_DOWN == tmpCollRelayColState))
			|| ((DOWN_VALID == relayDetainValidFlag) && (RELAY_DRIVE_STATE_UP == tmpCollRelayColState))) /*继电器落下,未扣车*/
		{
			if ((SIGNAL_DETAIN_YES == signalDetainFlag) || (SIGNAL_DETAIN_XIANDI_ATSAUTO == signalDetainFlag) || (SIGNAL_DETAIN_ATS == signalDetainFlag) || (SIGNAL_DETAIN_ATS_AUTO == signalDetainFlag) || (SIGNAL_DETAIN_XIANDI == signalDetainFlag))
			{
				/*有软件扣车也需要驱动指示灯亮灯*/
				(void)SetRelayDriveState(signalDetainDisplayId, RELAY_STATE_UP); /*指示灯亮灯*/
			}
			else
			{
				/*继电器没有驱动过则驱动落下*/
				if (RELAY_DRIVE_STATE_NULL == relayDrivState)
				{
					/*硬线扣车和软件扣车都未实施则不驱指示灯*/
					(void)SetRelayDriveState(signalDetainDisplayId, RELAY_STATE_DOWN); /*指示灯灭灯*/
				}
			}
		}
		else
		{
			/*继电器状态无效或未达到采集容忍时间，判断是否存在软扣*/
			if ((SIGNAL_DETAIN_YES == signalDetainFlag) || (SIGNAL_DETAIN_XIANDI_ATSAUTO == signalDetainFlag) || (SIGNAL_DETAIN_ATS == signalDetainFlag) || (SIGNAL_DETAIN_ATS_AUTO == signalDetainFlag) || (SIGNAL_DETAIN_XIANDI == signalDetainFlag))
			{
				/*有软件扣车也需要驱动指示灯亮灯*/
				(void)SetRelayDriveState(signalDetainDisplayId, RELAY_STATE_UP); /*指示灯亮灯*/
			}
			else
			{
				/*继电器没有驱动过则驱动落下*/
				if (RELAY_DRIVE_STATE_NULL == relayDrivState)
				{
					/*硬线扣车和软件扣车都未实施则不驱指示灯*/
					(void)SetRelayDriveState(signalDetainDisplayId, RELAY_STATE_DOWN); /*指示灯灭灯*/
				}
			}
		}
	}
	else
	{
		/*此信号机没有扣车按钮或者没有扣车按钮指示灯，不做处理*/
	}
}

/*
* 功能描述：驱动自复式扣车相关指示灯
* 参数说明：const UINT16 signalId 信号机ID
*           const UINT16 signalDetDisRelayId 扣车表示灯继电器ID
*           const UINT16 signalDetCutDisRelayId 扣车旁路表示灯继电器
* 返 回 值：无
* Modified By LQ 2025.07.03
*/
void DriveZfsDetainBsRelay(const UINT16 signalId, const UINT16 signalDetDisRelayId, const UINT16 signalDetCutDisRelayId)
{
	UINT16 wSignalIdIndex = 0U;  /*信号机ID索引*/
	UINT16 wDetDisRelayIdIndex = 0U;  /*继电器ID索引*/
	UINT16 wDetCutDisRelayIdIndex = 0U;  /*继电器ID索引*/
	UINT8 localCiId = 0U;  /*本地联锁ID*/
	UINT8 detBsRelayBelongCi = 0U;   /*扣车表示灯继电器所属CI*/
	UINT8 detainBtnActFlag = SIGNAL_ZFS_BTN_ACT_FLAG_NO;    /*扣车按钮1激活标志*/
	UINT8 cDetCutBsRelayBelongCi = 0U;   /*扣车旁路按钮表示灯继电器所属CI*/
	UINT8 cDetCutBtnState = 0U;  /*扣车旁路按钮状态*/

	wSignalIdIndex = GetSignalConfigBufIndex(signalId);  /*获取信号机数组下标*/

	if (SIGNAL_SUM_MAX > wSignalIdIndex)
	{
		localCiId = GetSystemParaLocalCiId();

		/*扣车按钮表示灯驱动处理*/
		wDetDisRelayIdIndex = GetRelayConfigBufIndex(signalDetDisRelayId);  /*获取扣车按钮表示灯继电器数组下标*/
		if (RELAY_SUM_MAX > wDetDisRelayIdIndex)
		{			
			detBsRelayBelongCi = GetRelayBelongCiId(signalDetDisRelayId);

			/*设置扣车按钮表示灯继电器驱动状态*/
			if ((0U != localCiId) && (localCiId == detBsRelayBelongCi))
			{
				/*获取自复式扣车按钮1激活标志*/
				detainBtnActFlag = GetSignalDetainBtnActFlag(signalId);

				/*设置扣车指示灯亮灭状态*/
				if (SIGNAL_ZFS_BTN_ACT_FLAG_YES == detainBtnActFlag)
				{
					(void)SetRelayDriveState(signalDetDisRelayId, RELAY_STATE_UP); /*扣车按钮激活，驱动扣车指示灯亮灯*/
				}
				else
				{
					(void)SetRelayDriveState(signalDetDisRelayId, RELAY_STATE_DOWN); /*扣车按钮未激活，驱动扣车指示灯灭灯*/
				}
			}
			else
			{
				/*非本控区继电器，不处理*/
			}
		}
		else
		{
			/*不处理*/
		}

		/*扣车旁路按钮表示灯驱动处理*/
		wDetCutDisRelayIdIndex = GetRelayConfigBufIndex(signalDetCutDisRelayId);  /*获取扣车旁路按钮表示灯继电器数组下标*/
		if (RELAY_SUM_MAX > wDetCutDisRelayIdIndex)
		{
			cDetCutBsRelayBelongCi = GetRelayBelongCiId(signalDetCutDisRelayId);
			/*设置扣车旁路按钮表示灯继电器驱动状态*/
			if ((0U != localCiId) && (localCiId == cDetCutBsRelayBelongCi))
			{
				/*获取自复式扣车旁路按钮状态*/
				cDetCutBtnState = GetDetCutBtnState(signalId);

				/*设置扣车旁路按钮指示灯亮灭状态*/
				if (SIGNAL_DETAIN_CUT_VALID_YES == cDetCutBtnState)
				{
					(void)SetRelayDriveState(signalDetCutDisRelayId, RELAY_STATE_UP); /*扣车旁路按钮有效，驱动扣车指示灯亮灯*/
				}
				else
				{
					(void)SetRelayDriveState(signalDetCutDisRelayId, RELAY_STATE_DOWN); /*扣车旁路按钮无效，驱动扣车指示灯灭灯*/
				}
			}
			else
			{
				/*非本控区继电器，不处理*/
			}
		}
		else
		{
			/*不处理*/
		}
	}
	else
	{
		/*不做处理*/
	}
}

/*
* 功能描述：计轴总复位表示灯驱动输出处理
* 参数说明： void
* 返回值  ： void
*/
void PhyZFWBsRelayDriveOutput(void)
{
	/*变量初始化*/
	UINT16 i = 0u;
	UINT16 phyId = 0u;
	UINT16 ZFWShowRelayId = 0u;
	UINT8 ZFWShowDriState = 0u;
	UINT8 ZFWRelayState = 0u;
	UINT16 ZFWRelayId = 0u;
	UINT16 phyCurSum = 0u;
	UINT8  localCiId = 0u;          /*本地联锁ID*/
	UINT8  phyBlongCiId = 0u;       /*设备所属联锁ID*/

	/*物理区段数*/
	phyCurSum = GetPhySecCurSum();
	localCiId = GetSystemParaLocalCiId(); /*获取本地联锁ID*/

	for (i = 0u; i < phyCurSum; i++)
	{
		/*区段ID*/
		phyId = GetPhySecId(i);
		phyBlongCiId = GetPhySecBelongCiId(phyId);
		/*区段是本联锁*/
		if (phyBlongCiId == localCiId)
		{
			/*获取继电器ID*/
			ZFWRelayId = GetPhySecZFWRelayId(phyId);
			ZFWShowRelayId = GetPhySecZFWShowRelayId(phyId);
			ZFWRelayState = GetRelayCollState(ZFWRelayId);
			/*总复位表示灯存在*/
			if (0u < ZFWShowRelayId)
			{
				ZFWShowDriState = GetRelayDriveState(ZFWShowRelayId);
				/*总复位按下,继电器吸起*/
				if (RELAY_STATE_UP == ZFWRelayState)
				{
					/*驱动表示灯吸起*/
					(void)SetRelayDriveState(ZFWShowRelayId, RELAY_DRIVE_STATE_UP);
				}
				else
				{
					/*没有驱动*/
					if (RELAY_DRIVE_STATE_NULL == ZFWShowDriState)
					{
						/*驱动表示灯落下*/
						(void)SetRelayDriveState(ZFWShowRelayId, RELAY_DRIVE_STATE_DOWN);
					}
				}
			}
			else
			{
				/*不做处理*/
			}
		}
	}
}


/*
* 功能描述： 信号机继电器状态->逻辑状态
* 参数说明： const UINT32 curCycleNum, 当前周期号
* 返回值  ： 0u: 更新失败
*			 1: 更新成功
*/
void SignalRelayToDeviceStateProc(void)
{
	UINT16 signalCurSum = 0u;	/*信号机总数目*/
	UINT16 signalId = 0u;	    /*信号机ID*/
	UINT8 localCiId = 0u;        /*本地联锁ID*/
	UINT16 ii = 0u;              /*循环索引*/
	UINT8 signalBelongCi = 0u;       /*信号机所属联锁ID*/
	UINT8 signalCurColor = 0u;	/*信号机当前显示颜色*/
	UINT8 signalVirtualAttr = 0u;/*信号机虚拟属性*/
	UINT8 signalPreDrvColor = 0u;/*信号机之前驱动颜色*/
	UINT16 signalDetainRelayId = 0u;/*信号机硬线扣车ID*/
	UINT8 tmpRelayColState = 0u;/*继电器采集状态*/

	UINT8 sendLvl = ESEND_LEVEL_ZERO;/*发送级别*/
	UINT8 funcId = EFUNC_SIGNAL_RELAY_TO_DEVICE;/*函数ID*/
	UINT8 relayDetainValidFlag = 0u;/*硬线扣车标志*/

	UINT16 detainRelayId = 0u;/*扣车继电器ID*/
	UINT8 relayBelongCIId = 0u;/*继电器所属联锁ID*/
	UINT8 relayCollState = 0u;/*继电器采集状态*/
	UINT8 signalType = 0u;/*信号机驱采类型*/
	UINT8 signalBlockOpenColor = 0u;/*信号机后备开放颜色*/
	UINT8 commState = 0u;/*通信状态*/
	/*相邻联锁是否支持继电接口*/
	UINT8 funcSwitchSupportRelayInterface = GetCiFunctionSwitchConfig(FUNC_SWITCH_USE_RELAY_INTERFACE_BETWEEN_NEIGHBOURCI);

	UINT16	lxRelayId = 0u;    	/*列车信号继电器ID*/
	UINT8	lxRelaySta = RELAY_STATE_DOWN;    	/*列车信号继电器状态*/
	UINT8	lxBelongCi = 0u;/*列车信号继电器所属联锁*/

	signalCurSum = GetTotalSignalCurNum();		    /*获取信号机总数*/
	localCiId = GetSystemParaLocalCiId();       /*获取本机联锁ID*/


	/*处理信号机*/
	for (ii = 0u; ii < signalCurSum; ii++)
	{
		signalId = 0u;	    /*信号机ID*/
		signalBelongCi = 0u;     /*信号机所属联锁ID*/

		signalId = GetSignalId(ii);                          /*获取信号机ID*/
		signalBelongCi = GetSignalBelongCiId(signalId);          /*获取信号机所属联锁ID*/
		signalVirtualAttr = GetSignalVirtualAttr(signalId);  /*获取信号机虚拟属性*/


		if ((0u == signalId) || (signalId > SIGNAL_SUM_MAX) || (localCiId == 0u))
		{
			/*信号机id不合法，或者本联锁ID为0u,不处理*/
		}
		else if (signalBelongCi == localCiId)
		{
			/*获取信号机显示颜色*/
			if (SIGNAL_VIRTUAL_YES == signalVirtualAttr)
			{/*虚拟信号机当前显示颜色为之前驱动颜色*/
				signalCurColor = GetSignalPreDriveColor(signalId);
			}
			else if (SIGNAL_VIRTUAL_NO == signalVirtualAttr)
			{
				signalCurColor = GetSignalShowColor(signalId);
			}
			else
			{
				/*无操作*/
			}

			/*设置信号机驱动无效*/
			SetSignalCurDriveColor(signalId, SIGNAL_DRIVECOLOUR_NULL);

			if (signalCurColor != SIGNAL_SHOWCOLOUR_INVALID)
			{/*颜色有效*/

				/*设置当前显示颜色*/
				(void)SetSignalCurColor(signalId, signalCurColor);
			}
			else
			{/*颜色无效*/

				/*设置当前显示颜色*/
				(void)SetSignalCurColor(signalId, signalCurColor);
			}

			/*如果信号机当前是开放的，并且之前也是驱动开放，但是驱动颜色和当前颜色不同，驱关闭*/
			if (GetSignalOpenCloseState(signalCurColor) == SIGNAL_OPEN)
			{
				signalPreDrvColor = GetSignalPreDriveColor(signalId);/*获取信号机之前驱动颜色*/
				/*记录信号采集开放周期*/
				if (0u == GetSignalCollOpenStartCycNum(signalId))
				{
					(void)SetSignalCollOpenStartCycNum(signalId, Get2oo2CurCycleNum());
				}
				if ((GetSignalOpenCloseState(signalPreDrvColor) == SIGNAL_OPEN) && (signalPreDrvColor != signalCurColor))
				{/*之前驱动开放且和当前开放颜色不同*/
					if (0u == GetSignalDiffColorOpenStartCyc(signalId))
					{
						(void)SetSignalDiffColorOpenStartCyc(signalId, Get2oo2CurCycleNum());/*设置信号机驱动开放颜色不等于当前开放颜色起始周期*/
					}
					else
					{
						/*判断是否超过容忍周期数*/
						if ((Get2oo2CurCycleNum() - GetSignalDiffColorOpenStartCyc(signalId)) >= SIGNAL_RELAY_ACTION_TIMEMAX)
						{/*超时*/
							(void)DriveSignalClose(signalId);/*驱动关闭*/
							SetErrorData(funcId, CI_DEVICE_TYPE_SIGNAL, signalId, ETYPE_SIG_START_OPEN_STATE, SIGNAL_CLOSE, sendLvl);
							(void)SetSignalDiffColorOpenStartCyc(signalId, 0u);/*清空信号机驱动开放颜色不等于当前开放颜色起始周期*/
						}
						else
						{
							/*没有超时，继续容忍，不做处理*/
						}
					}
				}
				else
				{
					(void)SetSignalDiffColorOpenStartCyc(signalId, 0u);/*清空信号机驱动开放颜色不等于当前开放颜色起始周期*/
				}
			}
			else
			{
				(void)SetSignalDiffColorOpenStartCyc(signalId, 0u);/*清空信号机驱动开放颜色不等于当前开放颜色起始周期*/
				/*信号采集开放周期清零*/
				(void)SetSignalCollOpenStartCycNum(signalId, 0u);
			}

			/*武汉联络线需求，只采集复示列车继电器*/
			SetNoDriveSignalCurColor(signalId);
			/*处理信号机硬线扣车状态*/
			signalDetainRelayId = GetSignalDetainRelayId(signalId);
			if ((0u != signalDetainRelayId) && (UINT16_MAX != signalDetainRelayId))
			{/*硬线扣车继电器有效*/

				relayBelongCIId = GetRelayBelongCiId(signalDetainRelayId);/*扣车继电器所属联锁ID*/
				if (relayBelongCIId == localCiId)
				{/*硬线扣车继电器所属联锁为本联锁*/
					tmpRelayColState = GetRelayCollState(signalDetainRelayId);/*获取扣车继电器采集状态*/

					relayDetainValidFlag = GetCiFunctionSwitchConfig(FUNC_RELAY_DETAIN_VALID_FLAG);/*获取硬线扣车有效标志*/

					if (DOWN_VALID == relayDetainValidFlag)
					{/*落下有效*/
						if (RELAY_DRIVE_STATE_DOWN == tmpRelayColState)
						{/*继电器落下：扣车*/
							SetSignalRelayDetainFlag(signalId, SIGNAL_RELAY_DETAIN_YES);
						}
						else if (RELAY_DRIVE_STATE_UP == tmpRelayColState)
						{/*继电器吸起：未扣车*/
							SetSignalRelayDetainFlag(signalId, SIGNAL_RELAY_DETAIN_NO);
						}
						else
						{/*非法值，认为有硬线扣车*/
							SetSignalRelayDetainFlag(signalId, SIGNAL_RELAY_DETAIN_YES);
						}
					}
					else
					{
						/*吸起有效*/
						if (RELAY_DRIVE_STATE_UP == tmpRelayColState)
						{/*继电器吸起：扣车*/
							SetSignalRelayDetainFlag(signalId, SIGNAL_RELAY_DETAIN_YES);
						}
						else if (RELAY_DRIVE_STATE_DOWN == tmpRelayColState)
						{/*继电器落下：未扣车*/
							SetSignalRelayDetainFlag(signalId, SIGNAL_RELAY_DETAIN_NO);
						}
						else
						{/*非法值，认为有硬线扣车*/
							SetSignalRelayDetainFlag(signalId, SIGNAL_RELAY_DETAIN_YES);
						}
					}
				}

			}
			else
			{
				/*do nothing*/
			}
		}
		else if (signalBelongCi != localCiId)
		{/*如果信号机所属联锁与本联锁不同*/
			commState = GetLocalCiAndOtherCiTransSta(signalBelongCi);/*本联锁与信号机所在联锁通信状态*/
			/*这种情况处理信号机不属于本联锁，但信号机扣车继电器属于本联锁的情况*/
			detainRelayId = GetSignalDetainRelayId(signalId);
			if (detainRelayId > 0u)
			{
				relayBelongCIId = GetRelayBelongCiId(detainRelayId);/*扣车继电器所属联锁ID*/
				if (relayBelongCIId == localCiId)
				{/*信号机扣车继电器属于本联锁*/
					relayCollState = GetRelayCollState(detainRelayId);/*获取继电器采集状态*/
					relayDetainValidFlag = GetCiFunctionSwitchConfig(FUNC_RELAY_DETAIN_VALID_FLAG);/*获取硬线扣车有效标志*/

					if (DOWN_VALID == relayDetainValidFlag)
					{/*落下有效*/
						if (RELAY_DRIVE_STATE_DOWN == relayCollState)
						{/*继电器落下：扣车*/
#if 0
							SetSignalRelayDetainFlag(signalId,SIGNAL_RELAY_DETAIN_YES);
#endif
							AddCiSendToCiCmdInfo((UINT8)CI_CMD_KOUCHE_DETAIN, signalId, SIGNAL_DETAIN_CI_RELAY_YES, signalBelongCi);
						}
						else if (RELAY_DRIVE_STATE_UP == relayCollState)
						{/*继电器吸起：未扣车*/
#if 0
							SetSignalRelayDetainFlag(signalId,SIGNAL_RELAY_DETAIN_NO);
#endif
							AddCiSendToCiCmdInfo((UINT8)CI_CMD_KOUCHE_DETAIN, signalId, SIGNAL_DETAIN_CI_RELAY_NO, signalBelongCi);
						}
						else
						{
							/*非法值，不处理*/
						}
					}
					else
					{
						/*吸起有效*/
						if (RELAY_DRIVE_STATE_UP == relayCollState)
						{/*继电器吸起：扣车*/
#if 0
							SetSignalRelayDetainFlag(signalId,SIGNAL_RELAY_DETAIN_YES);
#endif
							AddCiSendToCiCmdInfo((UINT8)CI_CMD_KOUCHE_DETAIN, signalId, SIGNAL_DETAIN_CI_RELAY_YES, signalBelongCi);
						}
						else if (RELAY_DRIVE_STATE_DOWN == relayCollState)
						{/*继电器落下：未扣车*/
#if 0
							SetSignalRelayDetainFlag(signalId,SIGNAL_RELAY_DETAIN_NO);
#endif
							AddCiSendToCiCmdInfo((UINT8)CI_CMD_KOUCHE_DETAIN, signalId, SIGNAL_DETAIN_CI_RELAY_NO, signalBelongCi);
						}
						else
						{
							/*非法值，不处理*/
						}
					}
				}
			}

			if ((TRANSMIT_STATE_BAD == commState) &&
				(FUNC_SWITCH_ON == funcSwitchSupportRelayInterface))
			{
				/*本联锁与信号机所属联锁通信中断，且已配置支持继电接口，则可以把该信号机LXJ状态转换为信号机开放颜色*/
				lxRelayId = GetSignalRepLxRelayId(signalId);
				if (lxRelayId > 0u)
				{
					lxBelongCi = GetRelayBelongCiId(lxRelayId);
					if (lxBelongCi == localCiId)
					{/*复视列车信号继电器为本联锁继电器*/
						lxRelaySta = GetRelayCollState(lxRelayId);/*信号机列车信号继电器采集状态*/
						if (RELAY_STATE_UP == lxRelaySta)
						{
							signalType = GetSignalType(signalId);/*获取信号机驱采类型*/
							signalBlockOpenColor = GetSignalBlockOpenColorValue((UINT16)signalType);/*获取信号机后备开放颜色*/

							(void)SetSignalCurColor(signalId, signalBlockOpenColor);/*设置信号机当前颜色*/
						}
						else if (RELAY_STATE_DOWN == lxRelaySta)
						{
							(void)SetSignalCurColor(signalId, SIGNAL_DRIVECOLOUR_RED);/*列线继电器落下，设置信号机显示红灯*/
						}
						else
						{/*继电器状态非法，设置红灯*/
							(void)SetSignalCurColor(signalId, SIGNAL_DRIVECOLOUR_RED);
						}
					}

				}
			}
		}
		else
		{
			/*其它情况，不处理*/
		}

	}
}


/*
* 功能描述： 信号机逻辑状态->继电器状态
* 参数说明： void
* 返回值  ： 0u: 更新失败
*			 1: 更新成功
*/
void SignalDeviceToRelayStateProc(void)
{
	UINT16 signalCurSum = 0u; /*信号机总数目*/
	UINT8 localCiId = 0u; /*本地联锁ID*/
	UINT16 signalId = 0u; /*信号机ID*/
	UINT8 curDrvColor = 0u; /*信号机当前驱动颜色*/
	UINT8 curShowColor = 0u; /*信号机当前显示颜色*/
	UINT16 ii = 0u; /*循环索引*/
	UINT8 signalVirtualAttr = 0u;/*信号机虚拟属性*/

	UINT16 firDsRelayId = 0u;  	/*1灯丝继电器ID */
	UINT16 secDsRelayId = 0u;  	/*2灯丝继电器ID*/
	UINT16 lxRelayId = 0u;    	/*列车信号继电器ID*/
	UINT16 zxRelayId = 0u;    	/*正线信号继电器ID*/
	UINT16 yxRelayId = 0u;    	/*引导信号继电器ID*/
	UINT16 dxRelayId = 0u;		/*调车信号继电器ID*/
	UINT16 yellowRelayId = 0u;	/*黄灯继电器ID*/
	UINT16 greenRelayId = 0u;	/*绿灯继电器ID*/
	UINT16 blueRelayId = 0u;		/*蓝灯继电器ID*/
	UINT16 replxRelayId = 0u;    /*复示列车信号继电器ID*/
	UINT16 ddRelayId = 0u;    	/*点灯继电器ID*/

	UINT8 jkjRelayValidFlag = 0u;
	UINT8 checkRes = CI_TIME_OUT;
	UINT32 sigCycle = 0u;
	UINT32 sysParaCycle = 0u;
	UINT8 tmpRet = CI_ERROR;
	UINT8 sigColor = SIGNAL_SHOWCOLOUR_INVALID;

	UINT8 signalBelongCi = 0u;       /*信号机所属联锁ID*/
	UINT8 commState = 0u;/*通信状态*/
	UINT16 detainDriveRelayId = 0u;/*扣车驱动继电器ID*/
	UINT8 detainDriveRelayBelongCi = 0u;/*扣车区段继电器所属联锁*/
	UINT8 neighbourSignalDetainDrive = 0u;/*邻站信号机扣车驱动命令*/
	/*相邻联锁是否支持继电接口*/
	UINT8 funcSwitchSupportRelayInterface = GetCiFunctionSwitchConfig(FUNC_SWITCH_USE_RELAY_INTERFACE_BETWEEN_NEIGHBOURCI);
	UINT8 relayDetainValidFlag = 0u;/*硬线扣车标志*/
	UINT8 signalIsfushiFlag = 0u;

	signalCurSum = GetTotalSignalCurNum();		    /*获取信号机总数*/
	localCiId = GetSystemParaLocalCiId(); /*获取本机联锁ID*/
	/*处理信号机*/
	for (ii = 0u; ii < signalCurSum; ii++)
	{
		signalId = GetSignalId(ii); /*获取信号机ID*/
		signalBelongCi = GetSignalBelongCiId(signalId); /*获取信号机所属联锁ID*/
		signalVirtualAttr = GetSignalVirtualAttr(signalId);/*获取信号机虚拟属性*/
		firDsRelayId = GetSignalFirstDsRelayId(signalId);  /*获取信号机1灯丝继电器ID*/
		secDsRelayId = GetSignalSecondDsRelayId(signalId);  /*获取信号机2灯丝继电器ID*/
		lxRelayId = GetSignalLxRelayId(signalId);  /*获取信号机列车信号继电器ID*/
		zxRelayId = GetSignalZxRelayId(signalId);  /*获取信号机正线信号继电器ID*/
		yxRelayId = GetSignalYxRelayId(signalId);  /*获取信号机引导信号继电器ID*/
		dxRelayId = GetSignalDxRelayId(signalId);	/*获取信号机调车信号继电器ID*/
		yellowRelayId = GetSignalYellowRelayId(signalId);	/*黄灯继电器ID*/
		greenRelayId = GetSignalGreenRelayId(signalId);		/*绿灯继电器ID*/
		blueRelayId = GetSignalBlueRelayId(signalId);		/*蓝灯继电器ID*/
		replxRelayId = GetSignalRepLxRelayId(signalId);   /*复示列车继电器ID*/
		ddRelayId = GetSignalDdRelayId(signalId);        /*获取信号机点灯继电器ID*/
		if ((0u == signalId) || (signalId > SIGNAL_SUM_MAX) || (localCiId == 0u))
		{
			/*信号机id不合法，或者本联锁ID为0u,不处理*/
		}
		else if (signalBelongCi == localCiId)
		{
			/***处理超时驱动***/
			curDrvColor = GetSignalCurDriveColor(signalId);  /*获取信号机当前驱动颜色*/
			if (SIGNAL_DRIVECOLOUR_NULL == curDrvColor)
			{/*信号机驱动无效*/
				jkjRelayValidFlag = GetCiJkjFlag();
				curShowColor = GetSignalCurColor(signalId);
				if (((SIGNAL_SHOWCOLOUR_REDYELLOW == curShowColor) || (SIGNAL_SHOWCOLOUR_RED_WHITE == curShowColor)) &&
					(JKJ_REYLAY_VALID == jkjRelayValidFlag))
				{
					/*引导信号开放时间在应急盘有效之后，人工办理引导信号开放，不执行驱引导信号关闭逻辑（不宕机）*/
				}
				else
				{
					/*只有采集：判断除了复示LXJ，其他继电器ID全为0u；武汉5-8号线联络线需求*/
					if ((0u == firDsRelayId) && (0u == secDsRelayId) && (0u == lxRelayId) && (0u == zxRelayId)
						&& (0u == yxRelayId) && (0u == dxRelayId) && (0u == yellowRelayId) && (0u == greenRelayId)
						&& (0u == blueRelayId) && (0u == ddRelayId) && (0u != replxRelayId))
					{
						/*只有采集：不做驱动*/
					}
					else
					{
						tmpRet = DriveSignalClose(signalId);  /*驱动信号机关闭*/
						if (CI_ERROR == tmpRet)
						{
							/*错误处理*/
						}
					}
				}
			}
			curDrvColor = GetSignalCurDriveColor(signalId);  /*获取信号机当前驱动颜色*/


			if ((SIGNAL_DRIVECOLOUR_RED == curDrvColor) || (SIGNAL_DRIVECOLOUR_REDCLOSE == curDrvColor))
			{/*信号机关闭*/
				sigCycle = GetSignalDriveCloseStartCycNum(signalId);
				sysParaCycle = GetSystemParaSignalCloseCyc();
				checkRes = SystemOverTimeCheck(sigCycle, sysParaCycle);
				if (CI_TIME_OUT == checkRes)
				{/*信号机关闭超时*/

					signalIsfushiFlag = GetSignalIsfushiFlag(signalId);
					if (SIGNALTYPE_FUSHI_YES != signalIsfushiFlag)/*复示信号机驱动关闭超时，不宕机*/
					{
						/*xxxxx宕机 信号机关闭超时*/
						SetPlatOverFlag(); /*设置平台宕机*/
						SetErrorData(EFUNC_PLAT_OVER, CI_DEVICE_TYPE_SIGNAL, signalId, ETYPE_SIG_CLOSE_OVER_TIME, curDrvColor, ESEND_LEVEL_ZERO);/*记录宕机故障码*/
					}
				}
			}
			else
			{/*信号机开放状态*/
				sigCycle = GetSignalDriveOpenStartCycNum(signalId);
				sysParaCycle = GetSystemParaSignalOpenCyc();
				checkRes = SystemOverTimeCheck(sigCycle, sysParaCycle);
				if (CI_TIME_OUT == checkRes)
				{/*信号开放状态*/

					tmpRet = DriveSignalClose(signalId);/*驱动信号机关闭*/
					if (CI_ERROR == tmpRet)
					{
						/*错误处理*/
					}
				}
			}


			/***处理信号机驱动继电器***/

			if (SIGNAL_VIRTUAL_NO == signalVirtualAttr)
			{/*非虚拟信号机才进行驱动继电器动作*/
				tmpRet = SetSignalRelayState(signalId);
				if (CI_ERROR == tmpRet)
				{
					/*驱动信号机相关继电器执行点灯*/
				}
			}

			/*保存之前显示颜色，对虚拟信号机而言相当于根据逻辑状态驱动继电器状态*/
			sigColor = GetSignalCurDriveColor(signalId);
			tmpRet = SetSignalPreDriveColor(signalId, sigColor);
			if (CI_ERROR == tmpRet)
			{
				/*错误处理*/
			}
		}
		else if (signalBelongCi != localCiId)
		{/*如果信号机所属联锁与本联锁不同*/
			commState = GetLocalCiAndOtherCiTransSta(signalBelongCi);/*本联锁与信号机所在联锁通信状态*/
			detainDriveRelayId = GetSignalDetainDriveRelayId(signalId);
			detainDriveRelayBelongCi = GetRelayBelongCiId(detainDriveRelayId);
			if ((detainDriveRelayBelongCi == localCiId) && (TRANSMIT_STATE_BAD == commState) &&
				(FUNC_SWITCH_ON == funcSwitchSupportRelayInterface))
			{/*扣车驱动继电器所属联锁为本联锁，且 与信号机所属联锁通信中断，且配置了支持继电接口*/
				neighbourSignalDetainDrive = GetSignalNeighbourDetainDrive(signalId);
				if (NEIGHBOUR_SIGNAL_DETAIN_DRIVE_YES == neighbourSignalDetainDrive)
				{/*扣车驱动命令有效*/
					relayDetainValidFlag = GetCiFunctionSwitchConfig(FUNC_RELAY_DETAIN_VALID_FLAG);/*获取硬线扣车有效标志*/

					if (DOWN_VALID == relayDetainValidFlag)
					{/*落下有效*/
						(void)SetRelayDriveState(detainDriveRelayId, RELAY_DRIVE_STATE_DOWN);
					}
					else
					{
						/*吸起有效*/
						(void)SetRelayDriveState(detainDriveRelayId, RELAY_DRIVE_STATE_UP);
					}
				}
				else
				{/*扣车驱动命令取消*/
					relayDetainValidFlag = GetCiFunctionSwitchConfig(FUNC_RELAY_DETAIN_VALID_FLAG);/*获取硬线扣车有效标志*/

					if (DOWN_VALID == relayDetainValidFlag)
					{/*落下有效*/
						(void)SetRelayDriveState(detainDriveRelayId, RELAY_DRIVE_STATE_UP);
					}
					else
					{
						/*吸起有效*/
						(void)SetRelayDriveState(detainDriveRelayId, RELAY_DRIVE_STATE_DOWN);
					}
				}
			}

		}
		else
		{
			/*其它情况，不处理*/
		}
	}
}


/*
* 功能描述： 根据信号机驱动信息驱动指定ID信号机继电器
* 参数说明： const UINT16 signalId
* 返回值  ： 0u:设置失败
*			 >0u:设置成功
*/
UINT8 SetSignalRelayState(const UINT16 signalId)
{
	UINT8 bCiSwitchShowGreenYellow = FUNC_SWITCH_OFF;/*ci显示绿黄开关,默认是关闭的*/

	UINT16 firDsRelayId = 0u;  	/*1灯丝继电器ID */
	UINT16 secDsRelayId = 0u;  	/*2灯丝继电器ID*/
	UINT16 lxRelayId = 0u;    	/*列车信号继电器ID*/
	UINT16 zxRelayId = 0u;    	/*正线信号继电器ID*/
	UINT16 yxRelayId = 0u;    	/*引导信号继电器ID*/
	UINT16 ddRelayId = 0u;    	/*点灯继电器ID*/
	UINT16 dxRelayId = 0u;		/*调车信号继电器ID*/
	UINT16 yellowRelayId = 0u;	/*黄灯继电器ID*/
	UINT16 greenRelayId = 0u;	/*绿灯继电器ID*/
	UINT16 blueRelayId = 0u;		/*蓝灯继电器ID*/

	UINT8 firDsRelaySta = RELAY_STATE_DOWN;  	/*1灯丝继电器状态 */
	UINT8 secDsRelaySta = RELAY_STATE_DOWN;  	/*2灯丝继电器状态*/
	UINT8 lxRelaySta = RELAY_STATE_DOWN;    	/*列车信号继电器状态*/
	UINT8 zxRelaySta = RELAY_STATE_DOWN;    	/*正线信号继电器状态*/
	UINT8 yxRelaySta = RELAY_STATE_DOWN;    	/*引导信号继电器状态*/
	UINT8 ddRelaySta = RELAY_STATE_DOWN;    	/*点灯继电器状态*/
	UINT8 dxRelaySta = RELAY_STATE_DOWN;		/*调车信号继电器状态*/
	UINT8 yellowRelaySta = RELAY_STATE_DOWN;	/*黄灯继电器状态*/
	UINT8 greenRelaySta = RELAY_STATE_DOWN;		/*绿灯继电器状态*/
	UINT8 blueRelaySta = RELAY_STATE_DOWN;		/*蓝灯继电器状态*/

	UINT8 signalType = GetSignalType(signalId); /*信号机点灯逻辑类型*/
	UINT8 curDrvColor = GetSignalCurDriveColor(signalId); /*信号机当前驱动颜色*/
	UINT8 OldDriveColor = GetSignalOldDriveColor(signalId); /*信号机当前驱动颜色*/

	UINT8 returnValue = CI_SUCCESS;/*返回值默认成功*/
	UINT32 curCycleNum = Get2oo2CurCycleNum();
	UINT32 drvNewSigStartCycNum = GetSignalDriveNewSigStartCycNum(signalId);

	firDsRelayId = GetSignalFirstDsRelayId(signalId);  /*获取信号机1灯丝继电器ID*/
	secDsRelayId = GetSignalSecondDsRelayId(signalId);  /*获取信号机2灯丝继电器ID*/
	lxRelayId = GetSignalLxRelayId(signalId);  /*获取信号机列车信号继电器ID*/
	zxRelayId = GetSignalZxRelayId(signalId);  /*获取信号机正线信号继电器ID*/
	yxRelayId = GetSignalYxRelayId(signalId);  /*获取信号机引导信号继电器ID*/
	dxRelayId = GetSignalDxRelayId(signalId);	/*获取信号机调车信号继电器ID*/
	ddRelayId = GetSignalDdRelayId(signalId);  /*获取信号机点灯继电器ID*/
	yellowRelayId = GetSignalYellowRelayId(signalId);	/*黄灯继电器ID*/
	greenRelayId = GetSignalGreenRelayId(signalId);		/*绿灯继电器ID*/
	blueRelayId = GetSignalBlueRelayId(signalId);		/*蓝灯继电器ID*/

	firDsRelaySta = GetRelayCollState(firDsRelayId);	/*获取信号机1灯丝继电器状态*/
	secDsRelaySta = GetRelayCollState(secDsRelayId);	/*获取信号机2灯丝继电器状态*/
	ddRelaySta = GetRelayCollState(ddRelayId);	/*获取信号机点灯继电器状态*/
	lxRelaySta = GetRelayCollState(lxRelayId);	/*获取信号机列车信号继电器状态*/
	yxRelaySta = GetRelayCollState(yxRelayId);	/*获取信号机引导信号继电器状态*/
	zxRelaySta = GetRelayCollState(zxRelayId);  /*获取信号机正线信号继电器状态*/
	dxRelaySta = GetRelayCollState(dxRelayId);	/*获取信号机调车信号继电器状态*/
	yellowRelaySta = GetRelayCollState(yellowRelayId);
	greenRelaySta = GetRelayCollState(greenRelayId);
	blueRelaySta = GetRelayCollState(blueRelayId);

	bCiSwitchShowGreenYellow = GetCiFunctionSwitchConfig(CI_FUNCTION_SWITCH_SHOW_SIGNAL_GreenYellow);

	switch (signalType)
	{
	case SIGNAL_TYPE_4_ALL_NOYINDAO_ZX:  /* 0x2A 四显示（不封灯、不带引导） 红、绿、蓝、黄*/
	{
		if (FUNC_SWITCH_ON == bCiSwitchShowGreenYellow)/*如果显示绿黄灯开关【打开】*/
		{
			switch (curDrvColor)
			{
			case SIGNAL_DRIVECOLOUR_GREENCLOSE:
			{
				(void)SetRelayDriveState(ddRelayId, RELAY_STATE_UP);
				(void)SetRelayDriveState(lxRelayId, RELAY_STATE_UP);
				(void)SetRelayDriveState(zxRelayId, RELAY_STATE_UP);
				(void)SetRelayDriveState(greenRelayId, RELAY_STATE_UP);
				(void)SetRelayDriveState(yellowRelayId, RELAY_STATE_DOWN);
				break;
			}
			case SIGNAL_DRIVECOLOUR_GREEN:
			{
				(void)SetRelayDriveState(ddRelayId, RELAY_STATE_DOWN);
				(void)SetRelayDriveState(lxRelayId, RELAY_STATE_UP);
				(void)SetRelayDriveState(zxRelayId, RELAY_STATE_UP);
				(void)SetRelayDriveState(greenRelayId, RELAY_STATE_UP);
				(void)SetRelayDriveState(yellowRelayId, RELAY_STATE_DOWN);
				break;
			}
			case SIGNAL_DRIVECOLOUR_GREENYELLOWCLOSE:
			{
				(void)SetRelayDriveState(ddRelayId, RELAY_STATE_UP);
				(void)SetRelayDriveState(lxRelayId, RELAY_STATE_UP);
				(void)SetRelayDriveState(zxRelayId, RELAY_STATE_UP);
				(void)SetRelayDriveState(greenRelayId, RELAY_STATE_DOWN);
				(void)SetRelayDriveState(yellowRelayId, RELAY_STATE_DOWN);
				break;
			}
			case SIGNAL_DRIVECOLOUR_GREENYELLOW:
			{
				(void)SetRelayDriveState(ddRelayId, RELAY_STATE_DOWN);
				(void)SetRelayDriveState(lxRelayId, RELAY_STATE_UP);
				(void)SetRelayDriveState(zxRelayId, RELAY_STATE_UP);
				(void)SetRelayDriveState(greenRelayId, RELAY_STATE_DOWN);
				(void)SetRelayDriveState(yellowRelayId, RELAY_STATE_DOWN);
				break;
			}
			case SIGNAL_DRIVECOLOUR_YELLOWCLOSE:
			{
				(void)SetRelayDriveState(ddRelayId, RELAY_STATE_UP);
				(void)SetRelayDriveState(lxRelayId, RELAY_STATE_UP);
				(void)SetRelayDriveState(zxRelayId, RELAY_STATE_DOWN);
				(void)SetRelayDriveState(greenRelayId, RELAY_STATE_DOWN);
				(void)SetRelayDriveState(yellowRelayId, RELAY_STATE_UP);
				break;
			}
			case SIGNAL_DRIVECOLOUR_YELLOW:
			{
				(void)SetRelayDriveState(ddRelayId, RELAY_STATE_DOWN);
				(void)SetRelayDriveState(lxRelayId, RELAY_STATE_UP);
				(void)SetRelayDriveState(zxRelayId, RELAY_STATE_DOWN);
				(void)SetRelayDriveState(greenRelayId, RELAY_STATE_DOWN);
				(void)SetRelayDriveState(yellowRelayId, RELAY_STATE_UP);
				break;
			}
			case SIGNAL_DRIVECOLOUR_REDCLOSE:
			{
				(void)SetRelayDriveState(ddRelayId, RELAY_STATE_UP);
				(void)SetRelayDriveState(lxRelayId, RELAY_STATE_DOWN);
				(void)SetRelayDriveState(zxRelayId, RELAY_STATE_UP);
				(void)SetRelayDriveState(greenRelayId, RELAY_STATE_DOWN);
				(void)SetRelayDriveState(yellowRelayId, RELAY_STATE_DOWN);
				break;
			}
			case SIGNAL_DRIVECOLOUR_RED:
			{
				(void)SetRelayDriveState(ddRelayId, RELAY_STATE_DOWN);
				(void)SetRelayDriveState(lxRelayId, RELAY_STATE_DOWN);
				(void)SetRelayDriveState(zxRelayId, RELAY_STATE_UP);
				(void)SetRelayDriveState(greenRelayId, RELAY_STATE_DOWN);
				(void)SetRelayDriveState(yellowRelayId, RELAY_STATE_DOWN);
				break;
			}
			default:
				/*不可达分支*/
				break;
			}
			
		}
		else
		{
		    /*无操作*/
		}
		break;
	}
	case SIGNAL_TYPE_4_NOGREEN_NOYINDAO_ZX:/*0x2B	四显示（封绿灯、可单独点亮黄灯）红、蓝、黄*/
	{
		if (FUNC_SWITCH_ON == bCiSwitchShowGreenYellow)/*如果显示绿黄灯开关【打开】*/
		{
			switch (curDrvColor)
			{
			case SIGNAL_DRIVECOLOUR_YELLOWCLOSE:
			{
				(void)SetRelayDriveState(ddRelayId, RELAY_STATE_UP);
				(void)SetRelayDriveState(lxRelayId, RELAY_STATE_UP);
				break;
			}
			case SIGNAL_DRIVECOLOUR_YELLOW:
			{
				(void)SetRelayDriveState(ddRelayId, RELAY_STATE_DOWN);
				(void)SetRelayDriveState(lxRelayId, RELAY_STATE_UP);
				break;
			}
			case SIGNAL_DRIVECOLOUR_REDCLOSE:
			{
				(void)SetRelayDriveState(ddRelayId, RELAY_STATE_UP);
				(void)SetRelayDriveState(lxRelayId, RELAY_STATE_DOWN);
				break;
			}
			case SIGNAL_DRIVECOLOUR_RED:
			{
				(void)SetRelayDriveState(ddRelayId, RELAY_STATE_DOWN);
				(void)SetRelayDriveState(lxRelayId, RELAY_STATE_DOWN);
				break;
			}

			default:
				/*不可达分支*/
				break;
			}
		}
		}
		break;
	case SIGNAL_TYPE_5_NOGREEN_YINDAO_CD:/*0x2C	高柱五显示（封绿灯、带引导、可点亮双黄灯）红、黄、绿、白、双黄*/
	{
		if (FUNC_SWITCH_ON == bCiSwitchShowGreenYellow)/*如果显示绿黄灯开关【打开】*/
		{
			switch (curDrvColor)
			{
			case SIGNAL_DRIVECOLOUR_DOUBLE_YELLOW:
			{
				(void)SetRelayDriveState(lxRelayId, RELAY_STATE_UP);
				(void)SetRelayDriveState(yxRelayId, RELAY_STATE_DOWN);
				break;
			}
			case SIGNAL_DRIVECOLOUR_RED:
			{
				(void)SetRelayDriveState(lxRelayId, RELAY_STATE_DOWN);
				(void)SetRelayDriveState(yxRelayId, RELAY_STATE_DOWN);
				break;
			}
			case SIGNAL_DRIVECOLOUR_RED_WHITE:
			{
				(void)SetRelayDriveState(lxRelayId, RELAY_STATE_DOWN);
				(void)SetRelayDriveState(yxRelayId, RELAY_STATE_UP);
				break;
			}

			default:
				/*不可达分支*/
				break;
			}
		}
		}
		break;
	case SIGNAL_TYPE_5_NOY_NOYINDAO_CD:/*0x2D	矮柱五显示（封黄灯、不带引导）红、绿、双绿、白*/
	{
		if (FUNC_SWITCH_ON == bCiSwitchShowGreenYellow)/*如果显示绿黄灯开关【打开】*/
		{
			switch (curDrvColor)
			{
			case SIGNAL_DRIVECOLOUR_GREEN:
			{
				(void)SetRelayDriveState(lxRelayId, RELAY_STATE_UP);
				(void)SetRelayDriveState(zxRelayId, RELAY_STATE_UP);
				(void)SetRelayDriveState(dxRelayId, RELAY_STATE_DOWN);
				break;
			}
			case SIGNAL_DRIVECOLOUR_DOUBLE_GREEN:
			{
				(void)SetRelayDriveState(lxRelayId, RELAY_STATE_UP);
				(void)SetRelayDriveState(zxRelayId, RELAY_STATE_DOWN);
				(void)SetRelayDriveState(dxRelayId, RELAY_STATE_DOWN);
				break;
			}
			case SIGNAL_DRIVECOLOUR_WHITE:
			{
				(void)SetRelayDriveState(lxRelayId, RELAY_STATE_DOWN);
				(void)SetRelayDriveState(zxRelayId, RELAY_STATE_DOWN);
				(void)SetRelayDriveState(dxRelayId, RELAY_STATE_UP);
				break;
			}
			case SIGNAL_DRIVECOLOUR_RED:
			{
				(void)SetRelayDriveState(lxRelayId, RELAY_STATE_DOWN);
				(void)SetRelayDriveState(zxRelayId, RELAY_STATE_DOWN);
				(void)SetRelayDriveState(dxRelayId, RELAY_STATE_DOWN);
				break;
			}

			default:
				/*不可达分支*/
				break;
			}
		}
		}
		break;
	case SIGNAL_TYPE_4_ALL_NOYINDAO_CD:  /* 0x2E	矮柱四显示（不带引导）*/
	{
		if (FUNC_SWITCH_ON == bCiSwitchShowGreenYellow)/*如果显示绿黄灯开关【打开】*/
		{
			switch (curDrvColor)
			{
				case SIGNAL_DRIVECOLOUR_GREEN:
				{
					(void)SetRelayDriveState(lxRelayId, RELAY_STATE_UP);
					(void)SetRelayDriveState(greenRelayId, RELAY_STATE_UP);
					(void)SetRelayDriveState(dxRelayId, RELAY_STATE_DOWN);
					break;
				}
				case SIGNAL_DRIVECOLOUR_YELLOW:
				{
					(void)SetRelayDriveState(lxRelayId, RELAY_STATE_UP);
					(void)SetRelayDriveState(greenRelayId, RELAY_STATE_DOWN);
					(void)SetRelayDriveState(dxRelayId, RELAY_STATE_DOWN);
					break;
				}
				case SIGNAL_DRIVECOLOUR_WHITE:
				{
					(void)SetRelayDriveState(lxRelayId, RELAY_STATE_DOWN);
					(void)SetRelayDriveState(greenRelayId, RELAY_STATE_DOWN);
					(void)SetRelayDriveState(dxRelayId, RELAY_STATE_UP);
					break;
				}
				case SIGNAL_DRIVECOLOUR_RED:
				{
					(void)SetRelayDriveState(lxRelayId, RELAY_STATE_DOWN);
					(void)SetRelayDriveState(greenRelayId, RELAY_STATE_DOWN);
					(void)SetRelayDriveState(dxRelayId, RELAY_STATE_DOWN);
					break;
				}

				default:
					/*不可达分支*/
					break;
			}
		}
	}
		break;
	case SIGNAL_TYPE_5_NOY_NOYINDAO_WB: /* 0x2f	矮柱五灯位信号机封黄灯（不带引导）白、蓝*/
	{
		if (FUNC_SWITCH_ON == bCiSwitchShowGreenYellow)/*如果显示绿黄灯开关【打开】*/
		{
			switch (curDrvColor)
			{
			case SIGNAL_DRIVECOLOUR_DOUBLE_GREEN:
			{
				(void)SetRelayDriveState(lxRelayId, RELAY_STATE_UP);
				(void)SetRelayDriveState(dxRelayId, RELAY_STATE_DOWN);
				break;
			}
			case SIGNAL_DRIVECOLOUR_WHITE:
			{
				(void)SetRelayDriveState(lxRelayId, RELAY_STATE_DOWN);
				(void)SetRelayDriveState(dxRelayId, RELAY_STATE_UP);
				break;
			}
			case SIGNAL_DRIVECOLOUR_RED:
			{
				(void)SetRelayDriveState(lxRelayId, RELAY_STATE_DOWN);
				(void)SetRelayDriveState(dxRelayId, RELAY_STATE_DOWN);
				break;
			}

			default:
				/*不可达分支*/
				break;
			}
		}
		}
		break;
	case SIGNAL_TYPE_3_RGG_CD:/*0x30	 矮柱3灯位：红、双绿*/
	{
		if (FUNC_SWITCH_ON == bCiSwitchShowGreenYellow)/*如果显示绿黄灯开关【打开】*/
		{
			switch (curDrvColor)
			{
			case SIGNAL_DRIVECOLOUR_DOUBLE_GREEN:
			{
				(void)SetRelayDriveState(lxRelayId, RELAY_STATE_UP);
				break;
			}
			case SIGNAL_DRIVECOLOUR_RED:
			{
				(void)SetRelayDriveState(lxRelayId, RELAY_STATE_DOWN);
				break;
			}

			default:
				/*不可达分支*/
				break;
			}
		}
		}
		break;
	case SIGNAL_TYPE_3_RGG_NOGREEN_CD:  /* 0x31	矮柱3灯位：红、双绿、封绿灯*/
	{
		switch (curDrvColor)
		{
		case SIGNAL_DRIVECOLOUR_GREEN:
		{
			(void)SetRelayDriveState(lxRelayId, RELAY_STATE_UP);
			break;
		}
		case SIGNAL_DRIVECOLOUR_RED:
		{
			(void)SetRelayDriveState(lxRelayId, RELAY_STATE_DOWN);
			break;
		}

		default:
			/*不可达分支*/
			break;
		}
	}
		break;
	case SIGNAL_TYPE_3_NOGREENWHITE_CD:	/* 0x32 矮柱3灯位：绿、红、白，封绿、白灯*/
	{

		/*没有驱动*/
	}
		break;
	case SIGNAL_TYPE_4_ALL_NOYINDAO_NOYELLOWONLY_ZX:	/*0x33出站兼道岔防护信号机(黄、绿、红、蓝四灯位，不封灯位，不可单独点亮黄灯)*/
	{
		if (FUNC_SWITCH_ON == bCiSwitchShowGreenYellow)/*如果显示绿黄灯开关【打开】*/
		{
			switch (curDrvColor)
			{
			case SIGNAL_DRIVECOLOUR_GREENCLOSE:
			{
				(void)SetRelayDriveState(ddRelayId, RELAY_STATE_UP);
				(void)SetRelayDriveState(lxRelayId, RELAY_STATE_UP);
				(void)SetRelayDriveState(greenRelayId, RELAY_STATE_UP);
				break;
			}
			case SIGNAL_DRIVECOLOUR_GREEN:
			{
				(void)SetRelayDriveState(ddRelayId, RELAY_STATE_DOWN);
				(void)SetRelayDriveState(lxRelayId, RELAY_STATE_UP);
				(void)SetRelayDriveState(greenRelayId, RELAY_STATE_UP);
				break;
			}
			case SIGNAL_DRIVECOLOUR_GREENYELLOWCLOSE:
			{
				(void)SetRelayDriveState(ddRelayId, RELAY_STATE_UP);
				(void)SetRelayDriveState(lxRelayId, RELAY_STATE_UP);
				(void)SetRelayDriveState(greenRelayId, RELAY_STATE_DOWN);
				break;
			}
			case SIGNAL_DRIVECOLOUR_GREENYELLOW:
			{
				(void)SetRelayDriveState(ddRelayId, RELAY_STATE_DOWN);
				(void)SetRelayDriveState(lxRelayId, RELAY_STATE_UP);
				(void)SetRelayDriveState(greenRelayId, RELAY_STATE_DOWN);
				break;
			}
			case SIGNAL_DRIVECOLOUR_REDCLOSE:
			{
				(void)SetRelayDriveState(ddRelayId, RELAY_STATE_UP);
				(void)SetRelayDriveState(lxRelayId, RELAY_STATE_DOWN);
				(void)SetRelayDriveState(greenRelayId, RELAY_STATE_DOWN);
				break;
			}
			case SIGNAL_DRIVECOLOUR_RED:
			{
				(void)SetRelayDriveState(ddRelayId, RELAY_STATE_DOWN);
				(void)SetRelayDriveState(lxRelayId, RELAY_STATE_DOWN);
				(void)SetRelayDriveState(greenRelayId, RELAY_STATE_DOWN);
				break;
			}
			default:
			{
				/*不可达分支*/
				break;
			}
			}
		}
		break;
	}
	case SIGNAL_TYPE_4_NOGREENBLUE_NOYINDAO_ZX:	/*0x34联络线信号机（黄、绿、红、蓝四灯位，封绿、蓝灯，可单独点亮黄灯）*/
	{
		if (FUNC_SWITCH_ON == bCiSwitchShowGreenYellow)/*如果显示绿黄灯开关【打开】*/
		{
			switch (curDrvColor)
			{
			case SIGNAL_DRIVECOLOUR_YELLOW:
			{
				(void)SetRelayDriveState(lxRelayId, RELAY_STATE_UP);
				break;
			}
			case SIGNAL_DRIVECOLOUR_RED:
			{
				(void)SetRelayDriveState(lxRelayId, RELAY_STATE_DOWN);
				break;
			}
			default:
			{
				/*不可达分支*/
				break;
			}
			}
		}
		break;
	}
	case SIGNAL_TYPE_3_ALL_NOYINDAO_CD:	/*0x35矮柱三显信号机(不封灯、不带引导)（红白绿）*/
	{
		switch (curDrvColor)
		{
		case SIGNAL_DRIVECOLOUR_RED:
		{
			(void)SetRelayDriveState(lxRelayId, RELAY_STATE_DOWN);
			(void)SetRelayDriveState(dxRelayId, RELAY_STATE_DOWN);
			break;
		}
		case SIGNAL_DRIVECOLOUR_GREEN:
		{
			(void)SetRelayDriveState(lxRelayId, RELAY_STATE_UP);
			(void)SetRelayDriveState(dxRelayId, RELAY_STATE_DOWN);
			break;
		}
		case SIGNAL_DRIVECOLOUR_WHITE:
		{
			(void)SetRelayDriveState(lxRelayId, RELAY_STATE_DOWN);
			(void)SetRelayDriveState(dxRelayId, RELAY_STATE_UP);
			break;
		}
		default:
		{
			/*不可达分支*/
			break;
		}
		}
		break;
	}
	case SIGNAL_TYPE_1_ALL_END: /*0x36 单显示尽头阻挡信号机*/
	{/*没有驱动*/
		break;
	}

	case SIGNAL_TYPE_THREE_ALL_YINDAO:/*三显示（红、 绿、 黄、红黄）*/
		switch (curDrvColor)
		{
		case SIGNAL_DRIVECOLOUR_RED:/*红亮*/
			if ((SIGNAL_DRIVECOLOUR_GREEN == OldDriveColor) || (SIGNAL_DRIVECOLOUR_GREENCLOSE == OldDriveColor))
			{
				if (SIG_RELAY_DRV_DELAY_TIME > (curCycleNum - drvNewSigStartCycNum))
				{
					(void)SetRelayDriveState(GetSignalDdRelayId(signalId), RELAY_STATE_DOWN);/*点灯继电器落下*/
					(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_DOWN);/*列车信号继电器落下*/
					(void)SetRelayDriveState(GetSignalZxRelayId(signalId), RELAY_STATE_UP);/*主信号继电器吸起*/
					(void)SetRelayDriveState(GetSignalYxRelayId(signalId), RELAY_STATE_DOWN);/*引导信号继电器落下*/
				}
				else
				{
					(void)SetRelayDriveState(GetSignalDdRelayId(signalId), RELAY_STATE_DOWN);/*点灯继电器落下*/
					(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_DOWN);/*列车信号继电器落下*/
					(void)SetRelayDriveState(GetSignalZxRelayId(signalId), RELAY_STATE_DOWN);/*主信号继电器落下*/
					(void)SetRelayDriveState(GetSignalYxRelayId(signalId), RELAY_STATE_DOWN);/*引导信号继电器落下*/
				}
			}
			else
			{
				(void)SetRelayDriveState(GetSignalDdRelayId(signalId), RELAY_STATE_DOWN);/*点灯继电器落下*/
				(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_DOWN);/*列车信号继电器落下*/
				(void)SetRelayDriveState(GetSignalZxRelayId(signalId), RELAY_STATE_DOWN);/*主信号继电器落下*/
				(void)SetRelayDriveState(GetSignalYxRelayId(signalId), RELAY_STATE_DOWN);/*引导信号继电器落下*/
			}
			break;
		case SIGNAL_DRIVECOLOUR_REDCLOSE:/*红灭*/
			if ((SIGNAL_DRIVECOLOUR_GREEN == OldDriveColor) || (SIGNAL_DRIVECOLOUR_GREENCLOSE == OldDriveColor))
			{
				if (SIG_RELAY_DRV_DELAY_TIME > (curCycleNum - drvNewSigStartCycNum))
				{
					(void)SetRelayDriveState(GetSignalDdRelayId(signalId), RELAY_STATE_UP);/*点灯继电器吸起*/
					(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_DOWN);/*列车信号继电器落下*/
					(void)SetRelayDriveState(GetSignalZxRelayId(signalId), RELAY_STATE_UP);/*主信号继电器吸起*/
					(void)SetRelayDriveState(GetSignalYxRelayId(signalId), RELAY_STATE_DOWN);/*引导信号继电器落下*/
				}
				else
				{
					(void)SetRelayDriveState(GetSignalDdRelayId(signalId), RELAY_STATE_UP);/*点灯继电器吸起*/
					(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_DOWN);/*列车信号继电器落下*/
					(void)SetRelayDriveState(GetSignalZxRelayId(signalId), RELAY_STATE_DOWN);/*主信号继电器落下*/
					(void)SetRelayDriveState(GetSignalYxRelayId(signalId), RELAY_STATE_DOWN);/*引导信号继电器落下*/
				}
			}
			else
			{
				(void)SetRelayDriveState(GetSignalDdRelayId(signalId), RELAY_STATE_UP);/*点灯继电器吸起*/
				(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_DOWN);/*列车信号继电器落下*/
				(void)SetRelayDriveState(GetSignalZxRelayId(signalId), RELAY_STATE_DOWN);/*主信号继电器落下*/
				(void)SetRelayDriveState(GetSignalYxRelayId(signalId), RELAY_STATE_DOWN);/*引导信号继电器落下*/
			}
			break;
		case SIGNAL_DRIVECOLOUR_GREEN:/*绿亮*/
			if ((SIGNAL_DRIVECOLOUR_RED == OldDriveColor) || (SIGNAL_DRIVECOLOUR_REDCLOSE == OldDriveColor))
			{
				if (SIG_RELAY_DRV_DELAY_TIME > (curCycleNum - drvNewSigStartCycNum))
				{
					(void)SetRelayDriveState(GetSignalDdRelayId(signalId), RELAY_STATE_DOWN);/*点灯继电器落下*/
					(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_DOWN);/*列车信号继电器落下*/
					(void)SetRelayDriveState(GetSignalZxRelayId(signalId), RELAY_STATE_UP);/*主信号继电器吸起*/
					(void)SetRelayDriveState(GetSignalYxRelayId(signalId), RELAY_STATE_DOWN);/*引导信号继电器落下*/
				}
				else
				{
					(void)SetRelayDriveState(GetSignalDdRelayId(signalId), RELAY_STATE_DOWN);/*点灯继电器落下*/
					(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_UP);/*列车信号继电器吸起*/
					(void)SetRelayDriveState(GetSignalZxRelayId(signalId), RELAY_STATE_UP);/*主信号继电器吸起*/
					(void)SetRelayDriveState(GetSignalYxRelayId(signalId), RELAY_STATE_DOWN);/*引导信号继电器落下*/
				}
			}
			else
			{
				(void)SetRelayDriveState(GetSignalDdRelayId(signalId), RELAY_STATE_DOWN);/*点灯继电器落下*/
				(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_UP);/*列车信号继电器吸起*/
				(void)SetRelayDriveState(GetSignalZxRelayId(signalId), RELAY_STATE_UP);/*主信号继电器吸起*/
				(void)SetRelayDriveState(GetSignalYxRelayId(signalId), RELAY_STATE_DOWN);/*引导信号继电器落下*/
			}
			break;
		case SIGNAL_DRIVECOLOUR_GREENCLOSE:/*绿灭*/
			if ((SIGNAL_DRIVECOLOUR_RED == OldDriveColor) || (SIGNAL_DRIVECOLOUR_REDCLOSE == OldDriveColor))
			{
				if (SIG_RELAY_DRV_DELAY_TIME > (curCycleNum - drvNewSigStartCycNum))
				{
					(void)SetRelayDriveState(GetSignalDdRelayId(signalId), RELAY_STATE_UP);/*点灯继电器吸起*/
					(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_DOWN);/*列车信号继电器落下*/
					(void)SetRelayDriveState(GetSignalZxRelayId(signalId), RELAY_STATE_UP);/*主信号继电器吸起*/
					(void)SetRelayDriveState(GetSignalYxRelayId(signalId), RELAY_STATE_DOWN);/*引导信号继电器落下*/
				}
				else
				{
					(void)SetRelayDriveState(GetSignalDdRelayId(signalId), RELAY_STATE_UP);/*点灯继电器吸起*/
					(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_UP);/*列车信号继电器吸起*/
					(void)SetRelayDriveState(GetSignalZxRelayId(signalId), RELAY_STATE_UP);/*主信号继电器吸起*/
					(void)SetRelayDriveState(GetSignalYxRelayId(signalId), RELAY_STATE_DOWN);/*引导信号继电器落下*/
				}
			}
			else
			{
				(void)SetRelayDriveState(GetSignalDdRelayId(signalId), RELAY_STATE_UP);/*点灯继电器吸起*/
				(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_UP);/*列车信号继电器吸起*/
				(void)SetRelayDriveState(GetSignalZxRelayId(signalId), RELAY_STATE_UP);/*主信号继电器吸起*/
				(void)SetRelayDriveState(GetSignalYxRelayId(signalId), RELAY_STATE_DOWN);/*引导信号继电器落下*/
			}
			break;
		case SIGNAL_DRIVECOLOUR_YELLOW:/*黄亮*/
			(void)SetRelayDriveState(GetSignalDdRelayId(signalId), RELAY_STATE_DOWN);/*点灯继电器落下*/
			(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_UP);/*列车信号继电器吸起*/
			(void)SetRelayDriveState(GetSignalZxRelayId(signalId), RELAY_STATE_DOWN);/*主信号继电器落下*/
			(void)SetRelayDriveState(GetSignalYxRelayId(signalId), RELAY_STATE_DOWN);/*引导信号继电器落下*/
			break;
		case SIGNAL_DRIVECOLOUR_YELLOWCLOSE:/*黄灭*/
			(void)SetRelayDriveState(GetSignalDdRelayId(signalId), RELAY_STATE_UP);/*点灯继电器吸起*/
			(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_UP);/*列车信号继电器吸起*/
			(void)SetRelayDriveState(GetSignalZxRelayId(signalId), RELAY_STATE_DOWN);/*主信号继电器落下*/
			(void)SetRelayDriveState(GetSignalYxRelayId(signalId), RELAY_STATE_DOWN);/*引导信号继电器落下*/
			break;
		case SIGNAL_DRIVECOLOUR_REDYELLOW:/*红黄灯*/
			(void)SetRelayDriveState(GetSignalDdRelayId(signalId), RELAY_STATE_DOWN);/*点灯继电器落下*/
			(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_DOWN);/*列车信号继电器落下*/
			(void)SetRelayDriveState(GetSignalZxRelayId(signalId), RELAY_STATE_DOWN);/*主信号继电器落下*/
			(void)SetRelayDriveState(GetSignalYxRelayId(signalId), RELAY_STATE_UP);/*引导信号继电器吸起*/
			break;
		default:/*红亮*/
			(void)SetRelayDriveState(GetSignalDdRelayId(signalId), RELAY_STATE_DOWN);/*点灯继电器落下*/
			(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_DOWN);/*列车信号继电器落下*/
			(void)SetRelayDriveState(GetSignalZxRelayId(signalId), RELAY_STATE_DOWN);/*主信号继电器落下*/
			(void)SetRelayDriveState(GetSignalYxRelayId(signalId), RELAY_STATE_DOWN);/*引导信号继电器落下*/
			returnValue = CI_ERROR;
			break;
		}
		break;

	case SIGNAL_TYPE_THREE_ALL_NOYINDAO:/*三显示无引导（红、 绿、 黄）*/
		switch (curDrvColor)
		{
		case SIGNAL_DRIVECOLOUR_RED:/*红亮*/
			if ((SIGNAL_DRIVECOLOUR_GREEN == OldDriveColor) || (SIGNAL_DRIVECOLOUR_GREENCLOSE == OldDriveColor))
			{
				if (SIG_RELAY_DRV_DELAY_TIME > (curCycleNum - drvNewSigStartCycNum))
				{
					(void)SetRelayDriveState(GetSignalDdRelayId(signalId), RELAY_STATE_DOWN);/*点灯继电器落下*/
					(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_DOWN);/*列车信号继电器落下*/
					(void)SetRelayDriveState(GetSignalZxRelayId(signalId), RELAY_STATE_UP);/*主信号继电器保持吸起*/
				}
				else
				{
					(void)SetRelayDriveState(GetSignalDdRelayId(signalId), RELAY_STATE_DOWN);/*点灯继电器落下*/
					(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_DOWN);/*列车信号继电器落下*/
					(void)SetRelayDriveState(GetSignalZxRelayId(signalId), RELAY_STATE_DOWN);/*主信号继电器落下*/
				}
			}
			else
			{
				(void)SetRelayDriveState(GetSignalDdRelayId(signalId), RELAY_STATE_DOWN);/*点灯继电器落下*/
				(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_DOWN);/*列车信号继电器落下*/
				(void)SetRelayDriveState(GetSignalZxRelayId(signalId), RELAY_STATE_DOWN);/*主信号继电器落下*/
			}
			break;
		case SIGNAL_DRIVECOLOUR_REDCLOSE:/*红灭*/
			if ((SIGNAL_DRIVECOLOUR_GREEN == OldDriveColor) || (SIGNAL_DRIVECOLOUR_GREENCLOSE == OldDriveColor))
			{
				if (SIG_RELAY_DRV_DELAY_TIME > (curCycleNum - drvNewSigStartCycNum))
				{
					(void)SetRelayDriveState(GetSignalDdRelayId(signalId), RELAY_STATE_UP);/*点灯继电器吸起*/
					(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_DOWN);/*列车信号继电器落下*/
					(void)SetRelayDriveState(GetSignalZxRelayId(signalId), RELAY_STATE_UP);/*主信号继电器保持吸起*/
				}
				else
				{
					(void)SetRelayDriveState(GetSignalDdRelayId(signalId), RELAY_STATE_UP);/*点灯继电器吸起*/
					(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_DOWN);/*列车信号继电器落下*/
					(void)SetRelayDriveState(GetSignalZxRelayId(signalId), RELAY_STATE_DOWN);/*主信号继电器落下*/
				}
			}
			else
			{
				(void)SetRelayDriveState(GetSignalDdRelayId(signalId), RELAY_STATE_UP);/*点灯继电器吸起*/
				(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_DOWN);/*列车信号继电器落下*/
				(void)SetRelayDriveState(GetSignalZxRelayId(signalId), RELAY_STATE_DOWN);/*主信号继电器落下*/
			}
			break;
		case SIGNAL_DRIVECOLOUR_GREEN:/*绿亮*/
			if ((SIGNAL_DRIVECOLOUR_RED == OldDriveColor) || (SIGNAL_DRIVECOLOUR_REDCLOSE == OldDriveColor))
			{
				if (SIG_RELAY_DRV_DELAY_TIME > (curCycleNum - drvNewSigStartCycNum))
				{
					(void)SetRelayDriveState(GetSignalDdRelayId(signalId), RELAY_STATE_DOWN);/*点灯继电器落下*/
					(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_DOWN);/*列车信号继电器落下*/
					(void)SetRelayDriveState(GetSignalZxRelayId(signalId), RELAY_STATE_UP);/*主信号继电器吸起*/
				}
				else
				{
					(void)SetRelayDriveState(GetSignalDdRelayId(signalId), RELAY_STATE_DOWN);/*点灯继电器落下*/
					(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_UP);/*列车信号继电器吸起*/
					(void)SetRelayDriveState(GetSignalZxRelayId(signalId), RELAY_STATE_UP);/*主信号继电器吸起*/
				}
			}
			else
			{
				(void)SetRelayDriveState(GetSignalDdRelayId(signalId), RELAY_STATE_DOWN);/*点灯继电器落下*/
				(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_UP);/*列车信号继电器吸起*/
				(void)SetRelayDriveState(GetSignalZxRelayId(signalId), RELAY_STATE_UP);/*主信号继电器吸起*/
			}
			break;
		case SIGNAL_DRIVECOLOUR_GREENCLOSE:/*绿灭*/
			if ((SIGNAL_DRIVECOLOUR_RED == OldDriveColor) || (SIGNAL_DRIVECOLOUR_REDCLOSE == OldDriveColor))
			{
				if (SIG_RELAY_DRV_DELAY_TIME > (curCycleNum - drvNewSigStartCycNum))
				{
					(void)SetRelayDriveState(GetSignalDdRelayId(signalId), RELAY_STATE_UP);/*点灯继电器吸起*/
					(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_DOWN);/*列车信号继电器落下*/
					(void)SetRelayDriveState(GetSignalZxRelayId(signalId), RELAY_STATE_UP);/*主信号继电器吸起*/
				}
				else
				{
					(void)SetRelayDriveState(GetSignalDdRelayId(signalId), RELAY_STATE_UP);/*点灯继电器吸起*/
					(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_UP);/*列车信号继电器吸起*/
					(void)SetRelayDriveState(GetSignalZxRelayId(signalId), RELAY_STATE_UP);/*主信号继电器吸起*/
				}
			}
			else
			{
				(void)SetRelayDriveState(GetSignalDdRelayId(signalId), RELAY_STATE_UP);/*点灯继电器吸起*/
				(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_UP);/*列车信号继电器吸起*/
				(void)SetRelayDriveState(GetSignalZxRelayId(signalId), RELAY_STATE_UP);/*主信号继电器吸起*/
			}
			break;
		case SIGNAL_DRIVECOLOUR_YELLOW:/*黄亮*/
			(void)SetRelayDriveState(GetSignalDdRelayId(signalId), RELAY_STATE_DOWN);/*点灯继电器落下*/
			(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_UP);/*列车信号继电器吸起*/
			(void)SetRelayDriveState(GetSignalZxRelayId(signalId), RELAY_STATE_DOWN);/*主信号继电器落下*/
			break;
		case SIGNAL_DRIVECOLOUR_YELLOWCLOSE:/*黄灭*/
			(void)SetRelayDriveState(GetSignalDdRelayId(signalId), RELAY_STATE_UP);/*点灯继电器吸起*/
			(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_UP);/*列车信号继电器吸起*/
			(void)SetRelayDriveState(GetSignalZxRelayId(signalId), RELAY_STATE_DOWN);/*主信号继电器落下*/
			break;
		default:/*红亮*/
			(void)SetRelayDriveState(GetSignalDdRelayId(signalId), RELAY_STATE_DOWN);/*点灯继电器落下*/
			(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_DOWN);/*列车信号继电器落下*/
			(void)SetRelayDriveState(GetSignalZxRelayId(signalId), RELAY_STATE_DOWN);/*主信号继电器吸起落下*/
			returnValue = CI_ERROR;
			break;
		}
		break;
	case SIGNAL_TYPE_THREE_NOGREEN_YINDAO:/*三显示封绿灯（红、黄、红黄）*/
		switch (curDrvColor)
		{
		case SIGNAL_DRIVECOLOUR_RED:/*红亮*/
			(void)SetRelayDriveState(GetSignalDdRelayId(signalId), RELAY_STATE_DOWN);/*点灯继电器落下*/
			(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_DOWN);/*列车信号继电器落下*/
			(void)SetRelayDriveState(GetSignalYxRelayId(signalId), RELAY_STATE_DOWN);/*引导信号继电器落下*/
			break;
		case SIGNAL_DRIVECOLOUR_REDCLOSE:/*红灭*/
			(void)SetRelayDriveState(GetSignalDdRelayId(signalId), RELAY_STATE_UP);/*点灯继电器吸起*/
			(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_DOWN);/*列车信号继电器落下*/
			(void)SetRelayDriveState(GetSignalYxRelayId(signalId), RELAY_STATE_DOWN);/*引导信号继电器落下*/
			break;
		case SIGNAL_DRIVECOLOUR_YELLOW:/*黄亮*/
			(void)SetRelayDriveState(GetSignalDdRelayId(signalId), RELAY_STATE_DOWN);/*点灯继电器落下*/
			(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_UP);/*列车信号继电器吸起*/
			(void)SetRelayDriveState(GetSignalYxRelayId(signalId), RELAY_STATE_DOWN);/*引导信号继电器落下*/
			break;
		case SIGNAL_DRIVECOLOUR_YELLOWCLOSE:/*黄灭*/
			(void)SetRelayDriveState(GetSignalDdRelayId(signalId), RELAY_STATE_UP);/*点灯继电器吸起*/
			(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_UP);/*列车信号继电器吸起*/
			(void)SetRelayDriveState(GetSignalYxRelayId(signalId), RELAY_STATE_DOWN);/*引导信号继电器落下*/
			break;
		case SIGNAL_DRIVECOLOUR_REDYELLOW:/*红黄*/
			(void)SetRelayDriveState(GetSignalDdRelayId(signalId), RELAY_STATE_DOWN);/*点灯继电器落下*/
			(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_DOWN);/*列车信号继电器落下*/
			(void)SetRelayDriveState(GetSignalYxRelayId(signalId), RELAY_STATE_UP);/*引导信号继电器吸起*/
			break;
		default:/*红亮*/
			(void)SetRelayDriveState(GetSignalDdRelayId(signalId), RELAY_STATE_DOWN);/*点灯继电器落下*/
			(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_DOWN);/*列车信号继电器落下*/
			(void)SetRelayDriveState(GetSignalYxRelayId(signalId), RELAY_STATE_DOWN);/*引导信号继电器落下*/
			returnValue = CI_ERROR;
			break;
		}
		break;
	case SIGNAL_TYPE_THREE_NOGREEN_NOYINDAO:/*三显示封绿灯无引导（红、黄）*/
		switch (curDrvColor)
		{
		case SIGNAL_DRIVECOLOUR_RED:/*红亮*/
			(void)SetRelayDriveState(GetSignalDdRelayId(signalId), RELAY_STATE_DOWN);/*点灯继电器落下*/
			(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_DOWN);/*列车信号继电器落下*/
			break;
		case SIGNAL_DRIVECOLOUR_REDCLOSE:/*红灭*/
			(void)SetRelayDriveState(GetSignalDdRelayId(signalId), RELAY_STATE_UP);/*点灯继电器吸起*/
			(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_DOWN);/*列车信号继电器落下*/
			break;
		case SIGNAL_DRIVECOLOUR_YELLOW:/*黄亮*/
			(void)SetRelayDriveState(GetSignalDdRelayId(signalId), RELAY_STATE_DOWN);/*点灯继电器落下*/
			(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_UP);/*列车信号继电器吸起*/
			break;
		case SIGNAL_DRIVECOLOUR_YELLOWCLOSE:/*黄灭*/
			(void)SetRelayDriveState(GetSignalDdRelayId(signalId), RELAY_STATE_UP);/*点灯继电器吸起*/
			(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_UP);/*列车信号继电器吸起*/
			break;
		default:/*红亮*/
			(void)SetRelayDriveState(GetSignalDdRelayId(signalId), RELAY_STATE_DOWN);/*点灯继电器落下*/
			(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_DOWN);/*列车信号继电器落下*/
			returnValue = CI_ERROR;
			break;
		}
		break;
	case SIGNAL_TYPE_THREE_NOYELLOW_YINDAO:/*进段信号机(三显示，无黄灯，可引导，无灭灯)*/
		switch (curDrvColor)
		{
		case SIGNAL_DRIVECOLOUR_RED:/*红亮*/
			(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_DOWN);/*列车信号继电器落下*/
			(void)SetRelayDriveState(GetSignalYxRelayId(signalId), RELAY_STATE_DOWN);/*引导信号继电器落下*/
			break;
		case SIGNAL_DRIVECOLOUR_GREEN:/*绿亮*/
			(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_UP);/*列车信号继电器吸起*/
			(void)SetRelayDriveState(GetSignalYxRelayId(signalId), RELAY_STATE_DOWN);/*引导信号继电器落下*/
			break;
		case SIGNAL_DRIVECOLOUR_REDYELLOW:/*红黄*/
			(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_DOWN);/*列车信号继电器落下*/
			(void)SetRelayDriveState(GetSignalYxRelayId(signalId), RELAY_STATE_UP);/*引导信号继电器吸起*/
			break;
		default:/*红亮*/
			(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_DOWN);/*列车信号继电器落下*/
			(void)SetRelayDriveState(GetSignalYxRelayId(signalId), RELAY_STATE_DOWN);/*引导信号继电器落下*/
			returnValue = CI_ERROR;
			break;
		}
		break;
	case SIGNAL_TYPE_THREE_ALL_YINDAO_NOY:/*道岔防护信号机(三显示，不封灯，带引导，不可单独点亮黄灯，可灭灯)*/
		switch (curDrvColor)
		{
		case SIGNAL_DRIVECOLOUR_RED:/*红亮*/
			(void)SetRelayDriveState(GetSignalDdRelayId(signalId), RELAY_STATE_DOWN);/*点灯继电器落下*/
			(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_DOWN);/*列车信号继电器落下*/
			(void)SetRelayDriveState(GetSignalYxRelayId(signalId), RELAY_STATE_DOWN);/*引导信号继电器落下*/
			break;
		case SIGNAL_DRIVECOLOUR_REDCLOSE:/*红灭*/
			(void)SetRelayDriveState(GetSignalDdRelayId(signalId), RELAY_STATE_UP);/*点灯继电器*/
			(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_DOWN);/*列车信号继电器落下*/
			(void)SetRelayDriveState(GetSignalYxRelayId(signalId), RELAY_STATE_DOWN);/*引导信号继电器落下*/
			break;
		case SIGNAL_DRIVECOLOUR_GREEN:/*绿亮*/
			(void)SetRelayDriveState(GetSignalDdRelayId(signalId), RELAY_STATE_DOWN);/*点灯继电器落下*/
			(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_UP);/*列车信号继电器吸起*/
			(void)SetRelayDriveState(GetSignalYxRelayId(signalId), RELAY_STATE_DOWN);/*引导信号继电器落下*/
			break;
		case SIGNAL_DRIVECOLOUR_GREENCLOSE:/*绿灭*/
			(void)SetRelayDriveState(GetSignalDdRelayId(signalId), RELAY_STATE_UP);/*点灯继电器*/
			(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_UP);/*列车信号继电器吸起*/
			(void)SetRelayDriveState(GetSignalYxRelayId(signalId), RELAY_STATE_DOWN);/*引导信号继电器落下*/
			break;
		case SIGNAL_DRIVECOLOUR_REDYELLOW:/*红黄*/
			(void)SetRelayDriveState(GetSignalDdRelayId(signalId), RELAY_STATE_DOWN);/*点灯继电器落下*/
			(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_DOWN);/*列车信号继电器落下*/
			(void)SetRelayDriveState(GetSignalYxRelayId(signalId), RELAY_STATE_UP);/*引导信号继电器吸起*/
			break;
		default:/*红亮*/
			(void)SetRelayDriveState(GetSignalDdRelayId(signalId), RELAY_STATE_DOWN);/*点灯继电器落下*/
			(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_DOWN);/*列车信号继电器落下*/
			(void)SetRelayDriveState(GetSignalYxRelayId(signalId), RELAY_STATE_DOWN);/*引导信号继电器落下*/
			returnValue = CI_ERROR;
			break;
		}
		break;
	case SIGNAL_TYPE_THREE_NOYELLOW_NOYINDAO:/*三显示封黄灯无引导（红、绿）*/
	case SIGNAL_TYPE_TWO_ALL_NOYINDAO:/*两显示（红、绿）*/
		switch (curDrvColor)
		{
		case SIGNAL_DRIVECOLOUR_RED:/*红亮*/
			(void)SetRelayDriveState(GetSignalDdRelayId(signalId), RELAY_STATE_DOWN);/*点灯继电器落下*/
			(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_DOWN);/*列车信号继电器落下*/
			break;
		case SIGNAL_DRIVECOLOUR_REDCLOSE:/*红灭*/
			(void)SetRelayDriveState(GetSignalDdRelayId(signalId), RELAY_STATE_UP);/*点灯继电器吸起*/
			(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_DOWN);/*列车信号继电器落下*/
			break;
		case SIGNAL_DRIVECOLOUR_GREEN:/*绿亮*/
			(void)SetRelayDriveState(GetSignalDdRelayId(signalId), RELAY_STATE_DOWN);/*点灯继电器落下*/
			(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_UP);/*列车信号继电器吸起*/
			break;
		case SIGNAL_DRIVECOLOUR_GREENCLOSE:/*绿灭*/
			(void)SetRelayDriveState(GetSignalDdRelayId(signalId), RELAY_STATE_UP);/*点灯继电器吸起*/
			(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_UP);/*列车信号继电器吸起*/
			break;
		default:/*红亮*/
			(void)SetRelayDriveState(GetSignalDdRelayId(signalId), RELAY_STATE_DOWN);/*点灯继电器落下*/
			(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_DOWN);/*列车信号继电器落下*/
			returnValue = CI_ERROR;
			break;
		}
		break;
	case SIGNAL_TYPE_TWO_NOGREEN_NOYINDAO:/*两显示封绿灯（仅红亮）*/
		if (SIGNAL_DRIVECOLOUR_RED == curDrvColor)
		{ /*红亮*/

			(void)SetRelayDriveState(GetSignalFirstDsRelayId(signalId), RELAY_STATE_UP);/*1灯丝继电器吸起*/
		}
		else
		{/*红亮*/

			(void)SetRelayDriveState(GetSignalFirstDsRelayId(signalId), RELAY_STATE_UP);/*1灯丝继电器吸起*/
			returnValue = CI_ERROR;
		}
		break;
	case SIGNAL_TYPE_DIAOCHE:/*调车信号机*/
		switch (curDrvColor)
		{
		case SIGNAL_DRIVECOLOUR_RED:/*红亮*/
			(void)SetRelayDriveState(GetSignalDxRelayId(signalId), RELAY_STATE_DOWN);/*调车信号继电器落下*/
			break;
		case SIGNAL_DRIVECOLOUR_WHITE:/*白亮*/
			(void)SetRelayDriveState(GetSignalDxRelayId(signalId), RELAY_STATE_UP);/*调车信号继电器吸起*/
			break;
		default:/*红亮*/
			(void)SetRelayDriveState(GetSignalDxRelayId(signalId), RELAY_STATE_DOWN);/*调车信号继电器落下*/
			returnValue = CI_ERROR;
			break;
		}
		break;
	case SIGNAL_TYPE_JINKUCHUKU:/*进库出库信号机*/
		switch (curDrvColor)
		{
		case SIGNAL_DRIVECOLOUR_RED:/*红亮*/
			(void)SetRelayDriveState(GetSignalDxRelayId(signalId), RELAY_STATE_DOWN);/*调车信号继电器落下*/
			(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_DOWN);/*列车信号继电器落下*/
			break;
		case SIGNAL_DRIVECOLOUR_WHITE:/*白亮*/
			(void)SetRelayDriveState(GetSignalDxRelayId(signalId), RELAY_STATE_UP);/*调车信号继电器吸起*/
			(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_DOWN);/*列车信号继电器落下*/
			break;
		case SIGNAL_DRIVECOLOUR_YELLOW:/*黄亮*/
			(void)SetRelayDriveState(GetSignalDxRelayId(signalId), RELAY_STATE_DOWN);/*调车信号继电器落下*/
			(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_UP);/*列车信号继电器吸起*/
			break;
		default:/*红亮*/
			(void)SetRelayDriveState(GetSignalDxRelayId(signalId), RELAY_STATE_DOWN);/*调车信号继电器落下*/
			(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_DOWN);/*列车信号继电器落下*/
			returnValue = CI_ERROR;
			break;
		}
		break;

	case SIGNAL_TYPE_TWO_JINKU_RGY:/*进段/进库信号机(三显示),仅亮红灯、亮绿灯和亮红黄灯*/
		/*驱动不处理*/
		break;
	case SIGNAL_TYPE_3_NOGREEN_YINDAO_NOL:/*道岔防护信号机(三显示，封绿灯，带引导，不能灭灯)*/
		switch (curDrvColor)
		{
		case SIGNAL_DRIVECOLOUR_RED:/*红亮*/
			(void)SetRelayDriveState(GetSignalYxRelayId(signalId), RELAY_STATE_DOWN);/*引导信号继电器落下*/
			(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_DOWN);/*列车信号继电器落下*/
			break;
		case SIGNAL_DRIVECOLOUR_YELLOW:/*黄亮*/
			(void)SetRelayDriveState(GetSignalYxRelayId(signalId), RELAY_STATE_DOWN);/*引导信号继电器落下*/
			(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_UP);/*列车信号继电器吸起*/
			break;
		case SIGNAL_DRIVECOLOUR_REDYELLOW:/*红黄*/
			(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_DOWN);/*列车信号继电器落下*/
			(void)SetRelayDriveState(GetSignalYxRelayId(signalId), RELAY_STATE_UP);/*引导信号继电器吸起*/
			break;
		default:/*红亮*/
			(void)SetRelayDriveState(GetSignalYxRelayId(signalId), RELAY_STATE_DOWN);/*引导信号继电器落下*/
			(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_DOWN);/*列车信号继电器落下*/
			returnValue = CI_ERROR;
			break;
		}
		break;
	case SIGNAL_TYPE_THREE_DIAOCHE_YINDAO:/*进段带引导调车信号机(三显示，可引导红白灯，无灭灯)*/
		switch (curDrvColor)
		{
		case SIGNAL_DRIVECOLOUR_RED:/*红亮*/
			(void)SetRelayDriveState(GetSignalDxRelayId(signalId), RELAY_STATE_DOWN);/*调车信号继电器落下*/
			(void)SetRelayDriveState(GetSignalYxRelayId(signalId), RELAY_STATE_DOWN);/*引导信号继电器落下*/
			break;
		case SIGNAL_DRIVECOLOUR_WHITE:/*白亮*/
			(void)SetRelayDriveState(GetSignalDxRelayId(signalId), RELAY_STATE_UP);/*调车信号继电器吸起*/
			(void)SetRelayDriveState(GetSignalYxRelayId(signalId), RELAY_STATE_DOWN);/*引导信号继电器落下*/
			break;
		case SIGNAL_DRIVECOLOUR_RED_WHITE:/*红白亮*/
			(void)SetRelayDriveState(GetSignalDxRelayId(signalId), RELAY_STATE_DOWN);/*调车信号继电器落下*/
			(void)SetRelayDriveState(GetSignalYxRelayId(signalId), RELAY_STATE_UP);/*引导信号继电器吸起*/
			break;
		default:/*红亮*/
			(void)SetRelayDriveState(GetSignalDxRelayId(signalId), RELAY_STATE_DOWN);/*调车信号继电器落下*/
			(void)SetRelayDriveState(GetSignalYxRelayId(signalId), RELAY_STATE_DOWN);/*引导信号继电器落下*/
			returnValue = CI_ERROR;
			break;
		}
		break;
	case SIGNAL_TYPE_THREE_JINKU_YINDAO:  /*进库信号机（三显示带引导）*/  /*新机场车辆段新增信号机类型2019.1.15*/
		switch (curDrvColor)
		{
		case SIGNAL_DRIVECOLOUR_RED:/*红亮*/
			(void)SetRelayDriveState(GetSignalDxRelayId(signalId), RELAY_STATE_DOWN);/*调车信号继电器落下*/
			(void)SetRelayDriveState(GetSignalYxRelayId(signalId), RELAY_STATE_DOWN);/*引导信号继电器落下*/
			(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_DOWN);/*列车信号继电器落下*/
			break;
		case SIGNAL_DRIVECOLOUR_WHITE:/*白亮*/
			(void)SetRelayDriveState(GetSignalDxRelayId(signalId), RELAY_STATE_UP);/*调车信号继电器吸起*/
			(void)SetRelayDriveState(GetSignalYxRelayId(signalId), RELAY_STATE_DOWN);/*引导信号继电器落下*/
			(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_DOWN);/*列车信号继电器落下*/
			break;
		case SIGNAL_DRIVECOLOUR_REDYELLOW:/*红黄亮*/
			(void)SetRelayDriveState(GetSignalDxRelayId(signalId), RELAY_STATE_DOWN);/*调车信号继电器落下*/
			(void)SetRelayDriveState(GetSignalYxRelayId(signalId), RELAY_STATE_UP);/*引导信号继电器吸起*/
			(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_DOWN);/*列车信号继电器落下*/
			break;
		case SIGNAL_DRIVECOLOUR_YELLOW:/*黄亮*/
			(void)SetRelayDriveState(GetSignalDxRelayId(signalId), RELAY_STATE_DOWN);/*调车信号继电器落下*/
			(void)SetRelayDriveState(GetSignalYxRelayId(signalId), RELAY_STATE_DOWN);/*引导信号继电器落下*/
			(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_UP);/*列车信号继电器吸起*/
			break;
		default:/*红亮*/
			(void)SetRelayDriveState(GetSignalDxRelayId(signalId), RELAY_STATE_DOWN);/*调车信号继电器落下*/
			(void)SetRelayDriveState(GetSignalYxRelayId(signalId), RELAY_STATE_DOWN);/*引导信号继电器落下*/
			(void)SetRelayDriveState(GetSignalLxRelayId(signalId), RELAY_STATE_DOWN);/*列车信号继电器落下*/
			returnValue = CI_ERROR;
			break;
		}
		break;
	case SIGNAL_TYPE_THREE_JINKU_OFF:  /*进出库信号机三显示带引导，且可灭灯cgh-合并CID-3037-8：*/
		switch (curDrvColor)
		{
		case SIGNAL_DRIVECOLOUR_RED:
			(void)SetRelayDriveState(dxRelayId, RELAY_STATE_DOWN);/*调车信号继电器落下*/
			(void)SetRelayDriveState(yxRelayId, RELAY_STATE_DOWN);/*引导信号继电器落下*/
			(void)SetRelayDriveState(lxRelayId, RELAY_STATE_DOWN);/*列车信号继电器落下*/
			(void)SetRelayDriveState(ddRelayId, RELAY_STATE_DOWN);/*点灯继电器落下*/
			break;
		case SIGNAL_DRIVECOLOUR_WHITE:
			(void)SetRelayDriveState(dxRelayId, RELAY_STATE_UP);/*调车信号继电器吸起*/
			(void)SetRelayDriveState(yxRelayId, RELAY_STATE_DOWN);/*引导信号继电器落下*/
			(void)SetRelayDriveState(lxRelayId, RELAY_STATE_DOWN);/*列车信号继电器落下*/
			(void)SetRelayDriveState(ddRelayId, RELAY_STATE_DOWN);/*点灯继电器落下*/
			break;
		case SIGNAL_DRIVECOLOUR_REDYELLOW:/*红黄亮*/
			(void)SetRelayDriveState(dxRelayId, RELAY_STATE_DOWN);/*调车信号继电器落下*/
			(void)SetRelayDriveState(yxRelayId, RELAY_STATE_UP);/*引导信号继电器吸起*/
			(void)SetRelayDriveState(lxRelayId, RELAY_STATE_DOWN);/*列车信号继电器落下*/
			(void)SetRelayDriveState(ddRelayId, RELAY_STATE_DOWN);/*点灯继电器落下*/
			break;
		case SIGNAL_DRIVECOLOUR_YELLOW:
			(void)SetRelayDriveState(dxRelayId, RELAY_STATE_DOWN);/*调车信号继电器落下*/
			(void)SetRelayDriveState(yxRelayId, RELAY_STATE_DOWN);/*引导信号继电器落下*/
			(void)SetRelayDriveState(lxRelayId, RELAY_STATE_UP);/*列车信号继电器吸起*/
			(void)SetRelayDriveState(ddRelayId, RELAY_STATE_DOWN);/*点灯继电器落下*/
			break;
		case SIGNAL_DRIVECOLOUR_REDCLOSE:
			(void)SetRelayDriveState(dxRelayId, RELAY_STATE_DOWN);/*调车信号继电器落下*/
			(void)SetRelayDriveState(yxRelayId, RELAY_STATE_DOWN);/*引导信号继电器落下*/
			(void)SetRelayDriveState(lxRelayId, RELAY_STATE_DOWN);/*列车信号继电器落下*/
			(void)SetRelayDriveState(ddRelayId, RELAY_STATE_UP);/*点灯继电器吸起*/
			break;
		case SIGNAL_DRIVECOLOUR_YELLOWCLOSE:
			(void)SetRelayDriveState(dxRelayId, RELAY_STATE_DOWN);/*调车信号继电器落下*/
			(void)SetRelayDriveState(yxRelayId, RELAY_STATE_DOWN);/*引导信号继电器落下*/
			(void)SetRelayDriveState(lxRelayId, RELAY_STATE_UP);/*列车信号继电器吸起*/
			(void)SetRelayDriveState(ddRelayId, RELAY_STATE_UP);/*点灯继电器吸起*/
			break;
		default:
			(void)SetRelayDriveState(dxRelayId, RELAY_STATE_DOWN);/*调车信号继电器落下*/
			(void)SetRelayDriveState(yxRelayId, RELAY_STATE_DOWN);/*引导信号继电器落下*/
			(void)SetRelayDriveState(lxRelayId, RELAY_STATE_DOWN);/*列车信号继电器落下*/
			(void)SetRelayDriveState(ddRelayId, RELAY_STATE_DOWN);/*点灯继电器落下*/
			returnValue = CI_ERROR;
			break;
		}
		break;
	default:
		returnValue = CI_ERROR;
		break;
	}

	return returnValue;
}


/*
* 功能描述： 根据继电器采集数据获取指定ID信号机的当前显示颜色
* 参数说明： const UINT16 signalId
* 返回值  ： 0u: SIGNAL_SHOWCOLOUR_INVALID
*			 >0u: 当前显示颜色
*/
UINT8 GetSignalShowColor(const UINT16 signalId)
{
	UINT16 firDsRelayId = 0u;  	/*1灯丝继电器ID */
	UINT16 secDsRelayId = 0u;  	/*2灯丝继电器ID*/
	UINT16 lxRelayId = 0u;    	/*列车信号继电器ID*/
	UINT16 zxRelayId = 0u;    	/*正线信号继电器ID*/
	UINT16 yxRelayId = 0u;    	/*引导信号继电器ID*/
	UINT16 ddRelayId = 0u;    	/*点灯继电器ID*/
	UINT16 dxRelayId = 0u;		/*调车信号继电器ID*/
	UINT16 yellowRelayId = 0u;	/*黄灯继电器ID*/
	UINT16 greenRelayId = 0u;	/*绿灯继电器ID*/
	UINT16 blueRelayId = 0u;		/*蓝灯继电器ID*/

	UINT8 signalType = 0u;	/*信号机点灯电路类型*/
	UINT8 returnValue = 0u;/*返回值*/
	UINT8 bCiSwitchShowGreenYellow = FUNC_SWITCH_OFF;/*ci显示绿黄开关,默认是关闭的*/

	UINT8 firDsRelaySta = RELAY_STATE_DOWN;  	/*1灯丝继电器状态 */
	UINT8 secDsRelaySta = RELAY_STATE_DOWN;  	/*2灯丝继电器状态*/
	UINT8 lxRelaySta = RELAY_STATE_DOWN;    	/*列车信号继电器状态*/
	UINT8 zxRelaySta = RELAY_STATE_DOWN;    	/*正线信号继电器状态*/
	UINT8 yxRelaySta = RELAY_STATE_DOWN;    	/*引导信号继电器状态*/
	UINT8 ddRelaySta = RELAY_STATE_DOWN;    	/*点灯继电器状态*/
	UINT8 dxRelaySta = RELAY_STATE_DOWN;		/*调车信号继电器状态*/
	UINT8 yellowRelaySta = RELAY_STATE_DOWN;	/*黄灯继电器状态*/
	UINT8 greenRelaySta = RELAY_STATE_DOWN;		/*绿灯继电器状态*/

	firDsRelayId = GetSignalFirstDsRelayId(signalId);  /*获取信号机1灯丝继电器ID*/
	secDsRelayId = GetSignalSecondDsRelayId(signalId);  /*获取信号机2灯丝继电器ID*/
	lxRelayId = GetSignalLxRelayId(signalId);  /*获取信号机列车信号继电器ID*/
	zxRelayId = GetSignalZxRelayId(signalId);  /*获取信号机正线信号继电器ID*/
	yxRelayId = GetSignalYxRelayId(signalId);  /*获取信号机引导信号继电器ID*/
	dxRelayId = GetSignalDxRelayId(signalId);	/*获取信号机调车信号继电器ID*/
	ddRelayId = GetSignalDdRelayId(signalId);  /*获取信号机点灯继电器ID*/
	yellowRelayId = GetSignalYellowRelayId(signalId);	/*黄灯继电器ID*/
	greenRelayId = GetSignalGreenRelayId(signalId);		/*绿灯继电器ID*/
	blueRelayId = GetSignalBlueRelayId(signalId);		/*蓝灯继电器ID*/


	signalType = GetSignalType(signalId);	/*获取信号机点灯逻辑类型*/

	firDsRelaySta = GetRelayCollState(firDsRelayId);	/*获取信号机1灯丝继电器状态*/
	secDsRelaySta = GetRelayCollState(secDsRelayId);	/*获取信号机2灯丝继电器状态*/
	ddRelaySta = GetRelayCollState(ddRelayId);	/*获取信号机点灯继电器状态*/
	lxRelaySta = GetRelayCollState(lxRelayId);	/*获取信号机列车信号继电器状态*/
	yxRelaySta = GetRelayCollState(yxRelayId);	/*获取信号机引导信号继电器状态*/
	zxRelaySta = GetRelayCollState(zxRelayId);  /*获取信号机正线信号继电器状态*/
	dxRelaySta = GetRelayCollState(dxRelayId);	/*获取信号机调车信号继电器状态*/
	yellowRelaySta = GetRelayCollState(yellowRelayId);
	greenRelaySta = GetRelayCollState(greenRelayId);

	if (0u == ddRelayId)
	{
		returnValue = GetNoDDJSignalColor(signalId);
	}
	else
	{
		bCiSwitchShowGreenYellow = GetCiFunctionSwitchConfig(CI_FUNCTION_SWITCH_SHOW_SIGNAL_GreenYellow);
		switch (signalType)
		{
		case SIGNAL_TYPE_4_ALL_NOYINDAO_ZX:/*0x2A 四显示（不封灯、不带引导） 红、绿、蓝、黄*/
		{
			if (FUNC_SWITCH_ON == bCiSwitchShowGreenYellow)/*如果显示绿黄灯开关【打开】*/
			{
				if ((RELAY_STATE_UP == ddRelaySta) && (RELAY_STATE_UP == lxRelaySta) && (RELAY_STATE_UP == zxRelaySta)
					&& (RELAY_STATE_UP == greenRelaySta) && (RELAY_STATE_DOWN == yellowRelaySta)
					&& (RELAY_STATE_DOWN == firDsRelaySta) && (RELAY_STATE_DOWN == secDsRelaySta))
				{/*点灯吸起、列车吸起、正线吸起、绿灯吸起、黄灯落下、1灯丝落下、2灯丝落下*/
					returnValue = SIGNAL_SHOWCOLOUR_GREENCLOSE;/*绿灭*/
				}
				else if ((RELAY_STATE_DOWN == ddRelaySta) && (RELAY_STATE_UP == lxRelaySta) && (RELAY_STATE_UP == zxRelaySta)
					&& (RELAY_STATE_UP == greenRelaySta) && (RELAY_STATE_DOWN == yellowRelaySta)
					&& (RELAY_STATE_UP == firDsRelaySta) && (RELAY_STATE_DOWN == secDsRelaySta))
				{
					returnValue = SIGNAL_SHOWCOLOUR_GREEN; /*绿灯*/
				}
				else if ((RELAY_STATE_UP == ddRelaySta) && (RELAY_STATE_UP == lxRelaySta) && (RELAY_STATE_UP == zxRelaySta)
					&& (RELAY_STATE_DOWN == greenRelaySta) && (RELAY_STATE_DOWN == yellowRelaySta)
					&& (RELAY_STATE_DOWN == firDsRelaySta) && (RELAY_STATE_DOWN == secDsRelaySta))
				{
					returnValue = SIGNAL_SHOWCOLOUR_GREENYELLOWCLOSE;/*灭绿黄*/
				}
				else if ((RELAY_STATE_DOWN == ddRelaySta) && (RELAY_STATE_UP == lxRelaySta) && (RELAY_STATE_UP == zxRelaySta)
					&& (RELAY_STATE_DOWN == greenRelaySta) && (RELAY_STATE_DOWN == yellowRelaySta)
					&& (RELAY_STATE_UP == firDsRelaySta) && (RELAY_STATE_UP == secDsRelaySta))
				{
					returnValue = SIGNAL_SHOWCOLOUR_GREENYELLOW;/*亮绿黄*/
				}
				else if ((RELAY_STATE_UP == ddRelaySta) && (RELAY_STATE_UP == lxRelaySta) && (RELAY_STATE_DOWN == zxRelaySta)
					&& (RELAY_STATE_DOWN == greenRelaySta) && (RELAY_STATE_UP == yellowRelaySta)
					&& (RELAY_STATE_DOWN == firDsRelaySta) && (RELAY_STATE_DOWN == secDsRelaySta))
				{
					returnValue = SIGNAL_SHOWCOLOUR_YELLOWCLOSE;/*灭黄灯*/
				}
				else if ((RELAY_STATE_DOWN == ddRelaySta) && (RELAY_STATE_UP == lxRelaySta) && (RELAY_STATE_DOWN == zxRelaySta)
					&& (RELAY_STATE_DOWN == greenRelaySta) && (RELAY_STATE_UP == yellowRelaySta)
					&& (RELAY_STATE_UP == firDsRelaySta) && (RELAY_STATE_DOWN == secDsRelaySta))
				{
					returnValue = SIGNAL_SHOWCOLOUR_YELLOW;/*黄灯*/
				}
				else if ((RELAY_STATE_UP == ddRelaySta) && (RELAY_STATE_DOWN == lxRelaySta) && (RELAY_STATE_UP == zxRelaySta)
					&& (RELAY_STATE_DOWN == greenRelaySta) && (RELAY_STATE_DOWN == yellowRelaySta)
					&& (RELAY_STATE_DOWN == firDsRelaySta) && (RELAY_STATE_DOWN == secDsRelaySta))
				{
					returnValue = SIGNAL_SHOWCOLOUR_REDCLOSE;/*灭红灯*/
				}
				else if ((RELAY_STATE_DOWN == ddRelaySta) && (RELAY_STATE_DOWN == lxRelaySta) && (RELAY_STATE_UP == zxRelaySta)
					&& (RELAY_STATE_DOWN == greenRelaySta) && (RELAY_STATE_DOWN == yellowRelaySta)
					&& (RELAY_STATE_UP == firDsRelaySta) && (RELAY_STATE_DOWN == secDsRelaySta))
				{
					returnValue = SIGNAL_SHOWCOLOUR_RED;/*红灯*/
				}
				else
				{
					returnValue = SIGNAL_SHOWCOLOUR_INVALID;
				}
			}
			break;
		}
		case SIGNAL_TYPE_4_NOGREEN_NOYINDAO_ZX:/*0x2B 四显示（封绿灯、可单独点亮黄灯）红、蓝、黄*/
		{
			if (FUNC_SWITCH_ON == bCiSwitchShowGreenYellow)/*如果显示绿黄灯开关【打开】*/
			{
				if ((RELAY_STATE_UP == ddRelaySta) && (RELAY_STATE_UP == lxRelaySta)
					&& (RELAY_STATE_DOWN == firDsRelaySta))
				{
					returnValue = SIGNAL_SHOWCOLOUR_YELLOWCLOSE;/*灭黄灯*/
				}
				else if ((RELAY_STATE_DOWN == ddRelaySta) && (RELAY_STATE_UP == lxRelaySta)
					&& (RELAY_STATE_UP == firDsRelaySta))
				{
					returnValue = SIGNAL_SHOWCOLOUR_YELLOW;/*黄灯*/
				}
				else if ((RELAY_STATE_UP == ddRelaySta) && (RELAY_STATE_DOWN == lxRelaySta)
					&& (RELAY_STATE_DOWN == firDsRelaySta))
				{
					returnValue = SIGNAL_SHOWCOLOUR_REDCLOSE;/*灭红灯*/
				}
				else if ((RELAY_STATE_DOWN == ddRelaySta) && (RELAY_STATE_DOWN == lxRelaySta)
					&& (RELAY_STATE_UP == firDsRelaySta))
				{
					returnValue = SIGNAL_SHOWCOLOUR_RED;/*红灯*/
				}
				else
				{
					returnValue = SIGNAL_SHOWCOLOUR_INVALID;/*无效*/
				}
			}
			break;
		}
		case SIGNAL_TYPE_5_NOGREEN_YINDAO_CD:/*0x2C 高柱五显示（封绿灯、带引导、可点亮双黄灯）红、黄、绿、白、双黄*/
		{
			if (FUNC_SWITCH_ON == bCiSwitchShowGreenYellow)/*如果显示绿黄灯开关【打开】*/
			{
				if ((RELAY_STATE_UP == lxRelaySta) && (RELAY_STATE_DOWN == yxRelaySta)
					&& (RELAY_STATE_UP == firDsRelaySta) && (RELAY_STATE_UP == secDsRelaySta))
				{
					returnValue = SIGNAL_SHOWCOLOUR_DOUBLE_YELLOW;/*双黄灯*/
				}
				else if ((RELAY_STATE_DOWN == lxRelaySta) && (RELAY_STATE_DOWN == yxRelaySta)
					&& (RELAY_STATE_UP == firDsRelaySta) && (RELAY_STATE_DOWN == secDsRelaySta))
				{
					returnValue = SIGNAL_SHOWCOLOUR_RED;/*红灯*/
				}
				else if ((RELAY_STATE_DOWN == lxRelaySta) && (RELAY_STATE_UP == yxRelaySta)
					&& (RELAY_STATE_UP == firDsRelaySta) && (RELAY_STATE_UP == secDsRelaySta))
				{
					returnValue = SIGNAL_SHOWCOLOUR_RED_WHITE;/*红白灯*/
				}
				else
				{
					returnValue = SIGNAL_SHOWCOLOUR_INVALID;/*无效*/
				}
			}
			break;
		}
		case SIGNAL_TYPE_5_NOY_NOYINDAO_CD:	/* 0x2D 矮柱五显示（封黄灯、不带引导）红、绿、双绿、白*/
		{
			if (FUNC_SWITCH_ON == bCiSwitchShowGreenYellow)/*如果显示绿黄灯开关【打开】*/
			{
				if ((RELAY_STATE_UP == lxRelaySta) && (RELAY_STATE_UP == zxRelaySta) && (RELAY_STATE_DOWN == dxRelaySta)
					&& (RELAY_STATE_UP == firDsRelaySta) && (RELAY_STATE_DOWN == secDsRelaySta))
				{
					returnValue = SIGNAL_SHOWCOLOUR_GREEN;/*绿灯*/
				}
				else if ((RELAY_STATE_UP == lxRelaySta) && (RELAY_STATE_DOWN == zxRelaySta) && (RELAY_STATE_DOWN == dxRelaySta)
					&& (RELAY_STATE_UP == firDsRelaySta) && (RELAY_STATE_UP == secDsRelaySta))
				{
					returnValue = SIGNAL_SHOWCOLOUR_DOUBLE_GREEN;/*双绿灯*/
				}
				else if ((RELAY_STATE_DOWN == lxRelaySta) && (RELAY_STATE_DOWN == zxRelaySta) && (RELAY_STATE_UP == dxRelaySta)
					&& (RELAY_STATE_UP == firDsRelaySta) && (RELAY_STATE_DOWN == secDsRelaySta))
				{
					returnValue = SIGNAL_SHOWCOLOUR_WHITE;/*白灯*/
				}
				else if ((RELAY_STATE_DOWN == lxRelaySta) && (RELAY_STATE_DOWN == zxRelaySta) && (RELAY_STATE_DOWN == dxRelaySta)
					&& (RELAY_STATE_UP == firDsRelaySta) && (RELAY_STATE_DOWN == secDsRelaySta))
				{
					returnValue = SIGNAL_SHOWCOLOUR_RED;/*红灯*/
				}
				else
				{
					returnValue = SIGNAL_SHOWCOLOUR_INVALID;/*无效*/
				}
			}
			break;
		}
		case SIGNAL_TYPE_4_ALL_NOYINDAO_CD:	/*0x2E	 矮柱四显示（不带引导）*/
		{
			if (FUNC_SWITCH_ON == bCiSwitchShowGreenYellow)/*如果显示绿黄灯开关【打开】*/
			{
				if ((RELAY_STATE_UP == lxRelaySta) && (RELAY_STATE_UP == greenRelaySta) && (RELAY_STATE_DOWN == dxRelaySta)
					&& (RELAY_STATE_UP == firDsRelaySta))
				{
					returnValue = SIGNAL_SHOWCOLOUR_GREEN;/*绿灯*/
				}
				else if ((RELAY_STATE_UP == lxRelaySta) && (RELAY_STATE_DOWN == greenRelaySta) && (RELAY_STATE_DOWN == dxRelaySta)
					&& (RELAY_STATE_UP == firDsRelaySta))
				{
					returnValue = SIGNAL_SHOWCOLOUR_YELLOW;/*黄灯*/
				}
				else if ((RELAY_STATE_DOWN == lxRelaySta) && (RELAY_STATE_DOWN == greenRelaySta) && (RELAY_STATE_UP == dxRelaySta)
					&& (RELAY_STATE_UP == firDsRelaySta))
				{
					returnValue = SIGNAL_SHOWCOLOUR_WHITE;/*白灯*/
				}
				else if ((RELAY_STATE_DOWN == lxRelaySta) && (RELAY_STATE_DOWN == greenRelaySta) && (RELAY_STATE_DOWN == dxRelaySta)
					&& (RELAY_STATE_UP == firDsRelaySta))
				{
					returnValue = SIGNAL_SHOWCOLOUR_RED;/*红灯*/
				}
				else
				{
					returnValue = SIGNAL_SHOWCOLOUR_INVALID;/*无效*/
				}
			}
			break;
		}
		case SIGNAL_TYPE_5_NOY_NOYINDAO_WB:	/*	0x2f  矮柱五灯位信号机封黄灯（不带引导）白、蓝*/
		{
			if (FUNC_SWITCH_ON == bCiSwitchShowGreenYellow)/*如果显示绿黄灯开关【打开】*/
			{
				if ((RELAY_STATE_UP == lxRelaySta) && (RELAY_STATE_DOWN == dxRelaySta) && (RELAY_STATE_UP == firDsRelaySta)
					&& (RELAY_STATE_UP == secDsRelaySta))
				{
					returnValue = SIGNAL_SHOWCOLOUR_DOUBLE_GREEN;/*双绿灯*/
				}
				else if ((RELAY_STATE_DOWN == lxRelaySta) && (RELAY_STATE_UP == dxRelaySta) && (RELAY_STATE_UP == firDsRelaySta)
					&& (RELAY_STATE_DOWN == secDsRelaySta))
				{
					returnValue = SIGNAL_SHOWCOLOUR_WHITE;/*白灯*/
				}
				else if ((RELAY_STATE_DOWN == lxRelaySta) && (RELAY_STATE_DOWN == dxRelaySta) && (RELAY_STATE_UP == firDsRelaySta)
					&& (RELAY_STATE_DOWN == secDsRelaySta))
				{
					returnValue = SIGNAL_SHOWCOLOUR_RED;/*红灯*/
				}
				else
				{
					returnValue = SIGNAL_SHOWCOLOUR_INVALID;/*无效*/
				}
			}
			break;
		}
		case SIGNAL_TYPE_3_RGG_CD:	/*	0x30	矮柱3灯位：红、双绿*/
		{
			if (FUNC_SWITCH_ON == bCiSwitchShowGreenYellow)/*如果显示绿黄灯开关【打开】*/
			{
				if ((RELAY_STATE_UP == lxRelaySta) && (RELAY_STATE_UP == firDsRelaySta))
				{
					returnValue = SIGNAL_SHOWCOLOUR_DOUBLE_GREEN;	/*双绿灯*/
				}
				else if ((RELAY_STATE_DOWN == lxRelaySta) && (RELAY_STATE_UP == firDsRelaySta))
				{
					returnValue = SIGNAL_SHOWCOLOUR_RED;	/*红灯*/
				}
				else
				{
					returnValue = SIGNAL_SHOWCOLOUR_INVALID;/*无效*/
				}
			}
			break;
		}
		case SIGNAL_TYPE_3_RGG_NOGREEN_CD:	  /*0x31	矮柱3灯位：红、双绿、封绿灯*/
		{
			if (FUNC_SWITCH_ON == bCiSwitchShowGreenYellow)/*如果显示绿黄灯开关【打开】*/
			{
				if ((RELAY_STATE_UP == lxRelaySta) && (RELAY_STATE_UP == firDsRelaySta))
				{
					returnValue = SIGNAL_SHOWCOLOUR_GREEN;	/*绿灯*/
				}
				else if ((RELAY_STATE_DOWN == lxRelaySta) && (RELAY_STATE_UP == firDsRelaySta))
				{
					returnValue = SIGNAL_SHOWCOLOUR_RED;	/*红灯*/
				}
				else
				{
					returnValue = SIGNAL_SHOWCOLOUR_INVALID;/*无效*/
				}
			}
			break;
		}
		case SIGNAL_TYPE_3_NOGREENWHITE_CD:	/*	0x32	矮柱3灯位：绿、红、白，封绿、白灯*/
		{
			if (FUNC_SWITCH_ON == bCiSwitchShowGreenYellow)/*如果显示绿黄灯开关【打开】*/
			{
				if ((RELAY_STATE_UP == firDsRelaySta))
				{
					returnValue = SIGNAL_SHOWCOLOUR_RED;	/*红灯*/
				}
				else
				{
					returnValue = SIGNAL_SHOWCOLOUR_INVALID;/*无效*/
				}
			}
			break;
		}
		case SIGNAL_TYPE_4_ALL_NOYINDAO_NOYELLOWONLY_ZX:/* 0x33 出站兼道岔防护信号机(黄、绿、红、蓝四灯位，不封灯位，不可单独点亮黄灯)*/
		{
			if (FUNC_SWITCH_ON == bCiSwitchShowGreenYellow)/*如果显示绿黄灯开关【打开】*/
			{
				if ((RELAY_STATE_UP == ddRelaySta) && (RELAY_STATE_UP == lxRelaySta)
					&& (RELAY_STATE_UP == greenRelaySta) && (RELAY_STATE_DOWN == firDsRelaySta) && (RELAY_STATE_DOWN == secDsRelaySta))
				{
					returnValue = SIGNAL_SHOWCOLOUR_GREENCLOSE;/*灭绿灯*/
				}
				else if ((RELAY_STATE_DOWN == ddRelaySta) && (RELAY_STATE_UP == lxRelaySta)
					&& (RELAY_STATE_UP == greenRelaySta) && (RELAY_STATE_UP == firDsRelaySta) && (RELAY_STATE_DOWN == secDsRelaySta))
				{
					returnValue = SIGNAL_SHOWCOLOUR_GREEN;/*亮绿灯*/
				}
				else if ((RELAY_STATE_UP == ddRelaySta) && (RELAY_STATE_UP == lxRelaySta)
					&& (RELAY_STATE_DOWN == greenRelaySta) && (RELAY_STATE_DOWN == firDsRelaySta) && (RELAY_STATE_DOWN == secDsRelaySta))
				{
					returnValue = SIGNAL_SHOWCOLOUR_GREENYELLOWCLOSE;/*灭绿黄灯*/
				}
				else if ((RELAY_STATE_DOWN == ddRelaySta) && (RELAY_STATE_UP == lxRelaySta)
					&& (RELAY_STATE_DOWN == greenRelaySta) && (RELAY_STATE_UP == firDsRelaySta) && (RELAY_STATE_UP == secDsRelaySta))
				{
					returnValue = SIGNAL_SHOWCOLOUR_GREENYELLOW;/*亮绿黄灯*/
				}
				else if ((RELAY_STATE_UP == ddRelaySta) && (RELAY_STATE_DOWN == lxRelaySta)
					&& (RELAY_STATE_DOWN == greenRelaySta) && (RELAY_STATE_DOWN == firDsRelaySta) && (RELAY_STATE_DOWN == secDsRelaySta))
				{
					returnValue = SIGNAL_SHOWCOLOUR_REDCLOSE;/*灭红灯*/
				}
				else if ((RELAY_STATE_DOWN == ddRelaySta) && (RELAY_STATE_DOWN == lxRelaySta)
					&& (RELAY_STATE_DOWN == greenRelaySta) && (RELAY_STATE_UP == firDsRelaySta) && (RELAY_STATE_DOWN == secDsRelaySta))
				{
					returnValue = SIGNAL_SHOWCOLOUR_RED;/*亮红灯*/
				}
				else
				{
					returnValue = SIGNAL_SHOWCOLOUR_INVALID;/*无效*/
				}
			}
			break;
		}
		case SIGNAL_TYPE_4_NOGREENBLUE_NOYINDAO_ZX:/*0x34 联络线信号机（黄、绿、红、蓝四灯位，封绿、蓝灯，可单独点亮黄灯）*/
		{
			if (FUNC_SWITCH_ON == bCiSwitchShowGreenYellow)/*如果显示绿黄灯开关【打开】*/
			{
				if ((RELAY_STATE_UP == lxRelaySta) && (RELAY_STATE_UP == firDsRelaySta))
				{
					returnValue = SIGNAL_SHOWCOLOUR_YELLOW;/*亮黄灯*/
				}
				else if ((RELAY_STATE_DOWN == lxRelaySta) && (RELAY_STATE_UP == firDsRelaySta))
				{
					returnValue = SIGNAL_SHOWCOLOUR_RED;/*亮红灯*/
				}
				else
				{
					returnValue = SIGNAL_SHOWCOLOUR_INVALID;/*无效*/
				}
			}
			break;
		}
		case SIGNAL_TYPE_3_ALL_NOYINDAO_CD:/*0x35 矮柱三显信号机(不封灯、不带引导)（红白绿）*/
		{
			if ((RELAY_STATE_DOWN == lxRelaySta) && (RELAY_STATE_DOWN == dxRelaySta) && (RELAY_STATE_UP == firDsRelaySta))
			{
				returnValue = SIGNAL_SHOWCOLOUR_RED;/*亮红灯*/
			}
			else if ((RELAY_STATE_UP == lxRelaySta) && (RELAY_STATE_DOWN == dxRelaySta) && (RELAY_STATE_UP == firDsRelaySta))
			{
				returnValue = SIGNAL_SHOWCOLOUR_GREEN;/*亮绿灯*/
			}
			else if ((RELAY_STATE_DOWN == lxRelaySta) && (RELAY_STATE_UP == dxRelaySta) && (RELAY_STATE_UP == firDsRelaySta))
			{
				returnValue = SIGNAL_SHOWCOLOUR_WHITE;/*亮白灯*/
			}
			else
			{
				returnValue = SIGNAL_SHOWCOLOUR_INVALID;/*无效*/
			}

			break;
		}
		case SIGNAL_TYPE_1_ALL_END:/*0x36 单显示尽头阻挡信号机*/
		{
			if (RELAY_STATE_UP == firDsRelaySta)
			{
				returnValue = SIGNAL_SHOWCOLOUR_RED;/*红灯*/
			}
			else
			{
				returnValue = SIGNAL_SHOWCOLOUR_INVALID;
			}

			break;
		}
		case SIGNAL_TYPE_THREE_ALL_YINDAO:/*三显示（红、黄、绿、红黄）*/
		{
			if ((RELAY_STATE_DOWN == ddRelaySta)
				&& (RELAY_STATE_DOWN == lxRelaySta)
				&& (RELAY_STATE_DOWN == yxRelaySta)
				&& (RELAY_STATE_UP == firDsRelaySta)
				&& (RELAY_STATE_DOWN == secDsRelaySta))
			{/*点灯继电器落下、列车信号继电器落下、引导信号机落下、1灯丝继电器吸起、2灯丝继电器落下*/

				returnValue = SIGNAL_SHOWCOLOUR_RED;/*红亮*/
			}
			else if ((RELAY_STATE_UP == ddRelaySta)
				&& (RELAY_STATE_DOWN == lxRelaySta)
				&& (RELAY_STATE_DOWN == yxRelaySta)
				&& (RELAY_STATE_DOWN == firDsRelaySta)
				&& (RELAY_STATE_DOWN == secDsRelaySta))
			{/*点灯继电器吸起、列车信号继电器落下、引导信号机落下、1灯丝继电器落下、2灯丝继电器落下*/

				returnValue = SIGNAL_SHOWCOLOUR_REDCLOSE;/*红灭*/
			}
			else if ((RELAY_STATE_DOWN == ddRelaySta)
				&& (RELAY_STATE_UP == lxRelaySta)
				&& (RELAY_STATE_DOWN == zxRelaySta)
				&& (RELAY_STATE_DOWN == yxRelaySta)
				&& (RELAY_STATE_UP == firDsRelaySta)
				&& (RELAY_STATE_DOWN == secDsRelaySta))
			{/*点灯继电器落下、列车信号继电器吸起、正线信号继电器落下、引导信号机落下、1灯丝继电器吸起、2灯丝继电器落下*/

				returnValue = SIGNAL_SHOWCOLOUR_YELLOW;/*黄亮*/
			}
			else if ((RELAY_STATE_UP == ddRelaySta)
				&& (RELAY_STATE_UP == lxRelaySta)
				&& (RELAY_STATE_DOWN == zxRelaySta)
				&& (RELAY_STATE_DOWN == yxRelaySta)
				&& (RELAY_STATE_DOWN == firDsRelaySta)
				&& (RELAY_STATE_DOWN == secDsRelaySta))
			{/*点灯继电器吸起、列车信号继电器吸起、正线信号继电器落下、引导信号机落下、1灯丝继电器落下、2灯丝继电器落下*/

				returnValue = SIGNAL_SHOWCOLOUR_YELLOWCLOSE;/*黄灭*/
			}
			else if ((RELAY_STATE_DOWN == ddRelaySta)
				&& (RELAY_STATE_DOWN == lxRelaySta)
				&& (RELAY_STATE_UP == yxRelaySta)
				&& (RELAY_STATE_UP == firDsRelaySta)
				&& (RELAY_STATE_UP == secDsRelaySta))
			{/*点灯继电器落下、列车信号继电器落下、引导信号机吸起、1灯丝继电器吸起、2灯丝继电器吸起*/

				returnValue = SIGNAL_SHOWCOLOUR_REDYELLOW;/*红黄亮*/
			}
			else if ((RELAY_STATE_DOWN == ddRelaySta)
				&& (RELAY_STATE_UP == lxRelaySta)
				&& (RELAY_STATE_UP == zxRelaySta)
				&& (RELAY_STATE_DOWN == yxRelaySta)
				&& (RELAY_STATE_UP == firDsRelaySta)
				&& (RELAY_STATE_DOWN == secDsRelaySta))
			{/*点灯继电器落下、列车信号继电器吸起、正线信号继电器吸起、引导信号机落下、1灯丝继电器吸起、2灯丝继电器落下*/

				returnValue = SIGNAL_SHOWCOLOUR_GREEN;/*绿亮*/
			}
			else if ((RELAY_STATE_UP == ddRelaySta)
				&& (RELAY_STATE_UP == lxRelaySta)
				&& (RELAY_STATE_UP == zxRelaySta)
				&& (RELAY_STATE_DOWN == yxRelaySta)
				&& (RELAY_STATE_DOWN == firDsRelaySta)
				&& (RELAY_STATE_DOWN == secDsRelaySta))
			{/*点灯继电器吸起、列车信号继电器吸起、正线信号继电器吸起、引导信号机落下、1灯丝继电器落下、2灯丝继电器落下*/

				returnValue = SIGNAL_SHOWCOLOUR_GREENCLOSE;/*绿灭*/
			}
			else
			{
				returnValue = SIGNAL_SHOWCOLOUR_INVALID;
			}
		}
		break;
		case SIGNAL_TYPE_THREE_ALL_NOYINDAO:/*三显示无引导（红、黄、绿）*/
		{


			if ((RELAY_STATE_DOWN == ddRelaySta)
				&& (RELAY_STATE_DOWN == lxRelaySta)
				&& (RELAY_STATE_UP == firDsRelaySta))
			{/*点灯继电器落下、列车信号继电器落下、1灯丝继电器吸起*/

				returnValue = SIGNAL_SHOWCOLOUR_RED;/*红亮*/
			}
			else if ((RELAY_STATE_UP == ddRelaySta)
				&& (RELAY_STATE_DOWN == lxRelaySta)
				&& (RELAY_STATE_DOWN == firDsRelaySta))
			{/*点灯继电器吸起、列车信号继电器落下、1灯丝继电器落下*/

				returnValue = SIGNAL_SHOWCOLOUR_REDCLOSE;/*红灭*/
			}
			else if ((RELAY_STATE_DOWN == ddRelaySta)
				&& (RELAY_STATE_UP == lxRelaySta)
				&& (RELAY_STATE_DOWN == zxRelaySta)
				&& (RELAY_STATE_UP == firDsRelaySta))
			{/*点灯继电器落下、列车信号继电器吸起、正线信号继电器落下、1灯丝继电器吸起*/

				returnValue = SIGNAL_SHOWCOLOUR_YELLOW;/*黄亮*/
			}
			else if ((RELAY_STATE_UP == ddRelaySta)
				&& (RELAY_STATE_UP == lxRelaySta)
				&& (RELAY_STATE_DOWN == zxRelaySta)
				&& (RELAY_STATE_DOWN == firDsRelaySta))
			{/*点灯继电器吸起、列车信号继电器吸起、正线信号继电器落下、1灯丝继电器落下*/

				returnValue = SIGNAL_SHOWCOLOUR_YELLOWCLOSE;/*黄灭*/
			}
			else if ((RELAY_STATE_DOWN == ddRelaySta)
				&& (RELAY_STATE_UP == lxRelaySta)
				&& (RELAY_STATE_UP == zxRelaySta)
				&& (RELAY_STATE_UP == firDsRelaySta))
			{/*点灯继电器落下、列车信号继电器吸起、正线信号继电器吸起、1灯丝继电器吸起*/

				returnValue = SIGNAL_SHOWCOLOUR_GREEN;/*绿亮*/
			}
			else if ((RELAY_STATE_UP == ddRelaySta)
				&& (RELAY_STATE_UP == lxRelaySta)
				&& (RELAY_STATE_UP == zxRelaySta)
				&& (RELAY_STATE_DOWN == firDsRelaySta))
			{/*点灯继电器吸起、列车信号继电器吸起、正线信号继电器吸起、1灯丝继电器落下*/

				returnValue = SIGNAL_SHOWCOLOUR_GREENCLOSE;/*绿灭*/
			}
			else
			{
				returnValue = SIGNAL_SHOWCOLOUR_INVALID;
			}
		}
		break;
		case SIGNAL_TYPE_THREE_NOGREEN_YINDAO:/*三显示封绿灯（红、黄、红黄）*/
		{
			if ((RELAY_STATE_DOWN == ddRelaySta)
				&& (RELAY_STATE_DOWN == lxRelaySta)
				&& (RELAY_STATE_DOWN == yxRelaySta)
				&& (RELAY_STATE_UP == firDsRelaySta)
				&& (RELAY_STATE_DOWN == secDsRelaySta))
			{/*点灯继电器落下、列车信号继电器落下、引导信号机落下、1灯丝继电器吸起、2灯丝继电器落下*/

				returnValue = SIGNAL_SHOWCOLOUR_RED;/*红亮*/
			}
			else if ((RELAY_STATE_UP == ddRelaySta)
				&& (RELAY_STATE_DOWN == lxRelaySta)
				&& (RELAY_STATE_DOWN == yxRelaySta)
				&& (RELAY_STATE_DOWN == firDsRelaySta)
				&& (RELAY_STATE_DOWN == secDsRelaySta))
			{/*点灯继电器吸起、列车信号继电器落下、引导信号机落下、1灯丝继电器落下、2灯丝继电器落下*/

				returnValue = SIGNAL_SHOWCOLOUR_REDCLOSE;/*红灭*/
			}
			else if ((RELAY_STATE_DOWN == ddRelaySta)
				&& (RELAY_STATE_UP == lxRelaySta)
				&& (RELAY_STATE_DOWN == yxRelaySta)
				&& (RELAY_STATE_UP == firDsRelaySta)
				&& (RELAY_STATE_DOWN == secDsRelaySta))
			{/*点灯继电器落下、列车信号继电器吸起、引导信号机落下、1灯丝继电器吸起、2灯丝继电器落下*/

				returnValue = SIGNAL_SHOWCOLOUR_YELLOW;/*黄亮*/
			}
			else if ((RELAY_STATE_UP == ddRelaySta)
				&& (RELAY_STATE_UP == lxRelaySta)
				&& (RELAY_STATE_DOWN == yxRelaySta)
				&& (RELAY_STATE_DOWN == firDsRelaySta)
				&& (RELAY_STATE_DOWN == secDsRelaySta))
			{/*点灯继电器吸起、列车信号继电器吸起、引导信号机落下、1灯丝继电器落下、2灯丝继电器落下*/

				returnValue = SIGNAL_SHOWCOLOUR_YELLOWCLOSE;/*黄灭*/
			}
			else if ((RELAY_STATE_DOWN == ddRelaySta)
				&& (RELAY_STATE_DOWN == lxRelaySta)
				&& (RELAY_STATE_UP == yxRelaySta)
				&& (RELAY_STATE_UP == firDsRelaySta)
				&& (RELAY_STATE_UP == secDsRelaySta))
			{/*点灯继电器落下、列车信号继电器落下、引导信号机吸起、1灯丝继电器吸起、2灯丝继电器吸起*/

				returnValue = SIGNAL_SHOWCOLOUR_REDYELLOW;/*红黄亮*/
			}
			else
			{
				returnValue = SIGNAL_SHOWCOLOUR_INVALID;
			}
		}
		break;
		case SIGNAL_TYPE_THREE_NOGREEN_NOYINDAO:/*三显示封绿灯无引导（红、黄）*/
		{
			if ((RELAY_STATE_DOWN == ddRelaySta)
				&& (RELAY_STATE_DOWN == lxRelaySta)
				&& (RELAY_STATE_UP == firDsRelaySta))
			{/*点灯继电器落下、列车信号继电器落下、1灯丝继电器吸起*/

				returnValue = SIGNAL_SHOWCOLOUR_RED;/*红亮*/
			}
			else if ((RELAY_STATE_UP == ddRelaySta)
				&& (RELAY_STATE_DOWN == lxRelaySta)
				&& (RELAY_STATE_DOWN == firDsRelaySta))
			{/*点灯继电器吸起、列车信号继电器落下、1灯丝继电器落下*/

				returnValue = SIGNAL_SHOWCOLOUR_REDCLOSE;/*红灭*/
			}
			else if ((RELAY_STATE_DOWN == ddRelaySta)
				&& (RELAY_STATE_UP == lxRelaySta)
				&& (RELAY_STATE_UP == firDsRelaySta))
			{/*点灯继电器落下、列车信号继电器吸起、1灯丝继电器吸起*/

				returnValue = SIGNAL_SHOWCOLOUR_YELLOW;/*黄亮*/
			}
			else if ((RELAY_STATE_UP == ddRelaySta)
				&& (RELAY_STATE_UP == lxRelaySta)
				&& (RELAY_STATE_DOWN == firDsRelaySta))
			{/*点灯继电器吸起、列车信号继电器吸起、1灯丝继电器落下*/

				returnValue = SIGNAL_SHOWCOLOUR_YELLOWCLOSE;/*黄灭*/
			}
			else
			{
				returnValue = SIGNAL_SHOWCOLOUR_INVALID;
			}
		}
		break;
		case SIGNAL_TYPE_THREE_NOYELLOW_YINDAO:/*进段信号机(三显示，无黄灯，可引导，无灭灯)*/
		{
			if ((RELAY_STATE_DOWN == lxRelaySta)
				&& (RELAY_STATE_DOWN == yxRelaySta)
				&& (RELAY_STATE_UP == firDsRelaySta)
				&& (RELAY_STATE_DOWN == secDsRelaySta))
			{/*列车信号继电器落下、引导信号机落下、1灯丝继电器吸起、2灯丝继电器落下*/

				returnValue = SIGNAL_SHOWCOLOUR_RED;/*红亮*/
			}
			else if ((RELAY_STATE_UP == lxRelaySta)
				&& (RELAY_STATE_DOWN == yxRelaySta)
				&& (RELAY_STATE_UP == firDsRelaySta)
				&& (RELAY_STATE_DOWN == secDsRelaySta))
			{/*列车信号继电器吸起、引导信号机落下、1灯丝继电器吸起、2灯丝继电器落下*/

				returnValue = SIGNAL_SHOWCOLOUR_GREEN;/*绿亮*/
			}
			else if ((RELAY_STATE_DOWN == lxRelaySta)
				&& (RELAY_STATE_UP == yxRelaySta)
				&& (RELAY_STATE_UP == firDsRelaySta)
				&& (RELAY_STATE_UP == secDsRelaySta))
			{/*列车信号继电器落下、引导信号机吸起、1灯丝继电器吸起、2灯丝继电器吸起*/

				returnValue = SIGNAL_SHOWCOLOUR_REDYELLOW;/*红黄亮*/
			}
			else
			{
				returnValue = SIGNAL_SHOWCOLOUR_INVALID;
			}
		}
		break;
		case SIGNAL_TYPE_THREE_ALL_YINDAO_NOY:/*道岔防护信号机(三显示，不封灯，带引导，不可单独点亮黄灯，可灭灯)*/
		{
			if ((RELAY_STATE_DOWN == lxRelaySta)
				&& (RELAY_STATE_DOWN == yxRelaySta)
				&& (RELAY_STATE_UP == firDsRelaySta)
				&& (RELAY_STATE_DOWN == secDsRelaySta)
				&& (RELAY_STATE_DOWN == ddRelaySta))
			{/*列车信号继电器落下、引导信号机落下、1灯丝继电器吸起、2灯丝继电器落下、点灯继电器落下*/

				returnValue = SIGNAL_SHOWCOLOUR_RED;/*红亮*/
			}
			else if ((RELAY_STATE_DOWN == lxRelaySta)
				&& (RELAY_STATE_DOWN == yxRelaySta)
				&& (RELAY_STATE_DOWN == firDsRelaySta)
				&& (RELAY_STATE_DOWN == secDsRelaySta)
				&& (RELAY_STATE_UP == ddRelaySta))
			{/*列车信号继电器落下、引导信号机落下、1灯丝继电器落下、2灯丝继电器落下、点灯继电器吸起*/

				returnValue = SIGNAL_SHOWCOLOUR_REDCLOSE;/*红灭*/
			}
			else if ((RELAY_STATE_UP == lxRelaySta)
				&& (RELAY_STATE_DOWN == yxRelaySta)
				&& (RELAY_STATE_UP == firDsRelaySta)
				&& (RELAY_STATE_DOWN == secDsRelaySta)
				&& (RELAY_STATE_DOWN == ddRelaySta))
			{/*列车信号继电器吸起、引导信号机落下、1灯丝继电器吸起、2灯丝继电器落下、点灯继电器落下*/

				returnValue = SIGNAL_SHOWCOLOUR_GREEN;/*绿亮*/
			}
			else if ((RELAY_STATE_UP == lxRelaySta)
				&& (RELAY_STATE_DOWN == yxRelaySta)
				&& (RELAY_STATE_DOWN == firDsRelaySta)
				&& (RELAY_STATE_DOWN == secDsRelaySta)
				&& (RELAY_STATE_UP == ddRelaySta))
			{/*列车信号继电器吸起、引导信号机落下、1灯丝继电器落下、2灯丝继电器落下、点灯继电器吸起*/

				returnValue = SIGNAL_SHOWCOLOUR_GREENCLOSE;/*绿灭*/
			}
			else if ((RELAY_STATE_DOWN == lxRelaySta)
				&& (RELAY_STATE_UP == yxRelaySta)
				&& (RELAY_STATE_UP == firDsRelaySta)
				&& (RELAY_STATE_UP == secDsRelaySta)
				&& (RELAY_STATE_DOWN == ddRelaySta))
			{/*列车信号继电器落下、引导信号机吸起、1灯丝继电器吸起、2灯丝继电器吸起、点灯继电器落下*/

				returnValue = SIGNAL_SHOWCOLOUR_REDYELLOW;/*红黄亮*/
			}
			else
			{
				returnValue = SIGNAL_SHOWCOLOUR_INVALID;
			}
		}
		break;
		case SIGNAL_TYPE_THREE_NOYELLOW_NOYINDAO:/*三显示封黄灯无引导（红、绿）*/
		case SIGNAL_TYPE_TWO_ALL_NOYINDAO:/*两显示（红、绿）*/
		{
			if ((RELAY_STATE_DOWN == ddRelaySta)
				&& (RELAY_STATE_DOWN == lxRelaySta)
				&& (RELAY_STATE_UP == firDsRelaySta))
			{/*点灯继电器落下、列车信号继电器落下、1灯丝继电器吸起*/

				returnValue = SIGNAL_SHOWCOLOUR_RED;/*红亮*/
			}
			else if ((RELAY_STATE_UP == ddRelaySta)
				&& (RELAY_STATE_DOWN == lxRelaySta)
				&& (RELAY_STATE_DOWN == firDsRelaySta))
			{/*点灯继电器吸起、列车信号继电器落下、1灯丝继电器落下*/

				returnValue = SIGNAL_SHOWCOLOUR_REDCLOSE;/*红灭*/
			}
			else if ((RELAY_STATE_DOWN == ddRelaySta)
				&& (RELAY_STATE_UP == lxRelaySta)
				&& (RELAY_STATE_UP == firDsRelaySta))
			{/*点灯继电器落下、列车信号继电器吸起、1灯丝继电器吸起*/

				returnValue = SIGNAL_SHOWCOLOUR_GREEN;/*绿亮*/
			}
			else if ((RELAY_STATE_UP == ddRelaySta)
				&& (RELAY_STATE_UP == lxRelaySta)
				&& (RELAY_STATE_DOWN == firDsRelaySta))
			{/*点灯继电器吸起、列车信号继电器吸起、1灯丝继电器落下*/

				returnValue = SIGNAL_SHOWCOLOUR_GREENCLOSE;/*绿灭*/
			}
			else
			{
				returnValue = SIGNAL_SHOWCOLOUR_INVALID;
			}
		}
		break;
		case SIGNAL_TYPE_TWO_NOGREEN_NOYINDAO:/*两显示封绿灯（仅红）*/
			if (RELAY_STATE_UP == firDsRelaySta)
			{/*1灯丝继电器吸起*/

				returnValue = SIGNAL_SHOWCOLOUR_RED;/*红亮*/
			}
			else
			{
				returnValue = SIGNAL_SHOWCOLOUR_INVALID;
			}
			break;
		case SIGNAL_TYPE_DIAOCHE:/*调车信号机（红、白）*/
			if ((RELAY_STATE_DOWN == dxRelaySta)
				&& (RELAY_STATE_UP == firDsRelaySta))
			{/*调车信号继电器落下、1灯丝继电器吸起*/

				returnValue = SIGNAL_SHOWCOLOUR_RED;/*红亮*/
			}
			else if ((RELAY_STATE_UP == dxRelaySta)
				&& (RELAY_STATE_UP == firDsRelaySta))
			{/*调车信号继电器吸起、1灯丝继电器吸起*/

				returnValue = SIGNAL_SHOWCOLOUR_WHITE;/*白亮*/
			}
			else
			{
				returnValue = SIGNAL_SHOWCOLOUR_INVALID;
			}
			break;
		case SIGNAL_TYPE_JINKUCHUKU:/*进库出库信号机*/
		{
			if ((RELAY_STATE_DOWN == dxRelaySta)
				&& (RELAY_STATE_DOWN == lxRelaySta)
				&& (RELAY_STATE_UP == firDsRelaySta))
			{/*调车信号继电器落下、列车信号继电器落下、1灯丝继电器吸起*/

				returnValue = SIGNAL_SHOWCOLOUR_RED;/*红亮*/
			}
			else if ((RELAY_STATE_UP == dxRelaySta)
				&& (RELAY_STATE_DOWN == lxRelaySta)
				&& (RELAY_STATE_UP == firDsRelaySta))
			{/*调车信号继电器吸起、列车信号继电器落下、1灯丝继电器吸起*/

				returnValue = SIGNAL_SHOWCOLOUR_WHITE;/*白亮*/
			}
			else if ((RELAY_STATE_DOWN == dxRelaySta)
				&& (RELAY_STATE_UP == lxRelaySta)
				&& (RELAY_STATE_UP == firDsRelaySta))
			{/*调车信号继电器落下、列车信号继电器吸起、1灯丝继电器吸起*/

				returnValue = SIGNAL_SHOWCOLOUR_YELLOW;/*黄亮*/
			}
			else
			{
				returnValue = SIGNAL_SHOWCOLOUR_INVALID;
			}
		}
		break;

		case SIGNAL_TYPE_TWO_JINKU_RGY:/*进段/进库信号机(三显示),仅亮红灯、亮绿灯和亮红黄灯*/
		{
			if ((RELAY_STATE_UP == lxRelaySta)
				&& (RELAY_STATE_DOWN == yxRelaySta))
			{/*列车信号继电器吸起 && 引导信号继电器落下*/

				returnValue = SIGNAL_SHOWCOLOUR_GREEN;/*绿亮*/
			}
			else if ((RELAY_STATE_DOWN == lxRelaySta)
				&& (RELAY_STATE_UP == yxRelaySta))
			{/*列车信号继电器落下 && 引导信号继电器吸起*/

				returnValue = SIGNAL_SHOWCOLOUR_REDYELLOW;/*红黄灯*/
			}
			else if ((RELAY_STATE_DOWN == lxRelaySta)
				&& (RELAY_STATE_DOWN == yxRelaySta))
			{/*列车信号继电器落下 && 引导信号继电器落下*/

				returnValue = SIGNAL_SHOWCOLOUR_RED;/*红亮*/
			}
			else
			{
				returnValue = SIGNAL_SHOWCOLOUR_INVALID;
			}
		}
		break;
		case SIGNAL_TYPE_3_NOGREEN_YINDAO_NOL:/*道岔防护信号机(三显示，封绿灯，带引导，不能灭灯)*/
		{
			if ((RELAY_STATE_UP == lxRelaySta)
				&& (RELAY_STATE_DOWN == yxRelaySta)
				&& (RELAY_STATE_UP == firDsRelaySta)
				&& (RELAY_STATE_DOWN == secDsRelaySta))
			{/*列车信号继电器吸起 && 引导信号继电器落下 && 1灯丝继电器吸起 && 2灯丝继电器落下*/

				returnValue = SIGNAL_SHOWCOLOUR_YELLOW;/*黄亮*/
			}
			else if ((RELAY_STATE_DOWN == lxRelaySta)
				&& (RELAY_STATE_UP == yxRelaySta)
				&& (RELAY_STATE_UP == firDsRelaySta)
				&& (RELAY_STATE_UP == secDsRelaySta))
			{/*列车信号继电器落下 && 引导信号继电器吸起 && 1灯丝继电器吸起 && 2灯丝继电器吸起*/

				returnValue = SIGNAL_SHOWCOLOUR_REDYELLOW;/*红黄灯*/
			}
			else if ((RELAY_STATE_DOWN == lxRelaySta)
				&& (RELAY_STATE_DOWN == yxRelaySta)
				&& (RELAY_STATE_UP == firDsRelaySta)
				&& (RELAY_STATE_DOWN == secDsRelaySta))
			{/*列车信号继电器落下 && 引导信号继电器落下 && 1灯丝继电器吸起 && 2灯丝继电器落下*/

				returnValue = SIGNAL_SHOWCOLOUR_RED;/*红亮*/
			}
			else
			{
				returnValue = SIGNAL_SHOWCOLOUR_INVALID;
			}
		}
		break;
		case SIGNAL_TYPE_THREE_DIAOCHE_YINDAO:/*进段带引导调车信号机(三显示，可引导红白灯，无灭灯)*/
		{
			if ((RELAY_STATE_DOWN == dxRelaySta)
				&& (RELAY_STATE_DOWN == yxRelaySta)
				&& (RELAY_STATE_UP == firDsRelaySta)
				&& (RELAY_STATE_DOWN == secDsRelaySta))
			{/*调车信号继电器落下、引导信号继电器落下、1灯丝继电器吸起、2灯丝继电器落下*/

				returnValue = SIGNAL_SHOWCOLOUR_RED;/*红亮*/
			}
			else if ((RELAY_STATE_UP == dxRelaySta)
				&& (RELAY_STATE_DOWN == yxRelaySta)
				&& (RELAY_STATE_UP == firDsRelaySta)
				&& (RELAY_STATE_DOWN == secDsRelaySta))
			{/*调车信号继电器吸起、引导信号继电器落下、1灯丝继电器吸起、2灯丝继电器落下*/

				returnValue = SIGNAL_SHOWCOLOUR_WHITE;/*白亮*/
			}
			else if ((RELAY_STATE_DOWN == dxRelaySta)
				&& (RELAY_STATE_UP == yxRelaySta)
				&& (RELAY_STATE_UP == firDsRelaySta)
				&& (RELAY_STATE_UP == secDsRelaySta))
			{/*调车信号继电器落下、引导信号继电器吸起、1灯丝继电器吸起、2灯丝继电器吸起*/

				returnValue = SIGNAL_SHOWCOLOUR_RED_WHITE;/*红白亮*/
			}
			else
			{
				returnValue = SIGNAL_SHOWCOLOUR_INVALID;
			}
		}
		break;
		case SIGNAL_TYPE_THREE_JINKU_YINDAO:  /*进库信号机（三显示带引导）*/  /*新机场车辆段新增信号机类型2019.1.15*/
		{
			if ((RELAY_STATE_UP == lxRelaySta)
				&& (RELAY_STATE_DOWN == dxRelaySta)
				&& (RELAY_STATE_DOWN == yxRelaySta)
				&& (RELAY_STATE_UP == firDsRelaySta)
				&& (RELAY_STATE_DOWN == secDsRelaySta))
			{/*列车信号继电器吸起、调车信号继电器落下、引导信号继电器落下、1灯丝继电器吸起、2灯丝继电器落下*/
				returnValue = SIGNAL_SHOWCOLOUR_YELLOW;/*黄亮*/
			}
			else if ((RELAY_STATE_DOWN == lxRelaySta)
				&& (RELAY_STATE_UP == dxRelaySta)
				&& (RELAY_STATE_DOWN == yxRelaySta)
				&& (RELAY_STATE_UP == firDsRelaySta)
				&& (RELAY_STATE_DOWN == secDsRelaySta))
			{ /*列车信号继电器落下、调车信号继电器吸起、引导信号继电器落下、1灯丝继电器吸起、2灯丝继电器落下*/
				returnValue = SIGNAL_SHOWCOLOUR_WHITE;/*白亮*/
			}
			else if ((RELAY_STATE_DOWN == lxRelaySta)
				&& (RELAY_STATE_DOWN == dxRelaySta)
				&& (RELAY_STATE_DOWN == yxRelaySta)
				&& (RELAY_STATE_UP == firDsRelaySta)
				&& (RELAY_STATE_DOWN == secDsRelaySta))
			{ /*列车信号继电器落下、调车信号继电器落下、引导信号继电器落下、1灯丝继电器吸起、2灯丝继电器落下*/
				returnValue = SIGNAL_SHOWCOLOUR_RED;/*红亮*/
			}
			else if ((RELAY_STATE_DOWN == lxRelaySta)
				&& (RELAY_STATE_DOWN == dxRelaySta)
				&& (RELAY_STATE_UP == yxRelaySta)
				&& (RELAY_STATE_UP == firDsRelaySta)
				&& (RELAY_STATE_UP == secDsRelaySta))
			{/*列车信号继电器落下、调车信号继电器落下、引导信号继电器吸起、1灯丝继电器吸起、2灯丝继电器吸起*/
				returnValue = SIGNAL_SHOWCOLOUR_REDYELLOW;/*红黄灯*/
			}
			else
			{
				returnValue = SIGNAL_SHOWCOLOUR_INVALID;  /*无效继电器组合*/
			}
		}
		break;
		case SIGNAL_TYPE_THREE_JINKU_OFF:/*cgh-合并CID-3037-8：*/
			if ((RELAY_STATE_UP == lxRelaySta)
				&& (RELAY_STATE_DOWN == dxRelaySta)
				&& (RELAY_STATE_DOWN == yxRelaySta)
				&& (RELAY_STATE_UP == firDsRelaySta)
				&& (RELAY_STATE_DOWN == secDsRelaySta)
				&& (RELAY_STATE_DOWN == ddRelaySta))
			{
				returnValue = SIGNAL_SHOWCOLOUR_YELLOW;/*黄亮*/
			}
			else if ((RELAY_STATE_DOWN == lxRelaySta)
				&& (RELAY_STATE_UP == dxRelaySta)
				&& (RELAY_STATE_DOWN == yxRelaySta)
				&& (RELAY_STATE_UP == firDsRelaySta)
				&& (RELAY_STATE_DOWN == secDsRelaySta)
				&& (RELAY_STATE_DOWN == ddRelaySta))
			{
				returnValue = SIGNAL_SHOWCOLOUR_WHITE;/*白亮*/
			}
			else if ((RELAY_STATE_DOWN == lxRelaySta)
				&& (RELAY_STATE_DOWN == dxRelaySta)
				&& (RELAY_STATE_DOWN == yxRelaySta)
				&& (RELAY_STATE_UP == firDsRelaySta)
				&& (RELAY_STATE_DOWN == secDsRelaySta)
				&& (RELAY_STATE_DOWN == ddRelaySta))
			{
				returnValue = SIGNAL_SHOWCOLOUR_RED;/*红亮*/
			}
			else if ((RELAY_STATE_DOWN == lxRelaySta)
				&& (RELAY_STATE_DOWN == dxRelaySta)
				&& (RELAY_STATE_UP == yxRelaySta)
				&& (RELAY_STATE_UP == firDsRelaySta)
				&& (RELAY_STATE_UP == secDsRelaySta)
				&& (RELAY_STATE_DOWN == ddRelaySta))
			{
				returnValue = SIGNAL_SHOWCOLOUR_REDYELLOW;/*红黄灯*/
			}
			else if ((RELAY_STATE_DOWN == lxRelaySta)
				&& (RELAY_STATE_DOWN == dxRelaySta)
				&& (RELAY_STATE_DOWN == yxRelaySta)
				&& (RELAY_STATE_DOWN == firDsRelaySta)
				&& (RELAY_STATE_DOWN == secDsRelaySta)
				&& (RELAY_STATE_UP == ddRelaySta))
			{
				returnValue = SIGNAL_SHOWCOLOUR_REDCLOSE;/*红灭*/
			}
			else if ((RELAY_STATE_UP == lxRelaySta)
				&& (RELAY_STATE_DOWN == dxRelaySta)
				&& (RELAY_STATE_DOWN == yxRelaySta)
				&& (RELAY_STATE_DOWN == firDsRelaySta)
				&& (RELAY_STATE_DOWN == secDsRelaySta)
				&& (RELAY_STATE_UP == ddRelaySta))
			{
				returnValue = SIGNAL_SHOWCOLOUR_YELLOWCLOSE;/*黄灭*/
			}
			else
			{
				returnValue = SIGNAL_SHOWCOLOUR_INVALID;  /*无效继电器组合*/
			}
			break;
		default:
			returnValue = SIGNAL_SHOWCOLOUR_INVALID;
			break;
		}


	}
	/* 灯丝继电器未配置，则特殊处理 认为是联络线的的信号机，没有灯丝检查 */
	if (firDsRelayId == 0u)
	{
		returnValue = GetRelayToDeviceSignalColor(signalId);
	}

	return returnValue;
}


/******************************道岔相关继电器处理****************************/

/*
* 功能描述： 更新道岔逻辑状态
* 参数说明： const UINT32 curCycleNum, 当前周期号
* 返回值  ： 0u: 更新失败
*			 1: 更新成功
*/
void SwitchRelayToDeviceStateProc(void)
{
	UINT16 switchCurSum = 0u;	  /*道岔总数目*/
	UINT8 localCiId = 0u;         /*本地联锁ID*/
	UINT16 switchId = 0u;	      /*道岔ID*/
	UINT8 belongCiId = 0u;        /*道岔所属联锁ID*/
	UINT16 DbRelayId = 0u;        /*道岔定表继电器ID*/
	UINT16 FbRelayId = 0u;        /*道岔反表继电器ID*/
	UINT16 YcRelayId = 0u;        /*道岔允操继电器ID*/
	UINT16 DcRelayId = 0u;        /*道岔定操继电器ID*/
	UINT16 FcRelayId = 0u;        /*道岔反操继电器ID*/
	UINT16 ZDbRelayId = 0u;       /*道岔总定表继电器ID*/
	UINT16 ZFbRelayId = 0u;       /*道岔总反表继电器ID*/
	UINT16 DFHRelayId = 0u;		  /*道岔DFH继电器*/
	UINT8 YcRelayState = 0u;      /*道岔允操继电器状态*/
	UINT8 DbRelayState = 0u;      /*道岔定表继电器状态*/
	UINT8 FbRelayState = 0u;      /*道岔反表继电器状态*/
	UINT8 ZDbRelayState = 0u;     /*道岔总定表继电器状态*/
	UINT8 ZFbRelayState = 0u;     /*道岔总反表继电器状态*/
	UINT8 DFHRelayState = 0u;     /*道岔定反后继电器状态*/
	UINT16 ii = 0u;               /*循环索引*/
	UINT32 DfhRelayCycNum = 0u;    /*定反后继电器吸起有效周期号*/
	UINT32 YcRelayCycNum = 0u;      /*允操继电器吸起有效周期号*/
	UINT32 SigleYcRelayCycNum = 0u;      /*单独允操继电器吸起有效周期号*/
	UINT32 curCycNum = 0u;
	UINT32 DfhRelayValidMaxTimeCount = 0u;    /*定反后继电器吸起有效周期容忍最大值*/

	UINT8 checkRes = CI_TIME_OUT;
	UINT8 tmpRet = CI_ERROR;
	UINT8 curSwitchPos = SWITCH_POSITION_INVALID;		/*道岔当前位置*/
	UINT8 drvSwitchPos = SWITCH_DRIVE_POS_INVALID;	/*当前驱动道岔位置*/
	UINT8 SwitchDanCaoPos = SWITCH_POSITION_INVALID;	/*道岔单操位置*/
	UINT8 chTiocSysMode = 0U;
	UINT8 timeState = CI_TIME_NO;						    /*驱动道岔超时状态*/
	UINT8 chDsnLinSwitch = 0U;

	chDsnLinSwitch = GetCiFunctionSwitchConfig(FUNC_DSN_LINE_SWITCH);
	DfhRelayValidMaxTimeCount = GetDHFRelayValidTimeCount();/*获取定反后继电器吸起有效周期容忍最大值*/
	switchCurSum = GetSwitchCurSum();					    /*获取道岔总数*/
	localCiId = GetSystemParaLocalCiId();       		    /*获取本机联锁ID*/
	curCycNum = Get2oo2CurCycleNum();                       /*获取当前周期数*/

	if (FUNC_SWITCH_ON == chDsnLinSwitch)
	{
		chTiocSysMode = GetTiocSystemMode();
	}
	/*处理道岔*/
	for (ii = 0u; ii < switchCurSum; ii++)
	{
		switchId = 0u;	      /*道岔ID*/
		belongCiId = 0u;       /*道岔所属联锁ID*/
		DbRelayId = 0u;        /*道岔定表继电器ID*/
		FbRelayId = 0u;        /*道岔反表继电器ID*/
		YcRelayId = 0u;        /*道岔允操继电器ID*/
		DcRelayId = 0u;        /*道岔定操继电器ID*/
		FcRelayId = 0u;        /*道岔反操继电器ID*/
		ZDbRelayId = 0u;       /*道岔总定表继电器ID*/
		ZFbRelayId = 0u;       /*道岔总反表继电器ID*/
		DFHRelayId = 0u;       /*道岔定反后继电器ID*/
		YcRelayState = 0u;     /*道岔允操继电器状态*/
		DbRelayState = 0u;     /*道岔定表继电器状态*/
		FbRelayState = 0u;     /*道岔反表继电器状态*/
		ZDbRelayState = 0u;    /*道岔总定表继电器状态*/
		ZFbRelayState = 0u;    /*道岔总反表继电器状态*/
		DFHRelayState = 0u;    /*道岔定反后继电器状态*/

		switchId = GetSwitchId(ii);                      /*获取道岔ID*/

		if ((0u != switchId) && (switchId < SWITCH_SUM_MAX))
		{
			belongCiId = GetSwitchBelongCiId(switchId); 	 /*获取道岔所属联锁ID*/

			if ((belongCiId == localCiId) && (0u != localCiId))
			{
				DbRelayId = GetSwitchDbRelayId(switchId);  /*获取道岔定位表示继电器ID*/
				FbRelayId = GetSwitchFbRelayId(switchId);  /*获取道岔反位表示继电器ID*/
				YcRelayId = GetSwitchYcRelayId(switchId);  /*获取道岔允操继电器ID*/
				DcRelayId = GetSwitchDcRelayId(switchId);  /*获取道岔定操继电器ID*/
				FcRelayId = GetSwitchFcRelayId(switchId);  /*获取道岔反操继电器ID*/
				ZDbRelayId = GetSwitchZDbRelayId(switchId);  /*获取道岔总定位表示继电器ID*/
				ZFbRelayId = GetSwitchZFbRelayId(switchId);  /*获取道岔总反位表示继电器ID*/
				DFHRelayId = GetSwitchDFHRelayId(switchId);	 /*获取道岔DFH继电器ID*/

				if (REVERSE_MODE_SHADOW == chTiocSysMode)
				{
					/*影子模式下使用影子模式继电器*/
					DbRelayId = GetSwitchShadowDbRelayId(switchId);
					FbRelayId = GetSwitchShadowFbRelayId(switchId);
					ZDbRelayId = DbRelayId;
					ZFbRelayId = FbRelayId;
					DFHRelayId = 0u;
				}
				/*更新道岔位置*/
				YcRelayState = GetRelayCollState(YcRelayId);    /*道岔允操继电器状态*/
				DbRelayState = GetRelayCollState(DbRelayId);    /*道岔定表继电器状态*/
				FbRelayState = GetRelayCollState(FbRelayId);    /*道岔反表继电器状态*/
				ZDbRelayState = GetRelayCollState(ZDbRelayId);  /*道岔总定表继电器状态*/
				ZFbRelayState = GetRelayCollState(ZFbRelayId);  /*道岔总反表继电器状态*/
				DFHRelayState = GetRelayCollState(DFHRelayId);  /*道岔定反后继电器状态*/
				/*设置道岔当前位置和移动周期*/

				if (ZDbRelayState == ZFbRelayState)
				{/*道岔失表示*/
					if (RELAY_STATE_UP == ZDbRelayState)
					{/*总定表反表继电器均吸起为四开*/
						SetSwitchCurPosition(switchId, SWITCH_POSITION_SIKAI);
						tmpRet = SetSwitchYCRelayValidCycNum(switchId, 0u);	/*清除YC继电器有效起始周期号*/
						if (CI_ERROR == tmpRet)
						{
							/*错误处理*/
						}
					}
					else
					{
						/*道岔允操继电器ID不为0u*/
						if (0u != YcRelayId)
						{
							YcRelayCycNum = GetSwitchYCRelayValidCycNum(switchId);        /*YC继电器状态吸起更新周期*/

							if (RELAY_STATE_UP == YcRelayState)
							{/*允操吸起*/
								tmpRet = SetSwitchYCRelayValidCycNum(switchId, 0u);	/*清除YC继电器有效起始周期号*/
								if (CI_ERROR == tmpRet)
								{
									/*错误处理*/
								}
								if ((RELAY_STATE_DOWN == ZDbRelayState) && (RELAY_STATE_DOWN == ZFbRelayState))
								{/*道岔移动中*/
									SetSwitchCurPosition(switchId, SWITCH_POSITION_MOVE);/*设置道岔当前位置为移动*/
									tmpRet = SetSwitchDFHRelayValidCycNum(switchId, 0u);	/*清除DHF继电器有效起始周期号*/
									if (CI_ERROR == tmpRet)
									{
										/*错误处理*/
									}
								}
								else
								{
									SetSwitchCurPosition(switchId, SWITCH_POSITION_SIKAI);/*设置道岔位置为四开*/
								}
							}
							else
							{
								if (0u == YcRelayCycNum)
								{/*若未计时，则设置起始周期*/
									tmpRet = SetSwitchYCRelayValidCycNum(switchId, curCycNum);
									if (CI_ERROR == tmpRet)
									{
										/*错误处理*/
									}
									else
									{
										YcRelayCycNum = GetSwitchYCRelayValidCycNum(switchId);        /*YC继电器状态吸起更新周期*/
									}
								}
								checkRes = SystemOverTimeCheck(YcRelayCycNum, DfhRelayValidMaxTimeCount);
								if (CI_TIME_OUT == checkRes)
								{ /*安全值*/
									SetSwitchCurPosition(switchId, SWITCH_POSITION_SIKAI);/*设置道岔四开*/
								}
							}
						}
						else
						{
							SetSwitchCurPosition(switchId, SWITCH_POSITION_SIKAI);/*设置道岔位置为四开*/
						}
					}
				}
				else
				{/*道岔表示有效*/
					tmpRet = SetSwitchYCRelayValidCycNum(switchId, 0u);	/*清除YC继电器有效起始周期号*/
					if (CI_ERROR == tmpRet)
					{
						/*错误处理*/
					}
					if ((0u == DFHRelayId) || (UINT16_MAX == DFHRelayId))
					{/*DFH继电器无效,则不判断DFH继电器的状态*/
						if ((RELAY_STATE_UP == ZDbRelayState)
							&& (RELAY_STATE_DOWN == ZFbRelayState))
						{/*总定表吸起、总反表落下*/
							SetSwitchCurPosition(switchId, SWITCH_POSITION_DINGWEI);/*设置道岔定位*/

							if (SWITCH_DRIVE_POS_DINGWEI == GetSwitchDrivePostion(switchId))
							{/*道岔已经移动到位*/
								(void)SetRelayDriveState(YcRelayId, RELAY_STATE_DOWN);/*设置允操继电器落下*/
								(void)SetRelayDriveState(DcRelayId, RELAY_STATE_DOWN);/*设置定操继电器落下*/
								(void)SetRelayDriveState(FcRelayId, RELAY_STATE_DOWN);/*设置反操继电器落下*/
							}
						}
						else if ((RELAY_STATE_UP == ZFbRelayState)
							&& (RELAY_STATE_DOWN == ZDbRelayState))
						{/*总反表吸起、总定表落下*/
							SetSwitchCurPosition(switchId, SWITCH_POSITION_FANWEI);/*设置道岔反位*/

							drvSwitchPos = GetSwitchDrivePostion(switchId);
							if (SWITCH_DRIVE_POS_FANWEI == drvSwitchPos)
							{/*道岔已经移动到位*/
								(void)SetRelayDriveState(YcRelayId, RELAY_STATE_DOWN);/*设置允操继电器落下*/
								(void)SetRelayDriveState(DcRelayId, RELAY_STATE_DOWN);/*设置定操继电器落下*/
								(void)SetRelayDriveState(FcRelayId, RELAY_STATE_DOWN);/*设置反操继电器落下*/
							}
						}
						else
						{/*无此种情况*/

							/*安全值*/
							SetSwitchCurPosition(switchId, SWITCH_POSITION_SIKAI);/*设置道岔四开*/
						}
					}
					else
					{
						DfhRelayCycNum = GetSwitchDFHRelayValidCycNum(switchId);        /*DFH继电器状态吸起更新周期*/

						if (RELAY_STATE_UP == DFHRelayState)
						{
							if (0u == DfhRelayCycNum)
							{/*若未计时，则设置起始周期*/
								tmpRet = SetSwitchDFHRelayValidCycNum(switchId, curCycNum);
								if (CI_ERROR == tmpRet)
								{
									/*错误处理*/
								}
								else
								{
									DfhRelayCycNum = GetSwitchDFHRelayValidCycNum(switchId);        /*DFH继电器状态吸起更新周期*/
								}
							}
							checkRes = SystemOverTimeCheck(DfhRelayCycNum, DfhRelayValidMaxTimeCount);
							if (CI_TIME_OUT == checkRes)
							{ /*安全值*/
								SetSwitchCurPosition(switchId, SWITCH_POSITION_SIKAI);/*设置道岔四开*/
							}
						}
						else if (RELAY_STATE_DOWN == DFHRelayState)
						{/*检查DFH继电器为落下状态*/
							tmpRet = SetSwitchDFHRelayValidCycNum(switchId, 0u);	/*清除DHF继电器有效起始周期号*/
							if (CI_ERROR == tmpRet)
							{
								/*错误处理*/
							}
							else
							{
								if ((RELAY_STATE_UP == ZDbRelayState)
									&& (RELAY_STATE_DOWN == ZFbRelayState))
								{/*总定表吸起、总反表落下、DFH落下*/
									SetSwitchCurPosition(switchId, SWITCH_POSITION_DINGWEI);/*设置道岔定位*/

									drvSwitchPos = GetSwitchDrivePostion(switchId);
									if (SWITCH_DRIVE_POS_DINGWEI == drvSwitchPos)
									{/*道岔已经移动到位*/
										(void)SetRelayDriveState(YcRelayId, RELAY_STATE_DOWN);/*设置允操继电器落下*/
										(void)SetRelayDriveState(DcRelayId, RELAY_STATE_DOWN);/*设置定操继电器落下*/
										(void)SetRelayDriveState(FcRelayId, RELAY_STATE_DOWN);/*设置反操继电器落下*/
									}
								}
								else if ((RELAY_STATE_UP == ZFbRelayState)
									&& (RELAY_STATE_DOWN == ZDbRelayState))
								{/*总反表吸起、总定表落下、DFH落下*/
									SetSwitchCurPosition(switchId, SWITCH_POSITION_FANWEI);/*设置道岔反位*/

									drvSwitchPos = GetSwitchDrivePostion(switchId);
									if (SWITCH_DRIVE_POS_FANWEI == drvSwitchPos)
									{/*道岔已经移动到位*/
										(void)SetRelayDriveState(YcRelayId, RELAY_STATE_DOWN);/*设置允操继电器落下*/
										(void)SetRelayDriveState(DcRelayId, RELAY_STATE_DOWN);/*设置定操继电器落下*/
										(void)SetRelayDriveState(FcRelayId, RELAY_STATE_DOWN);/*设置反操继电器落下*/
									}
								}
								else
								{/*无此种情况*/
									/*安全值*/
									SetSwitchCurPosition(switchId, SWITCH_POSITION_SIKAI);/*设置道岔四开*/
								}
							}
						}
						else
						{
							/*安全值*/
							SetSwitchCurPosition(switchId, SWITCH_POSITION_SIKAI);/*设置道岔四开*/
						}
					}
				}

				/*更新单独道岔位置*/

				/*设置道岔当前位置和移动周期*/
				if (DbRelayState == FbRelayState)
				{/*道岔失表示*/
					if (RELAY_STATE_UP == DbRelayState)
					{/*定表反表继电器均吸起为四开*/
						SetSingleSwitchCurPosition(switchId, SWITCH_POSITION_SIKAI);
						tmpRet = SetSingleSwitchYCRelayValCyc(switchId, 0u);	/*清除YC继电器有效起始周期号*/
						if (CI_ERROR == tmpRet)
						{
							/*错误处理*/
						}
					}
					else
					{
						/*道岔允操继电器存在*/
						if (0u != YcRelayId)
						{
							SigleYcRelayCycNum = GetSingleSwitchYCRelayValCyc(switchId);        /*YC继电器状态吸起更新周期*/

							if (RELAY_STATE_UP == YcRelayState)
							{/*允操吸起*/
								tmpRet = SetSingleSwitchYCRelayValCyc(switchId, 0u);	/*清除YC继电器有效起始周期号*/
								if (CI_ERROR == tmpRet)
								{
									/*错误处理*/
								}
								SetSingleSwitchCurPosition(switchId, SWITCH_POSITION_MOVE);/*设置道岔当前位置为移动*/
								tmpRet = SetSigleSwitchDFHRelayValCyc(switchId, 0u);	/*清除DHF继电器有效起始周期号*/
								if (CI_ERROR == tmpRet)
								{
									/*错误处理*/
								}
							}
							else
							{/*道岔不是移动状态*/
								if (0u == SigleYcRelayCycNum)
								{/*若未计时，则设置起始周期*/
									tmpRet = SetSingleSwitchYCRelayValCyc(switchId, curCycNum);
									if (CI_ERROR == tmpRet)
									{
										/*错误处理*/
									}
									else
									{
										SigleYcRelayCycNum = GetSingleSwitchYCRelayValCyc(switchId);        /*YC继电器状态吸起更新周期*/
									}
								}
								checkRes = SystemOverTimeCheck(SigleYcRelayCycNum, DfhRelayValidMaxTimeCount);
								if (CI_TIME_OUT == checkRes)
								{ /*安全值*/
									SetSingleSwitchCurPosition(switchId, SWITCH_POSITION_SIKAI);/*设置道岔当前位置为四开*/
								}
							}
						}
						else
						{
							SetSingleSwitchCurPosition(switchId, SWITCH_POSITION_SIKAI);/*设置道岔当前位置为四开*/
						}
					}
				}
				else
				{/*道岔表示有效*/
					tmpRet = SetSingleSwitchYCRelayValCyc(switchId, 0u);	/*清除YC继电器有效起始周期号*/
					if (CI_ERROR == tmpRet)
					{
						/*错误处理*/
					}

					if (RELAY_STATE_UP == DbRelayState)
					{/*定表继电器吸起*/
						SetSingleSwitchCurPosition(switchId, SWITCH_POSITION_DINGWEI);/*设置道岔定位*/
					}
					else if (RELAY_STATE_UP == FbRelayState)
					{/*反表继电器吸起*/
						SetSingleSwitchCurPosition(switchId, SWITCH_POSITION_FANWEI);/*设置道岔反位*/
					}
					else
					{/*无此种情况*/

						/*安全值*/
						SetSingleSwitchCurPosition(switchId, SWITCH_POSITION_SIKAI);/*设置道岔四开*/
					}
				}
				/*以下一段代码是为了检查单操道岔是否已驱动超时*/

				/*检查驱动道岔时间是否已经超时*/
				timeState = SystemOverTimeCheck(GetSwitchDriveStartCycNum(switchId), GetSystemParaSwitchDriveCyc());

				if (CI_TIME_OUT == timeState)
				{/*驱动道岔时间超时*/

					/*获得当前道岔驱动位置*/
					drvSwitchPos = GetSwitchDrivePostion(switchId);

					/*获取道岔单操位置*/
					SwitchDanCaoPos = GetSwitchDanCaoPostition(switchId);

					if (((SWITCH_DRIVE_POS_DINGWEI == drvSwitchPos) && (SWITCH_POSITION_DINGWEI == SwitchDanCaoPos)) ||
						((SWITCH_DRIVE_POS_FANWEI == drvSwitchPos) && (SWITCH_POSITION_FANWEI == SwitchDanCaoPos)))
					{
						/*清除单操有效位置*/
						(void)SetSwitchDanCaoPosition(switchId, SWITCH_POSITION_INVALID);
					}

					/*设置道岔驱动超时位置*/
					SetSwitchDrivOvtmDrvPosition(switchId, drvSwitchPos);
					SetSwitchPreExpDrvPosition(switchId, SWITCH_DRIVE_POS_INVALID);/*清除道岔之前期望驱动位置*/
					SetSwitchDrivePostion(switchId, SWITCH_DRIVE_POS_INVALID);/*清除道岔实际驱动位置*/
				}

				/*以下一段代码是为了检查单操道岔是否已驱动到位*/

				/*再次获取道岔单操位置*/
				SwitchDanCaoPos = GetSwitchDanCaoPostition(switchId);

				/*获取道岔当前位置*/
				curSwitchPos = GetSwitchCurPosition(switchId);

				if ((SwitchDanCaoPos == curSwitchPos) && (SWITCH_POSITION_INVALID != SwitchDanCaoPos))
				{/*道岔驱动到位*/
					/*清除单操有效位置*/
					(void)SetSwitchDanCaoPosition(switchId, SWITCH_POSITION_INVALID);
				}
			}
		}
	}/*for*/
}

/* zt 删除单轨相关代码 2022-02-15 */
/*
* 功能描述： 驱动指定道岔ID继电器
* 参数说明： void
* 返回值  ： 无
*/
static void DriveSwitchRelayState(const UINT16 switchId, const UINT8 driveSwitchPos)
{
	UINT8 curSwitchPos = SWITCH_POSITION_INVALID;		/*道岔当前位置*/
	if (driveSwitchPos == SWITCH_DRIVE_POS_DINGWEI)
	{/*驱动定位*/
		/*设置道岔最近一次的有效驱动位置和起始周期*/
		(void)SetSwitchLastValidDrvPos(switchId, driveSwitchPos);
		(void)SetSwitchLastValidPosDrivCycNum(switchId, Get2oo2CurCycleNum());
		(void)SetRelayDriveState(GetSwitchYcRelayId(switchId), RELAY_STATE_UP);/*设置允操继电器吸起*/
		(void)SetRelayDriveState(GetSwitchDcRelayId(switchId), RELAY_STATE_UP);/*设置定操继电器吸起*/
		(void)SetRelayDriveState(GetSwitchFcRelayId(switchId), RELAY_STATE_DOWN);/*设置反操继电器落下*/
	}
	else if (driveSwitchPos == SWITCH_DRIVE_POS_FANWEI)
	{/*驱动反位*/
		/*设置道岔最近一次的有效驱动位置和起始周期*/
		(void)SetSwitchLastValidDrvPos(switchId, driveSwitchPos);
		(void)SetSwitchLastValidPosDrivCycNum(switchId, Get2oo2CurCycleNum());
		(void)SetRelayDriveState(GetSwitchYcRelayId(switchId), RELAY_STATE_UP);/*设置允操继电器吸起*/
		(void)SetRelayDriveState(GetSwitchDcRelayId(switchId), RELAY_STATE_DOWN);/*设置定操继电器落下*/
		(void)SetRelayDriveState(GetSwitchFcRelayId(switchId), RELAY_STATE_UP);/*设置反操继电器吸起*/
	}
	else if (driveSwitchPos == SWITCH_DRIVE_POS_INVALID)
	{
		/*道岔当前位置*/
		curSwitchPos = GetSwitchCurPosition(switchId);

		if (curSwitchPos == SWITCH_POSITION_JICHA)
		{/*道岔挤岔*/
			(void)SetRelayDriveState(GetSwitchYcRelayId(switchId), RELAY_STATE_DOWN);/*设置允操继电器落下*/
			(void)SetRelayDriveState(GetSwitchDcRelayId(switchId), RELAY_STATE_DOWN);/*设置定操继电器落下*/
			(void)SetRelayDriveState(GetSwitchFcRelayId(switchId), RELAY_STATE_DOWN);/*设置反操继电器落下*/
		}
		else
		{
			/*保持继电器状态*/
		}
	}
	else
	{
		/*无此情况*/
		(void)SetRelayDriveState(GetSwitchYcRelayId(switchId), RELAY_STATE_DOWN);/*设置允操继电器落下*/
		(void)SetRelayDriveState(GetSwitchDcRelayId(switchId), RELAY_STATE_DOWN);/*设置定操继电器落下*/
		(void)SetRelayDriveState(GetSwitchFcRelayId(switchId), RELAY_STATE_DOWN);/*设置反操继电器落下*/
	}
}
/*
* 功能描述： 更新道岔继电器状态
* 参数说明： void
* 返回值  ： 0u: 更新失败
*			 1: 更新成功
*/
void SwitchDeviceToRelayStateProc(void)
{
	UINT16 switchCurSum = 0u;	 /*道岔总数目*/
	UINT8 localCiId = 0u;         /*本地联锁ID*/

	UINT16 switchId = 0u;	     /*道岔ID*/
	UINT8 belongCiId = 0u;        /*道岔所属联锁ID*/
	UINT16 ii = 0u;               /*循环索引*/

	UINT8 curSwitchPos = SWITCH_POSITION_INVALID;		/*道岔当前位置*/
	UINT8 driveSwitchPos = SWITCH_DRIVE_POS_INVALID;	/*驱动道岔位置*/
	UINT8 curExpDrvSwitchPos = SWITCH_DRIVE_POS_INVALID;	/*本周期期望驱动道岔位置*/
	UINT8 preExpDrvSwitchPos = SWITCH_DRIVE_POS_INVALID;	/*上周期期望驱动道岔位置*/

	UINT8 timeState = CI_TIME_NO;						/*驱动道岔超时状态*/

	UINT8 switDrivPeakTimeState = SWIT_DRIV_PEAK_TIME_FALSE;	/*道岔驱动高峰期状态*/

	UINT8 preSwitchDrivingState = SWIT_DRIV_IDLE_TIME;	/*之前的道岔驱动状态*/
	UINT8 curSwitchDrivingState = SWIT_DRIV_IDLE_TIME;	/*当前的道岔驱动状态*/

	UINT8 SwitchDanCaoPosition = SWITCH_POSITION_INVALID;/*道岔单操位置*/
	UINT8 lineIdentity = GetCiFunctionSwitchConfig(LINE_RAILWAY_TYPE_CONF);/*获取线路标识:0x55:城轨交通；0xAA:单轨交通*/
	UINT8 chSwitchJichaState = 0U;/*道岔挤岔状态*/

	switchCurSum = GetSwitchCurSum();					/*获取道岔总数*/
	localCiId = GetSystemParaLocalCiId();				/*获取本机联锁ID*/

	/*单操道岔逻辑处理*/
	for (ii = 0u; ii < switchCurSum; ii++)
	{
		switchId = GetSwitchId(ii); 					 /*获取道岔ID*/

		if ((0u < switchId) && (switchId < SWITCH_SUM_MAX))
		{
			belongCiId = GetSwitchBelongCiId(switchId); 	 /*获取道岔所属联锁ID*/

			if ((belongCiId == localCiId) && (0u != localCiId))
			{
				SwitchDanCaoPosition = GetSwitchDanCaoPostition(switchId);

				if (SwitchDanCaoPosition == SWITCH_POSITION_DINGWEI)
				{/*道岔驱动到定位*/
					(void)SetSwitchExpDrvPosition(switchId, SWITCH_DRIVE_POS_DINGWEI);
				}
				else if (SwitchDanCaoPosition == SWITCH_POSITION_FANWEI)
				{/*道岔驱动到反位*/
					(void)SetSwitchExpDrvPosition(switchId, SWITCH_DRIVE_POS_FANWEI);
				}/* zt 删除单轨相关代码 2022-02-15 */
				else
				{
					/*什么也不做*/
				}
			}
		}
	}/*for*/

	/*道岔期望驱动位置处理*/
	for (ii = 0u; ii < switchCurSum; ii++)
	{
		switchId = GetSwitchId(ii); 					 /*获取道岔ID*/

		if ((0u < switchId) && (switchId < SWITCH_SUM_MAX))
		{
			belongCiId = GetSwitchBelongCiId(switchId); 	 /*获取道岔所属联锁ID*/

			if ((belongCiId == localCiId) && (0u != localCiId))
			{
				curSwitchPos = GetSwitchCurPosition(switchId);/*获取道岔当前位置*/

				curExpDrvSwitchPos = GetSwitchExpDrvPosition(switchId);/*获取当前期望驱动的位置*/

				/* zt 删除单轨相关代码 2022-02-15 */
				if (((curSwitchPos == SWITCH_POSITION_DINGWEI) && (curExpDrvSwitchPos == SWITCH_DRIVE_POS_DINGWEI))
					|| ((curSwitchPos == SWITCH_POSITION_FANWEI) && (curExpDrvSwitchPos == SWITCH_DRIVE_POS_FANWEI)))
				{/*道岔驱动到位或集中控制时采集到JTYJa 吸起或GZJ落下或驱动TYJ吸起*/
					(void)SetSwitchExpDrvPosition(switchId, SWITCH_DRIVE_POS_INVALID);/*既然已驱动到位,可设置期望驱动位置为无效*/
				}
			}
		}

	}/*for*/

	/*道岔驱动状态更新*/
	for (ii = 0u; ii < switchCurSum; ii++)
	{
		switchId = GetSwitchId(ii);							/*获取道岔ID*/

		if ((0u < switchId) && (switchId < SWITCH_SUM_MAX))
		{
			belongCiId = GetSwitchBelongCiId(switchId);		/*获取道岔所属联锁ID*/

			if ((belongCiId == localCiId) && (0u != localCiId))
			{

				curExpDrvSwitchPos = GetSwitchExpDrvPosition(switchId);/*获取当前期望驱动的位置*/

				preExpDrvSwitchPos = GetSwitchPreExpDrvPosition(switchId);/*获取之前期望驱动的位置*/

				preSwitchDrivingState = GetSwitchDrivingState(switchId);/*获取之前的实际驱动状态*/

				if (SWITCH_DRIVE_POS_INVALID == curExpDrvSwitchPos)
				{/*当前期望驱动位置无效*/
					SetSwitchDrivingState(switchId, SWIT_DRIV_IDLE_TIME);/*设置道岔驱动状态为空闲*/
				}
				else
				{/*当前期望驱动位置有效*/
					if (curExpDrvSwitchPos == preExpDrvSwitchPos)
					{/*检查道岔移动是否已经超时*//* zt 删除单轨相关代码 2022-02-15 */
						if (CI_TRADITION_RAILWAY == lineIdentity)
						{  /*城市交通*/
							timeState = SystemOverTimeCheck(GetSwitchMoveStartCycNum(switchId), GetSystemParaSwDrvCuoFengCnt());
						}
						else
						{

						}

						if (CI_TIME_NO == timeState)
						{/*道岔尚未被驱动*/
							if (SWIT_DRIV_IDLE_TIME == preSwitchDrivingState)
							{/*之前的道岔驱动状态为空闲*/
								SetSwitchDrivingState(switchId, SWIT_DRIV_WAIT_TIME);/*道岔需要被驱动,尚未开始动作,一般情况下,之前道岔驱动状态为空闲状态,故设置道岔驱动状态为等待*/
							}
							else if (SWIT_DRIV_PEAK_TIME == preSwitchDrivingState)
							{/*之前的道岔驱动状态为高峰*/
								SetSwitchDrivingState(switchId, SWIT_DRIV_PEAK_TIME);/*道岔需要被驱动,尚未开始动作,某些情况下,之前道岔驱动状态已为高峰状态,故依然设置道岔驱动状态为高峰*/

								switDrivPeakTimeState = SWIT_DRIV_PEAK_TIME_TRUE;/*设置道岔驱动高峰期状态为TRUE,表示需要驱动的道岔当中已有道岔处于驱动高峰状态*/
							}
							else
							{
								/*无操作*/
							}
						}
						else if (CI_TIME_IN == timeState)
						{/*道岔被驱动,正处于错峰期*/
							SetSwitchDrivingState(switchId, SWIT_DRIV_PEAK_TIME);/*道岔需要被驱动,已开始动作,无论之前道岔驱动状态如何,均设置道岔驱动状态为高峰*/

							switDrivPeakTimeState = SWIT_DRIV_PEAK_TIME_TRUE;/*设置道岔驱动高峰期状态为TRUE,表示需要驱动的道岔当中已有道岔处于驱动高峰状态*/
						}
						else if (CI_TIME_OUT == timeState)
						{/*道岔被驱动,已度过错峰期*/
							SetSwitchDrivingState(switchId, SWIT_DRIV_FLAT_TIME);/*道岔需要被驱动,已开始动作并超时,无论之前道岔驱动状态如何,均设置道岔驱动状态为平缓*/
						}
						else
						{
							/*什么也不做*/
						}
					}
					else
					{
						SetSwitchDrivingState(switchId, SWIT_DRIV_WAIT_TIME);/*设置道岔驱动状态为等待*/
					}
				}
			}
		}
	}/*for*/

	/*错峰驱动道岔逻辑处理*/
	for (ii = 0u; ii < switchCurSum; ii++)
	{
		switchId = GetSwitchId(ii); 					 /*获取道岔ID*/

		if ((0u < switchId) && (switchId < SWITCH_SUM_MAX))
		{
			belongCiId = GetSwitchBelongCiId(switchId); 	 /*获取道岔所属联锁ID*/

			if ((belongCiId == localCiId) && (0u != localCiId))
			{
				curExpDrvSwitchPos = GetSwitchExpDrvPosition(switchId);

				curSwitchDrivingState = GetSwitchDrivingState(switchId);

				/*道岔驱动状态处理*/
				if (SWIT_DRIV_IDLE_TIME == curSwitchDrivingState)
				{/*道岔驱动状态为空闲*/
					/*清除当前驱动状态*/
					SetSwitchDrivePostion(switchId, SWITCH_DRIVE_POS_INVALID);
				}
				else if (SWIT_DRIV_WAIT_TIME == curSwitchDrivingState)
				{/*道岔驱动状态为等待*/
					if (SWIT_DRIV_PEAK_TIME_FALSE == switDrivPeakTimeState)
					{/*当前没有道岔处于驱动高峰状态*/
						SetSwitchDrivePostion(switchId, curExpDrvSwitchPos);/*因为没有其他道岔处于驱动高峰状态,开始驱动道岔*/

						SetSwitchDrivingState(switchId, SWIT_DRIV_PEAK_TIME);/*开始驱动道岔,因此设置道岔为驱动高峰状态*/

						switDrivPeakTimeState = SWIT_DRIV_PEAK_TIME_TRUE;/*设置道岔驱动高峰期状态为TRUE,表示需要驱动的道岔当中已有道岔处于驱动高峰状态*/
					}
					else
					{
						SetSwitchDrivePostion(switchId, SWITCH_DRIVE_POS_INVALID);
					}
				}
				else if (SWIT_DRIV_PEAK_TIME == curSwitchDrivingState)
				{/*道岔驱动状态为高峰*/
					SetSwitchDrivePostion(switchId, curExpDrvSwitchPos);

					switDrivPeakTimeState = SWIT_DRIV_PEAK_TIME_TRUE;/*设置道岔驱动高峰期状态为TRUE,表示需要驱动的道岔当中已有道岔处于驱动高峰状态*/
				}
				else if (SWIT_DRIV_FLAT_TIME == curSwitchDrivingState)
				{/*道岔驱动状态为平缓*/
					SetSwitchDrivePostion(switchId, curExpDrvSwitchPos);/*驱动平缓状态下继续驱动道岔*/
				}
				else
				{
					/*什么也不做*/
				}
			}
		}
	}/*for*/

	/*驱动道岔继电器驱采处理*/
	for (ii = 0u; ii < switchCurSum; ii++)
	{
		switchId = GetSwitchId(ii);                      /*获取道岔ID*/

		if ((0u < switchId) && (switchId < SWITCH_SUM_MAX))
		{
			belongCiId = GetSwitchBelongCiId(switchId); 	 /*获取道岔所属联锁ID*/

			if ((belongCiId == localCiId) && (0u != localCiId))
			{
				/*驱动继电器处理*/

				/*获得驱动位置*/
				driveSwitchPos = GetSwitchDrivePostion(switchId);
				/* zt 删除单轨相关代码 2022-02-15 */
				if (CI_TRADITION_RAILWAY == lineIdentity)
				{  /*城市交通*/
					DriveSwitchRelayState(switchId, driveSwitchPos);
				}
				else
				{
				}


			}

		}

	}/*for*/

	/*本周期将行结束,设置上周期期望驱动位置*/
	for (ii = 0u; ii < switchCurSum; ii++)
	{
		switchId = GetSwitchId(ii); 					 /*获取道岔ID*/

		if ((0u < switchId) && (switchId < SWITCH_SUM_MAX))
		{
			belongCiId = GetSwitchBelongCiId(switchId); 	 /*获取道岔所属联锁ID*/

			if ((belongCiId == localCiId) && (0u != localCiId))
			{
				curExpDrvSwitchPos = GetSwitchExpDrvPosition(switchId);

				/*设置上周期期望驱动位置*/
				SetSwitchPreExpDrvPosition(switchId, curExpDrvSwitchPos);
			}

		}
	}/*for*/

	/*清除本周期期望驱动位置,因为双动道岔的原因,所以"设置上周起期望驱动位置"必须与"清除本周期期望驱动位置"代码分离*/
	for (ii = 0u; ii < switchCurSum; ii++)
	{
		switchId = GetSwitchId(ii); 					 /*获取道岔ID*/

		if ((0u < switchId) && (switchId < SWITCH_SUM_MAX))
		{
			belongCiId = GetSwitchBelongCiId(switchId); 	 /*获取道岔所属联锁ID*/

			if ((belongCiId == localCiId) && (0u != localCiId))
			{
				/*清除本周期期望驱动位置*/
				(void)SetSwitchExpDrvPosition(switchId, SWITCH_DRIVE_POS_INVALID);

				/*清除本周期驱动超时位置*/
				SetSwitchDrivOvtmDrvPosition(switchId, SWITCH_DRIVE_POS_INVALID);

				chSwitchJichaState = GetSwitchPrompylyAlarmInfo(switchId);
				/*只有静态红闪和动态红闪可以设置，其他设置不了一直为0*/
				SetSwitchJichaState(switchId, chSwitchJichaState);
			}

		}
	}/*for*/

	 /* zt 删除单轨相关代码 2022-02-15 */

}

/******************************区段相关继电器处理****************************/

/*
* 功能描述： 更新物理区段占用状态
* 参数说明： const UINT32 curCycleNum, 当前周期号
* 返回值  ： void
*/
void PhySecRelayToDeviceStateProc(void)
{
	UINT16 phySecCurSum = 0u;	 /*物理区段总数目*/

	UINT16 phySecId = 0u;	     /*物理区段ID*/
	UINT8 lockState = 0u;/*锁闭状态*/
	UINT8 phyBelongCi = 0u;        /*物理区段所属联锁ID*/
	UINT16 gdRelayId = 0u;        /*物理区段轨道继电器ID*/
	UINT16 wGdRelayId2 = 0U;	  /*迪斯尼物理区段轨道继电器ID2*/
	UINT16 ii = 0u;               /*循环索引*/
	UINT16 preResetRelayId = 0u;	/*物理区段计轴预复位状态继电器ID*/
	UINT8 gdJdqState = 0u;/*轨道继电器状态*/
	UINT8 chGdJdqState2 = 0u;/*轨道继电器状态*/
	UINT8 presetJdqState = 0u;/*预复位继电器状态*/

	UINT8 commState = 0u;/*通信状态*/
	/*相邻联锁是否支持继电接口*/
	UINT8 funcSwitchSupportRelayInterface = GetCiFunctionSwitchConfig(FUNC_SWITCH_USE_RELAY_INTERFACE_BETWEEN_NEIGHBOURCI);
	UINT8 localCi = GetSystemParaLocalCiId();/*本机联锁*/
	UINT8 confirmRelayInterfaceFlag = GetCiCiRelayInterfConfirmFlag();/*继电接口确认状态*/
	UINT16 repGdRelayId = 0u;/*复视轨道继电器ID*/
	UINT8 repGdRelayBelongCi = 0u;/*所属联锁*/
	UINT8 goExec = CI_ERROR;/*是否继续执行*/
	UINT8 chDsnLinSwitch = 0U;

	chDsnLinSwitch = GetCiFunctionSwitchConfig(FUNC_DSN_LINE_SWITCH);
	phySecCurSum = GetTotalPhySecCurNum();		/*获取物理区段总数*/

	/*处理物理区段*/
	for (ii = 0u; ii < phySecCurSum; ii++)
	{
		phySecId = 0u;	      /*物理区段ID*/
		phyBelongCi = 0u;       /*物理区段所属联锁ID*/
		gdRelayId = 0u;        /*物理区段轨道继电器ID*/


		phySecId = GetPhySecId(ii);                      /*获取物理区段ID*/
		phyBelongCi = GetPhySecBelongCiId(phySecId);      /*获取物理区段所属联锁ID*/

		if ((0u == phySecId) || (phySecId > PHYSICAL_SECTION_SUM_MAX))
		{
			goExec = CI_ERROR;
		}
		else
		{
			goExec = CI_SUCCESS;
		}

		if (CI_SUCCESS == goExec)
		{
			if ((phyBelongCi == localCi) && (localCi > 0u))
			{
				gdRelayId = GetPhySecGdRelayId(phySecId);  /*获取物理区段轨道继电器ID*/

				gdJdqState = GetRelayCollState(gdRelayId);/*获取轨道继电器采集状态*/
				if (FUNC_SWITCH_ON != chDsnLinSwitch)
				{
					if (RELAY_STATE_UP == gdJdqState)
					{/*轨道区段继电器吸起*/

						SetPhySecCurOccupyState(phySecId, SECTION_OCCUPY_NO);/*设置轨道区段采集状态空闲*/

					}
					else if (RELAY_STATE_DOWN == gdJdqState)
					{/*轨道区段继电器落下*/

						SetPhySecCurOccupyState(phySecId, SECTION_OCCUPY_YES);/*设置轨道区段采集状态占用*/

					}
					else
					{/*不存在的状态*/
						/*安全值*/
						SetPhySecCurOccupyState(phySecId, SECTION_OCCUPY_YES);/*设置轨道区段采集状态占用*/
					}
				}
				else
				{
					/*迪斯尼不考虑物理区段属于其他联锁得情况*/
					if ((UINT16_MAX != gdRelayId) && (0U != gdRelayId))
					{
						wGdRelayId2 = GetPhySecGdRelayId2(phySecId);  /*获取物理区段轨道继电器ID*/

						chGdJdqState2 = GetRelayCollState(wGdRelayId2);/*获取轨道继电器采集状态*/
						if ((UINT16_MAX != wGdRelayId2) && (0U != wGdRelayId2))
						{
							if ((RELAY_STATE_UP == gdJdqState) && (RELAY_STATE_UP == chGdJdqState2))
							{/*轨道区段继电器吸起*/

								SetPhySecCurOccupyState(phySecId, SECTION_OCCUPY_NO);/*设置轨道区段采集状态空闲*/

							}
							else if ((RELAY_STATE_DOWN == gdJdqState) && (RELAY_STATE_DOWN == chGdJdqState2))
							{/*轨道区段继电器落下*/

								SetPhySecCurOccupyState(phySecId, SECTION_OCCUPY_YES);/*设置轨道区段采集状态占用*/

							}
							else
							{
								/*安全值*/
								SetPhySecCurOccupyState(phySecId, SECTION_OCCUPY_YES);/*设置轨道区段采集状态占用*/

							}
						}
						else
						{
							/*迪斯尼需配置双继电器安全值*/
							SetPhySecCurOccupyState(phySecId, SECTION_OCCUPY_YES);/*设置轨道区段采集状态占用*/
						}
					}
					else
					{
						/*认为迪斯尼配置无计轴，采用故障占压与通信车占压方案 设置空闲*/
						SetPhySecCurOccupyState(phySecId, SECTION_OCCUPY_NO);/*设置轨道区段采集状态空闲*/
					}
				}
				preResetRelayId = GetPhySecPreResetRelayId(phySecId);/*获取物理区段计轴预复位状态继电器ID*/

				presetJdqState = GetRelayCollState(preResetRelayId);

				if (0u != preResetRelayId)
				{/*预复位状态继电器ID有效*/
					if (RELAY_STATE_UP == presetJdqState)
					{/*计轴预复位继电器吸起*/
						SetPhySecPreResetState(phySecId, PHYSICAL_SECTION_PRE_RESET_YES);	/*设置计轴预复位状态有效*/
					}
					else if (RELAY_STATE_DOWN == presetJdqState)
					{/*计轴预复位继电器落下*/
						SetPhySecPreResetState(phySecId, PHYSICAL_SECTION_PRE_RESET_NO);	/*设置计轴预复位状态无效*/
					}
					else
					{/*继电器采集状态为异常值*/
						SetPhySecPreResetState(phySecId, PHYSICAL_SECTION_PRE_RESET_NO);	/*设置计轴预复位状态无效*/
					}
				}
				else
				{
					/*预复位状态继电器ID无效，继续执行*/
				}
			}
			else if ((phyBelongCi != localCi) && (localCi > 0u))
			{

				repGdRelayId = GetPhySecRepGdRelayId(phySecId);
				if (repGdRelayId > 0u)
				{
					repGdRelayBelongCi = GetRelayBelongCiId(repGdRelayId);

					commState = GetLocalCiAndOtherCiTransSta(phyBelongCi);/*本联锁与其它联锁通信通信状态*/

					if ((repGdRelayBelongCi == localCi) && (TRANSMIT_STATE_BAD == commState) &&
						(CICI_RELAY_INTERFACE_CONFIRM_YES == confirmRelayInterfaceFlag) &&
						(FUNC_SWITCH_ON == funcSwitchSupportRelayInterface))
					{
						gdJdqState = GetRelayCollState(repGdRelayId);/*获取轨道继电器采集状态*/

						if (RELAY_STATE_UP == gdJdqState)
						{/*轨道区段继电器吸起*/

							SetPhySecCurOccupyState(phySecId, SECTION_OCCUPY_NO);/*设置轨道区段采集状态空闲*/
#if 0
							SetPhySecCurMergeState(phySecId, SECTION_OCCUPY_NO);
							SetPhySecPreMergeState(phySecId, SECTION_OCCUPY_NO);
#endif
							lockState = GetPhySecLockState(phySecId);
							if (PHYSICAL_SECTION_LOCK_START == lockState)
							{
								SetPhySecLockState(phySecId, PHYSICAL_SECTION_LOCK_NO, 0, 0);
							}
					}
						else if (RELAY_STATE_DOWN == gdJdqState)
						{/*轨道区段继电器落下*/

							SetPhySecCurOccupyState(phySecId, SECTION_OCCUPY_YES);/*设置轨道区段采集状态占用*/
							SetPhySecCurMergeState(phySecId, SECTION_OCCUPY_YES);
							SetPhySecPreMergeState(phySecId, SECTION_OCCUPY_YES);
						}
						else
						{/*不存在的状态*/
							/*安全值*/
							SetPhySecCurOccupyState(phySecId, SECTION_OCCUPY_YES);/*设置轨道区段采集状态占用*/
						}


				}
			}
		}
			else
			{
				/*不处理*/
			}

	}


}
}

/*
* 功能描述： 更新区段计轴复位继电器状态
* 参数说明： void
* 返回值  ： void
*/
void PhySecResetToRelayStateProc(void)
{
	UINT8 const functionId = EFUNC_PHYSEC_RESET_TO_RELAY_STATE_PROC; /*函数故障码*/
	UINT16 phySecId = 0u;            /*物理区段ID*/
	UINT16 ii = 0u;
	UINT16 retValid = CI_ERROR;		/*计轴总复位继电器状态有效性值，默认为无效*/
	UINT8 retGeneralResetFlag = CI_PHYSEC_GENERAL_RESET_NO;
	UINT8 localCi = 0u;/*本CI编号*/
	UINT16 relayZFWId = 0u; /*总复位继电器ID*/
	UINT8 relayZFWState = CI_ERROR;
	UINT8 relayDrvAddrA = 0u;
	UINT8 relayDrvPosA = 0u;
	UINT8 relayDrvAddrB = 0u;
	UINT8 relayDrvPosB = 0u;
	UINT32 relayZFWCycNum = 0u;
	UINT32 rZFWValidCycNum = 0u;
	UINT32 rZFWcmdStartCycNum = 0u;
	UINT32 curCycNum = 0u;
	UINT8 checkRelayRes = CI_TIME_OUT;
	UINT8 checkZFWValidRes = CI_TIME_OUT;
	UINT8 checkZFWcmdRes = CI_TIME_OUT;
	UINT8 tmpRet = CI_ERROR;
	UINT8 occupyState = 0u; /*占用状态*/
	UINT32 startCycNum = 0u; /*开始周期号*/
	UINT8 resetType = 0u; /*计轴复位类型*/
	UINT8 overTimeCheck = 0u;
	UINT16 wPhySecFwRelayId = 0U;/*物理区段复位继电器ID*/
	UINT32 dwPhyResetCount = 0U; /*计轴复位超时周期数*/

	localCi = GetSystemParaLocalCiId();
	relayZFWId = GetZFWRelayId(localCi);         /*总复位继电器ID*/
	retGeneralResetFlag = GetPhySecGeneralResetFlag();	/*获取物理区段计轴总复位继电器状态有效性*/
	if (relayZFWId > 0u)
	{
		relayZFWState = GetRelayCollState(relayZFWId);                 /*ZFWJ继电器采集状态*/
		relayDrvAddrA = GetRelayDrvAddrA(relayZFWId);                  /*ZFWJ继电器A系驱动地址*/
		relayDrvPosA = GetRelayDrvPosA(relayZFWId);                  /*ZFWJ继电器A系驱动位置*/
		relayDrvAddrB = GetRelayDrvAddrB(relayZFWId);                  /*ZFWJ继电器B系驱动地址*/
		relayDrvPosB = GetRelayDrvPosB(relayZFWId);                  /*ZFWJ继电器B系驱动位置*/

		relayZFWCycNum = GetRelayStateUpdateCycNum(relayZFWId);        /*ZFWJ继电器状态更新周期*/
		rZFWValidCycNum = GetZFWValidCycNum();                     /*ZFWJ状态有效周期*/
		curCycNum = Get2oo2CurCycleNum();
		rZFWcmdStartCycNum = GetZFWcmdStartCycNum();
		if ((RELAY_STATE_UP == relayZFWState))
		{/*采集到ZFWJ吸起*/
			if (CI_PHYSEC_GENERAL_RESET_YES == retGeneralResetFlag)
			{/*采集到ZFWJ吸起，且收到计轴总复位命令*/
				tmpRet = SetRelayStateUpdateCycNum(relayZFWId, 0u);	/*清除ZFW总复位继电器有效起始周期号*/
				if (CI_ERROR == tmpRet)
				{
					/*错误处理*/
					retValid = CI_ERROR;
				}
				else
				{
					checkZFWValidRes = SystemOverTimeCheck(rZFWValidCycNum, GetZFWJRelayDriveTimeCount());
					if (CI_TIME_NO == checkZFWValidRes)
					{/*若未计时，则设置起始周期*/
						SetZFWValidCycNum(curCycNum);   /*设置ZFW总复位有效周期*/
						/*有效，执行计轴总复位功能*/
						(void)SetRelayDriveState(relayZFWId, RELAY_STATE_UP);/*设置计轴总复位继电器吸起*/
						retValid = CI_SUCCESS;
					}
					else if (CI_TIME_OUT == checkZFWValidRes)
					{/*计轴总复位命令驱动超过最长时间*/
						SetZFWValidCycNum(0u);   /*设置ZFW总复位无效周期*/
						/*执行取消计轴总复位功能*/
						SetPhySecGeneralResetFlag(CI_PHYSEC_GENERAL_RESET_NO);	/*清除物理区段计轴总复位继电器状态有效性*/
						(void)SetRelayDriveState(relayZFWId, RELAY_STATE_DOWN);/*设置计轴总复位继电器落下*/
						retValid = CI_ERROR;
					}
					else
					{/*有效，执行计轴总复位功能*/
						(void)SetRelayDriveState(relayZFWId, RELAY_STATE_UP);/*设置计轴总复位继电器吸起*/
						retValid = CI_SUCCESS;
					}
				}
			}
			else
			{/*采集到ZFWJ吸起，未收到计轴总复位命令*/
				checkRelayRes = SystemOverTimeCheck(relayZFWCycNum, ZFWJ_REYLAY_VALID_CYCLE_NUM);
				if (CI_TIME_NO == checkRelayRes)
				{/*若未计时，则设置起始周期*/
					tmpRet = SetRelayStateUpdateCycNum(relayZFWId, curCycNum);/*设置ZFWJ总复位继电器有效周期*/
					if (CI_ERROR == tmpRet)
					{
						/*错误处理*/
						retValid = CI_ERROR;
					}
				}
				else if (CI_TIME_OUT == checkRelayRes)
				{/*计轴总复位命令驱动超过最长时间*/
					if ((relayDrvAddrA > 0u) && (relayDrvPosA > 0u) && (relayDrvAddrB > 0u) && (relayDrvPosB > 0u))
					{/*若联锁没有驱动ZFWJ，但是连续三个周期采集到ZFWJ吸起时，联锁增加给现地的报警提示“计轴总复位继电器混线”*/
						retValid = CI_ERROR;
						SetZfwjHunXianFLag(ZFWJ_HUN_XIAN_YES);
					}
					else
					{/*未配置驱动ZFWJ，采集到吸起可以继续执行计轴复位命令*/
						retValid = CI_SUCCESS;
					}
				}
				else
				{/*未超过超时周期数*/
					retValid = CI_ERROR;
				}
				SetZFWValidCycNum(0u);   /*设置ZFW总复位无效周期*/
				/*执行取消计轴总复位功能*/
				(void)SetRelayDriveState(relayZFWId, RELAY_STATE_DOWN);/*设置计轴总复位继电器落下*/
			}
		}
		else
		{/*采集到ZFWJ落下，不执行计轴复位逻辑处理*/
			retValid = CI_ERROR;
			tmpRet = SetRelayStateUpdateCycNum(relayZFWId, 0u);	/*清除ZFW总复位继电器有效起始周期号*/
			CleanPhySecResetStartCycNum();/*清除复位起始周期号*/
			if (CI_ERROR == tmpRet)
			{
				/*错误处理*/
			}
			else
			{
				SetZFWValidCycNum(0u);   /*设置ZFW总复位无效周期*/
				if (CI_PHYSEC_GENERAL_RESET_YES == retGeneralResetFlag)
				{/*有效，执行计轴总复位功能*/
					/*检查收到计轴总复位命令起始周期数*/
					checkZFWcmdRes = SystemOverTimeCheck(rZFWcmdStartCycNum, ZFWJ_REYLAY_VALID_CYCLE_NUM);
					if (CI_TIME_OUT == checkZFWcmdRes)
					{/*计轴总复位命令驱动超过最长时间*/
						/*无效，不执行计轴总复位功能*/
						SetPhySecGeneralResetFlag(CI_PHYSEC_GENERAL_RESET_NO);    /*计轴总复位命令无效*/
						(void)SetRelayDriveState(relayZFWId, RELAY_STATE_DOWN);/*设置计轴总复位继电器落下*/
					}
					else
					{/*未超过超时周期数*/
						(void)SetRelayDriveState(relayZFWId, RELAY_STATE_UP);/*设置计轴总复位继电器吸起*/
					}
				}
				else
				{/*无效，不执行计轴总复位功能*/
					(void)SetRelayDriveState(relayZFWId, RELAY_STATE_DOWN);/*设置计轴总复位继电器落下*/
				}
			}
		}
	}
	else
	{/*无总复位继电器继续执行计轴复位功能*/
		retValid = CI_SUCCESS;
	}

	if (CI_SUCCESS == retValid)
	{/*有效，执行计轴复位功能*/
		for (ii = 0u; ii < GetPhySecCurSum(); ii++)
		{
			retValid = CI_ERROR;	/*计轴总复位继电器状态有效性值置位为无效*/
			phySecId = GetPhySecId(ii);/*获取物理区段ID*/

			startCycNum = GetPhySecResetStartCycNum(phySecId);
			wPhySecFwRelayId = GetPhySecFWRelayId(phySecId);		

			if (startCycNum > 0u) /*计轴复位*/
			{
				occupyState = GetPhySecCurOccupyState(phySecId);
				if (SECTION_OCCUPY_NO == occupyState) /*采集空闲*/
				{
					SetPhySecResetStartCycNum(phySecId, 0u);/*修改计轴复位起始周期号*/
					(void)SetRelayDriveState(wPhySecFwRelayId, RELAY_STATE_DOWN);/*设置计轴复位继电器落下*/
				}
				else /*采集占用*/
				{
					occupyState = GetPhySecCurTxOccupyState(phySecId); /*m by yt，修改缺陷：开始非通信车占用，在计轴复位过程中，有通信车占用后，未处理问题，2022年8月3日*/
					if (LOGICSECTION_OCCUPY_TX == occupyState) /*通信车占用*/
					{
						SetPhySecResetStartCycNum(phySecId, 0u);/*修改计轴复位起始周期号*/
						(void)SetRelayDriveState(wPhySecFwRelayId, RELAY_STATE_DOWN);/*设置计轴复位继电器落下*/
						SetErrorData(functionId, CI_DEVICE_TYPE_PHYSEC, phySecId, ETYPE_PS_NO_UT_CT_OCU_STATE, occupyState, ESEND_LEVEL_ATS);
					}
					else
					{
						dwPhyResetCount = GetSystemParaSectionResetCount();
						overTimeCheck = SystemOverTimeCheck(startCycNum, dwPhyResetCount);
						if (CI_TIME_OUT == overTimeCheck)
						{/*区段计轴复位超时*/

							SetPhySecResetStartCycNum(phySecId, 0u);/*修改计轴复位起始周期号*/
							(void)SetRelayDriveState(wPhySecFwRelayId, RELAY_STATE_DOWN);/*设置计轴复位继电器落下*/
#if 0
							SetCiSendCmdBackInfoData(CI_BACK_PSEC_RESET_ERROR, CI_DEVICE_TYPE_PHYSEC, phySecId, 0u, 0u);/*反馈计轴复位失败*/
#endif

						}
						else
						{
							retValid = GetZFWValidByPhySecId(phySecId); /*获取物理区段计轴总复位继电器状态有效性*/
							if (CI_SUCCESS == retValid) /*有效，执行计轴复位功能*/
							{
								resetType = GetPhySecSectionResetType(phySecId);

								if ((PHYSICAL_SECTION_PRE_RESET_NO == resetType) || (PHYSICAL_SECTION_PRE_RESET_YES == resetType)) /*直接复位或者预复位*/
								{
									(void)SetRelayDriveState(wPhySecFwRelayId, RELAY_STATE_UP);/*设置计轴复位继电器吸起，依赖超时驱动继电器落下*/
								}
								else /*否则*/
								{
									SetPhySecResetStartCycNum(phySecId, 0u);/*修改计轴复位起始周期号*/
									(void)SetRelayDriveState(wPhySecFwRelayId, RELAY_STATE_DOWN);/*设置计轴复位继电器落下*/
								}
							}
							else /*无效*/
							{
								SetPhySecResetStartCycNum(phySecId, 0u);/*修改计轴复位起始周期号*/
								(void)SetRelayDriveState(wPhySecFwRelayId, RELAY_STATE_DOWN);/*设置计轴复位继电器落下*/
								SetCiSendCmdBackInfoData(CI_BACK_PSEC_RESET_ZFW_ERROR, CI_DEVICE_TYPE_PHYSEC, phySecId, 0u, 0u);/*反馈计轴复位失败：总复位继电器落下*/
							}
						}
				}
			}
		}
	}
}
}
/*
* 功能描述： 更新区段计轴复位继电器状态
* 参数说明： void
* 返回值  ： void
*/
void PhySecResetToRelayStateProc_Vir(UINT8 virCIid)
{
	UINT8 const functionId = EFUNC_PHYSEC_RESET_TO_RELAY_STATE_PROC; /*函数故障码*/
	UINT16 phySecId = 0u;            /*物理区段ID*/
	UINT16 ii = 0u;
	UINT16 retValid = CI_ERROR;		/*计轴总复位继电器状态有效性值，默认为无效*/
	UINT8 retGeneralResetFlag = CI_PHYSEC_GENERAL_RESET_NO;
	UINT8 localCi = 0u;/*本CI编号*/
	UINT16 relayZFWId = 0u; /*总复位继电器ID*/
	UINT8 relayZFWState = CI_ERROR;
	UINT8 relayDrvAddrA = 0u;
	UINT8 relayDrvPosA = 0u;
	UINT8 relayDrvAddrB = 0u;
	UINT8 relayDrvPosB = 0u;
	UINT32 relayZFWCycNum = 0u;
	UINT32 rZFWValidCycNum = 0u;
	UINT32 rZFWcmdStartCycNum = 0u;
	UINT32 curCycNum = 0u;
	UINT8 checkRelayRes = CI_TIME_OUT;
	UINT8 checkZFWValidRes = CI_TIME_OUT;
	UINT8 checkZFWcmdRes = CI_TIME_OUT;
	UINT8 tmpRet = CI_ERROR;
	UINT8 occupyState = 0u; /*占用状态*/
	UINT32 startCycNum = 0u; /*开始周期号*/
	UINT8 resetType = 0u; /*计轴复位类型*/
	UINT8 preResetState = 0u; /*计轴预复位状态*/
	UINT8 overTimeCheck = 0u;
	UINT8 belongVirCIid = 0u;

	localCi = GetSystemParaLocalCiId();
	relayZFWId = GetZFWRelayId_UseVirCI(localCi, virCIid);         /*总复位继电器ID*/
	retGeneralResetFlag = GetVirCIZfwFlag(virCIid);	/*获取物理区段计轴总复位继电器状态有效性*/
	if (relayZFWId > 0u)
	{
		relayZFWState = GetRelayCollState(relayZFWId);                 /*ZFWJ继电器采集状态*/
		relayDrvAddrA = GetRelayDrvAddrA(relayZFWId);                  /*ZFWJ继电器A系驱动地址*/
		relayDrvPosA = GetRelayDrvPosA(relayZFWId);                  /*ZFWJ继电器A系驱动位置*/
		relayDrvAddrB = GetRelayDrvAddrB(relayZFWId);                  /*ZFWJ继电器B系驱动地址*/
		relayDrvPosB = GetRelayDrvPosB(relayZFWId);                  /*ZFWJ继电器B系驱动位置*/

		relayZFWCycNum = GetRelayStateUpdateCycNum(relayZFWId);        /*ZFWJ继电器状态更新周期*/

		rZFWValidCycNum = GetVirCIZfwValidCycNum(virCIid);/*ZFWJ状态有效周期*/
		curCycNum = Get2oo2CurCycleNum();
		rZFWcmdStartCycNum = GetVirCIZfwStartCycNum(virCIid);
		if ((RELAY_STATE_UP == relayZFWState))
		{/*采集到ZFWJ吸起*/
			if (CI_PHYSEC_GENERAL_RESET_YES == retGeneralResetFlag)
			{/*采集到ZFWJ吸起，且收到计轴总复位命令*/
				tmpRet = SetRelayStateUpdateCycNum(relayZFWId, 0u);	/*清除ZFW总复位继电器有效起始周期号*/
				if (CI_ERROR == tmpRet)
				{
					/*错误处理*/
					retValid = CI_ERROR;
				}
				else
				{
					checkZFWValidRes = SystemOverTimeCheck(rZFWValidCycNum, GetZFWJRelayDriveTimeCount());
					if (CI_TIME_NO == checkZFWValidRes)
					{/*若未计时，则设置起始周期*/
						SetVirCIZfwValidCycNum(virCIid, curCycNum);   /*设置ZFW总复位有效周期*/
						/*有效，执行计轴总复位功能*/
						(void)SetRelayDriveState(relayZFWId, RELAY_STATE_UP);/*设置计轴总复位继电器吸起*/
						retValid = CI_SUCCESS;
					}
					else if (CI_TIME_OUT == checkZFWValidRes)
					{/*计轴总复位命令驱动超过最长时间*/
						SetVirCIZfwValidCycNum(virCIid, 0u);   /*设置ZFW总复位无效周期*/
						/*执行取消计轴总复位功能*/
						SetPhySecZfwManage(virCIid, CI_PHYSEC_GENERAL_RESET_NO);	/*清除物理区段计轴总复位继电器状态有效性*/
						(void)SetRelayDriveState(relayZFWId, RELAY_STATE_DOWN);/*设置计轴总复位继电器落下*/
						retValid = CI_ERROR;
					}
					else
					{/*有效，执行计轴总复位功能*/
						(void)SetRelayDriveState(relayZFWId, RELAY_STATE_UP);/*设置计轴总复位继电器吸起*/
						retValid = CI_SUCCESS;
					}
				}
			}
			else
			{/*采集到ZFWJ吸起，未收到计轴总复位命令*/
				checkRelayRes = SystemOverTimeCheck(relayZFWCycNum, ZFWJ_REYLAY_VALID_CYCLE_NUM);
				if (CI_TIME_NO == checkRelayRes)
				{/*若未计时，则设置起始周期*/
					tmpRet = SetRelayStateUpdateCycNum(relayZFWId, curCycNum);/*设置ZFWJ总复位继电器有效周期*/
					if (CI_ERROR == tmpRet)
					{
						/*错误处理*/
						retValid = CI_ERROR;
					}
				}
				else if (CI_TIME_OUT == checkRelayRes)
				{/*计轴总复位命令驱动超过最长时间*/
					if ((relayDrvAddrA > 0u) && (relayDrvPosA > 0u) && (relayDrvAddrB > 0u) && (relayDrvPosB > 0u))
					{/*若联锁没有驱动ZFWJ，但是连续三个周期采集到ZFWJ吸起时，联锁增加给现地的报警提示“计轴总复位继电器混线”*/
						retValid = CI_ERROR;
						SetVirCIZfwHunxianFlag(virCIid, ZFWJ_HUN_XIAN_YES);
					}
					else
					{/*未配置驱动ZFWJ，采集到吸起可以继续执行计轴复位命令*/
						retValid = CI_SUCCESS;
					}
				}
				else
				{/*未超过超时周期数*/
					retValid = CI_ERROR;
				}
				SetVirCIZfwValidCycNum(virCIid, 0u);   /*设置ZFW总复位无效周期*/
				/*执行取消计轴总复位功能*/
				(void)SetRelayDriveState(relayZFWId, RELAY_STATE_DOWN);/*设置计轴总复位继电器落下*/
			}
		}
		else
		{/*采集到ZFWJ落下，不执行计轴复位逻辑处理*/
			retValid = CI_ERROR;
			tmpRet = SetRelayStateUpdateCycNum(relayZFWId, 0u);	/*清除ZFW总复位继电器有效起始周期号*/
			if (CI_ERROR == tmpRet)
			{
				/*错误处理*/
			}
			else
			{
				SetVirCIZfwValidCycNum(virCIid, 0u);   /*设置ZFW总复位无效周期*/
				if (CI_PHYSEC_GENERAL_RESET_YES == retGeneralResetFlag)
				{/*有效，执行计轴总复位功能*/
					/*检查收到计轴总复位命令起始周期数*/
					checkZFWcmdRes = SystemOverTimeCheck(rZFWcmdStartCycNum, ZFWJ_REYLAY_VALID_CYCLE_NUM);
					if (CI_TIME_OUT == checkZFWcmdRes)
					{/*计轴总复位命令驱动超过最长时间*/
						/*无效，不执行计轴总复位功能*/
						SetPhySecZfwManage(virCIid, CI_PHYSEC_GENERAL_RESET_NO);    /*计轴总复位命令无效*/
						(void)SetRelayDriveState(relayZFWId, RELAY_STATE_DOWN);/*设置计轴总复位继电器落下*/
					}
					else
					{/*未超过超时周期数*/
						(void)SetRelayDriveState(relayZFWId, RELAY_STATE_UP);/*设置计轴总复位继电器吸起*/
					}
				}
				else
				{/*无效，不执行计轴总复位功能*/
					(void)SetRelayDriveState(relayZFWId, RELAY_STATE_DOWN);/*设置计轴总复位继电器落下*/
				}
			}
		}
	}
	else
	{/*无总复位继电器继续执行计轴复位功能*/
		retValid = CI_SUCCESS;
	}

	if (CI_SUCCESS == retValid)
	{/*有效，执行计轴复位功能*/
		for (ii = 0u; ii < GetPhySecCurSum(); ii++)
		{
			retValid = CI_ERROR;	/*计轴总复位继电器状态有效性值置位为无效*/
			phySecId = GetPhySecId(ii);/*获取物理区段ID*/
			belongVirCIid = GetPhySecBelongVirCiId(phySecId);

			startCycNum = GetPhySecResetStartCycNum(phySecId);
			if ((startCycNum > 0u) && (belongVirCIid == virCIid)) /*计轴复位*/
			{
				occupyState = GetPhySecCurOccupyState(phySecId);
				if (SECTION_OCCUPY_NO == occupyState) /*采集空闲*/
				{
					SetPhySecResetStartCycNum(phySecId, 0u);/*修改计轴复位起始周期号*/
					(void)SetRelayDriveState(GetPhySecFWRelayId(phySecId), RELAY_STATE_DOWN);/*设置计轴复位继电器落下*/
				}
				else /*采集占用*/
				{
					occupyState = GetPhySecCurTxOccupyState(phySecId); /*m by yt，修改缺陷：开始非通信车占用，在计轴复位过程中，有通信车占用后，未处理问题，2022年8月3日*/
					if (LOGICSECTION_OCCUPY_TX == occupyState) /*通信车占用*/
					{
						SetPhySecResetStartCycNum(phySecId, 0u);/*修改计轴复位起始周期号*/
						(void)SetRelayDriveState(GetPhySecFWRelayId(phySecId), RELAY_STATE_DOWN);/*设置计轴复位继电器落下*/
						SetErrorData(functionId, CI_DEVICE_TYPE_PHYSEC, phySecId, ETYPE_PS_NO_UT_CT_OCU_STATE, occupyState, ESEND_LEVEL_ATS);
					}
					else
					{
						overTimeCheck = SystemOverTimeCheck(GetPhySecResetStartCycNum(phySecId), GetSystemParaSectionResetCount());
						if (CI_TIME_OUT == overTimeCheck)
						{/*区段计轴复位超时*/

							SetPhySecResetStartCycNum(phySecId, 0u);/*修改计轴复位起始周期号*/
							(void)SetRelayDriveState(GetPhySecFWRelayId(phySecId), RELAY_STATE_DOWN);/*设置计轴复位继电器落下*/
#if 0
							SetCiSendCmdBackInfoData(CI_BACK_PSEC_RESET_ERROR, CI_DEVICE_TYPE_PHYSEC, phySecId, 0u, 0u);/*反馈计轴复位失败*/
#endif

					}
						else
						{
							retValid = GetZFWValidByPhySecId(phySecId); /*获取物理区段计轴总复位继电器状态有效性*/
							if (CI_SUCCESS == retValid) /*有效，执行计轴复位功能*/
							{
								resetType = GetPhySecSectionResetType(phySecId);
								if (PHYSICAL_SECTION_PRE_RESET_NO == resetType) /*直接复位*/
								{
									(void)SetRelayDriveState(GetPhySecFWRelayId(phySecId), RELAY_STATE_UP);/*设置计轴复位继电器吸起*/
								}
								else if (PHYSICAL_SECTION_PRE_RESET_YES == resetType) /*预复位*/
								{
									preResetState = GetPhySecPreResetState(phySecId);
									if (PHYSICAL_SECTION_PRE_RESET_NO == preResetState) /*计轴预复位未成功*/
									{
										(void)SetRelayDriveState(GetPhySecFWRelayId(phySecId), RELAY_STATE_UP);/*设置计轴复位继电器吸起*/
									}
									else /*计轴预复位成功*/
									{
										(void)SetRelayDriveState(GetPhySecFWRelayId(phySecId), RELAY_STATE_DOWN);/*设置计轴复位继电器落下*/
									}
								}
								else /*否则*/
								{
									SetPhySecResetStartCycNum(phySecId, 0u);/*修改计轴复位起始周期号*/
									(void)SetRelayDriveState(GetPhySecFWRelayId(phySecId), RELAY_STATE_DOWN);/*设置计轴复位继电器落下*/
								}
							}
							else /*无效*/
							{
								SetPhySecResetStartCycNum(phySecId, 0u);/*修改计轴复位起始周期号*/
								(void)SetRelayDriveState(GetPhySecFWRelayId(phySecId), RELAY_STATE_DOWN);/*设置计轴复位继电器落下*/
								SetCiSendCmdBackInfoData(CI_BACK_PSEC_RESET_ZFW_ERROR, CI_DEVICE_TYPE_PHYSEC, phySecId, 0u, 0u);/*反馈计轴复位失败：总复位继电器落下*/
							}
						}
				}
			}
		}
	}
}
}

/*
* 功能描述： 更新所有区段计轴复位继电器状态
* 参数说明： void
* 返回值  ： void
*/
void UpDataAllPhySecResetRelay_VirCI(void)
{
	UINT8 i = 0u;
	UINT8 virNum = 0u;
	UINT8 virCIid = 0u;

	virNum = GetVirtualCINum();
	for (i = 0u; i < virNum; i++)
	{
		virCIid = GetVirtualCIid(i);
		if (0u < virCIid)
		{
			PhySecResetToRelayStateProc_Vir(virCIid);
		}
	}
}

/******************************站台相关继电器处理****************************/

/*
* 功能描述： 更新屏蔽门逻辑状态
* 参数说明： void
* 返回值  ： 0u: 更新失败
*			 1: 更新成功
*/
void PsdRelayToDeviceStateProc(void)
{
	UINT16 ii = 0u;					/*游标*/
	UINT16 psdSum = 0u;				/*psd总数*/
	UINT16 psdId = 0u;				/*屏蔽门ID*/
	UINT16 psdDoorRelayId = 0u;		/*屏蔽门开关状态继电器ID*/
	UINT16 wPsdDoorRelayId2 = 0u;    /*屏蔽门开关状态继电器ID*/
	UINT16 psdMutualLockRelayId = 0u;/*互锁解除继电器ID*/
	UINT16 wPsdMutualLockRelayId2 = 0u;/*互锁解除继电器ID*/
	UINT16 psdButtonRelayId = 0u;    /*关门按钮继电器*/
	UINT16 psdReopenButtonRelayId = 0u;    /*PSD开门按钮继电器*/
	UINT16 psdDepartureButtonRelayId = 0u;    /*站台发车按钮继电器*/
	UINT8 psdDriState = 0u;		/*屏蔽门上一次驱动状态*/
	UINT16 psdRemoraId = 0u;       /*障碍物继电器*/
	UINT16 mutualLockId = 0u;      /*间隙探测互锁解除继电器ID*/
	UINT8 chPsdRemoraState = 0U;
	UINT8 chGapDecMutualLockState = 0U;
	UINT8 chMutualLockState = 0U;
	UINT8 chMutualLock2State = 0U;
	UINT8 chPsdCloseState = 0U;
	UINT8 chPsdClose2State = 0U;
	UINT8 chPsdButtonState = 0U;
	UINT8 chPsdReOpenRelayState = 0U;
	UINT8 reVal = CI_SUCCESS;
	UINT8 relayCollState = 0u;
	UINT8 buttonState = 0u;
	UINT32 buttonPressCycNum = 0U;
	UINT32 curCycNum = 0U;
	UINT8 chPsdVirtualState = 0U;
	UINT32 dwCycNum = 0U;
	UINT8 chDsnLinSwitch = 0U;
	UINT8 cFuncRet = 0U;

	chDsnLinSwitch = GetCiFunctionSwitchConfig(FUNC_DSN_LINE_SWITCH);

	psdSum = GetPsdSum();
	for (ii = 0u; ii < psdSum; ii++)
	{
		psdId = GetPsdId(ii);
		if (0u == psdId)
		{
			reVal = CI_ERROR;
		}
		else
		{
			chPsdVirtualState = GetPsdVirtualAttribute(psdId);
			if (PSD_VIRTUAL_ATTR_YES == chPsdVirtualState)
			{/*虚拟屏蔽门开关状态更新采用上一次驱动状态*/
				psdDriState = GetPsdPreDriveState(psdId);/*获取上一次驱动状态*/
				if (PSD_DRIVE_STATE_OPEN == psdDriState)
				{/*驱动开门*/
					reVal = SetPsdState(psdId,PSD_STATE_OPEN);
				}
				else if (PSD_DRIVE_STATE_CLOSE == psdDriState)
				{/*驱动关门*/
					reVal = SetPsdState(psdId,PSD_STATE_CLOSE);
				}
				else
				{
					/*什么都不做*/
				}
				/*苏州6需求by lyj：虚拟屏蔽门存在真实PCB,POB,DPB按钮；更新按钮状态*/
				/*TSCI合并添加 20221208-lc*/
				if (CI_SUCCESS == reVal)
				{
					psdButtonRelayId = GetDoorButtonRelayId(psdId);
					/*屏蔽门按钮状态更新*/
					if ((0u != psdButtonRelayId) && (UINT16_MAX != psdButtonRelayId))
					{/*PCB按钮继电器ID有效*/
						relayCollState = GetRelayCollState(psdButtonRelayId);
						if (RELAY_STATE_UP == relayCollState)
						{
							buttonPressCycNum = GetPCBPressCycNum(psdId);
							curCycNum = Get2oo2CurCycleNum();
							if (0U == buttonPressCycNum)
							{/*若未计时，则设置起始周期*/
								(void)SetPCBPressCycNum(psdId, curCycNum);
							}
							buttonState = SetPsdButtonState(psdId, PSD_BUTTON_STATE_DOWN);
							if (CI_ERROR == buttonState)
							{
								reVal = CI_ERROR;
							}
						}
						else if (RELAY_STATE_DOWN == relayCollState)
						{
							(void)SetPCBPressCycNum(psdId, 0u);	/*清除PCB按下起始周期号*/
							buttonState = SetPsdButtonState(psdId, PSD_BUTTON_STATE_UP);
							if (CI_ERROR == buttonState)
							{
								reVal = CI_ERROR;
							}
						}
						else
						{
							(void)SetPCBPressCycNum(psdId, 0u);	/*清除PCB按下起始周期号*/
							reVal = CI_ERROR;
						}
					}
					else
					{/*有些线路PSD不配置PCB按钮，即PCB按钮继电器ID无效，continue，继续执行*/
					}
				}

				if (CI_SUCCESS == reVal)
				{
					psdReopenButtonRelayId = GetPsdReOpenRelayId(psdId);
					/*屏蔽门开门按钮状态更新*/
					if ((0u != psdReopenButtonRelayId) && (UINT16_MAX != psdReopenButtonRelayId))
					{/*站台开门按钮继电器ID有效*/
						relayCollState = GetRelayCollState(psdReopenButtonRelayId);
						if (RELAY_STATE_UP == relayCollState)
						{
							buttonPressCycNum = GetPOBPressCycNum(psdId);
							curCycNum = Get2oo2CurCycleNum();
							if (0U == buttonPressCycNum)
							{/*若未计时，则设置起始周期*/
								(void)SetPOBPressCycNum(psdId, curCycNum);
							}
							buttonState = SetPsdOpenButtonState(psdId, PSD_OPEN_BUTTON_STATE_VALID);
							if (CI_ERROR == buttonState)
							{
								reVal = CI_ERROR;
							}
						}
						else if (RELAY_STATE_DOWN == relayCollState)
						{
							(void)SetPOBPressCycNum(psdId, 0u);	/*清除POB按下起始周期号*/
							buttonState = SetPsdOpenButtonState(psdId, PSD_OPEN_BUTTON_STATE_INVALID);
							if (CI_ERROR == buttonState)
							{
								reVal = CI_ERROR;
							}
						}
						else
						{
							(void)SetPOBPressCycNum(psdId, 0u);	/*清除POB按下起始周期号*/
							reVal = CI_ERROR;
						}
					}
					else
					{/*有些线路PSD不配置开门按钮继电器，continue，继续执行*/
					}
				}

				if (CI_SUCCESS == reVal)
				{
					psdDepartureButtonRelayId = GetPsdDeparConfmRelayId(psdId);
					/*屏蔽门发车按钮状态更新*/
					if ((0u != psdDepartureButtonRelayId) && (UINT16_MAX != psdDepartureButtonRelayId))
					{/*站台发车按钮继电器ID有效*/
						relayCollState = GetRelayCollState(psdDepartureButtonRelayId);
						if (RELAY_STATE_UP == relayCollState)
						{
							buttonPressCycNum = GetPSBPressCycNum(psdId);
							curCycNum = Get2oo2CurCycleNum();
							if (0U == buttonPressCycNum)
							{/*若未计时，则设置起始周期*/
								(void)SetPSBPressCycNum(psdId, curCycNum);
							}
							buttonState = SetPsdDepartButtonState(psdId, PLATFORM_DEPAR_BUTTON_STATE_VALID);
							if (CI_ERROR == buttonState)
							{
								reVal = CI_ERROR;
							}
						}
						else if (RELAY_STATE_DOWN == relayCollState)
						{
							(void)SetPSBPressCycNum(psdId, 0u);	/*清除PSB按下起始周期号*/
							buttonState = SetPsdDepartButtonState(psdId, PLATFORM_DEPAR_BUTTON_STATE_INVALID);
							if (CI_ERROR == buttonState)
							{
								reVal = CI_ERROR;
							}
						}
						else
						{
							(void)SetPSBPressCycNum(psdId, 0u);	/*清除PSB按下起始周期号*/
							reVal = CI_ERROR;
						}
					}
					else
					{/*有些线路PSD不配置发车按钮继电器，continue，继续执行*/
					}
				}
			}
			else
			{/*真实屏蔽门采用继电器状态更新互锁解除、开关状态及PCB按钮状态*/
				psdMutualLockRelayId = GetPsdMutualLockRelayId(psdId);
				wPsdMutualLockRelayId2 = GetPsdMutualLockRelayId2(psdId);
				if (psdMutualLockRelayId > 0u)
				{
					if (FUNC_SWITCH_ON != chDsnLinSwitch)
					{/*互锁解除状态更新*/
						chMutualLockState = GetRelayCollState(psdMutualLockRelayId);
						if (RELAY_STATE_DOWN == chMutualLockState)
						{
							reVal = SetPsdMutualLockRemoveState(psdId, PSD_MUTUALLOCK_REMOVE_NO);

						}
						else if (RELAY_STATE_UP == chMutualLockState)
						{
							reVal = SetPsdMutualLockRemoveState(psdId, PSD_MUTUALLOCK_REMOVE_YES);

						}
						else
						{
							reVal = CI_ERROR;
						}
					}
					else
					{
						/*迪斯尼线路状态判断*/
						chMutualLockState = GetRelayCollState(psdMutualLockRelayId);
						chMutualLock2State = GetRelayCollState(wPsdMutualLockRelayId2);
						if ((RELAY_STATE_DOWN == chMutualLockState)
							&& (RELAY_STATE_DOWN == chMutualLock2State))
						{
							reVal = SetPsdMutualLockRemoveState(psdId, PSD_MUTUALLOCK_REMOVE_NO);
						}
						else if ((RELAY_STATE_UP == chMutualLockState)
							&& (RELAY_STATE_UP == chMutualLock2State))
						{
							reVal = SetPsdMutualLockRemoveState(psdId, PSD_MUTUALLOCK_REMOVE_YES);
						}
						else
						{
							reVal = SetPsdMutualLockRemoveState(psdId, PSD_MUTUALLOCK_REMOVE_NO);
						}
					}
				}


				if (reVal == CI_SUCCESS)
				{
					psdDoorRelayId = GetPsdStateRelayId(psdId);
					wPsdDoorRelayId2 = GetPsdStateRelayId2(psdId);
					if (psdDoorRelayId > 0u)
					{
						if (FUNC_SWITCH_ON != chDsnLinSwitch)
						{
							/*屏蔽门开关状态更新*/
							cFuncRet = GetPsdRelayCollTolerateRet(psdId);  /*获取PSD门开继电器采集容忍结果*/
							if (CI_SUCCESS == cFuncRet)
							{
								reVal = SetPsdState(psdId, PSD_STATE_CLOSE);
							}
							else
							{
								reVal = SetPsdState(psdId, PSD_STATE_OPEN);
							}
						}
						else
						{
							chPsdCloseState = GetRelayCollState(psdDoorRelayId);
							chPsdClose2State = GetRelayCollState(wPsdDoorRelayId2);
							if ((RELAY_STATE_UP == chPsdCloseState) && (RELAY_STATE_UP == chPsdClose2State))
							{
								reVal = SetPsdState(psdId, PSD_STATE_CLOSE);

							}
							else if ((RELAY_STATE_DOWN == chPsdCloseState) && (RELAY_STATE_DOWN == chPsdClose2State))
							{
								reVal = SetPsdState(psdId, PSD_STATE_OPEN);

							}
							else
							{
								reVal = SetPsdState(psdId, PSD_STATE_OPEN);
							}
						}
					}

				}

				if (reVal == CI_SUCCESS)
				{
					psdButtonRelayId = GetDoorButtonRelayId(psdId);
					/*屏蔽门按钮状态更新*/
					if ((0u != psdButtonRelayId) && (UINT16_MAX != psdButtonRelayId))
					{/*PCB按钮继电器ID有效*/
						chPsdButtonState = GetRelayCollState(psdButtonRelayId);
						if (RELAY_STATE_UP == chPsdButtonState)
						{
							dwCycNum = GetPCBPressCycNum(psdId);
							if (0u == dwCycNum)
							{/*若未计时，则设置起始周期*/
								(void)SetPCBPressCycNum(psdId, Get2oo2CurCycleNum());
							}
							reVal = SetPsdButtonState(psdId, PSD_BUTTON_STATE_DOWN);
						}
						else if (RELAY_STATE_DOWN == chPsdButtonState)
						{
							(void)SetPCBPressCycNum(psdId, 0u);	/*清除PCB按下起始周期号*/
							reVal = SetPsdButtonState(psdId, PSD_BUTTON_STATE_UP);
						}
						else
						{
							(void)SetPCBPressCycNum(psdId, 0u);	/*清除PCB按下起始周期号*/
							reVal = CI_ERROR;
						}
					}
					else
					{/*有些线路PSD不配置PCB按钮，即PCB按钮继电器ID无效，continue，继续执行*/
					}

				}
				if (reVal == CI_SUCCESS)
				{
					psdRemoraId = GetPsdObtacleRelayId(psdId);
					/*障碍物状态更新，新机场线新需求2018.11.07*/
					if ((0u != psdRemoraId) && (UINT16_MAX != psdRemoraId))
					{/*障碍物继电器ID有效*/
						chPsdRemoraState = GetRelayCollState(psdRemoraId);
						if (RELAY_STATE_UP == chPsdRemoraState)
						{    /*障碍物继电器吸起表示无障碍物，落下表示有障碍物*/
							reVal = SetPsdRemoraState(psdId, PSD_REMORA_NO);
						}
						else if (RELAY_STATE_DOWN == chPsdRemoraState)
						{
							reVal = SetPsdRemoraState(psdId, PSD_REMORA_YES);
						}
						else
						{
							reVal = CI_ERROR;
						}
					}
				}
				if (reVal == CI_SUCCESS)
				{   /*间隙探测互锁解除信息*/
					mutualLockId = GetPsdGapDetMuLockelayId(psdId);
					/*障碍物状态更新，新机场线新需求2018.11.07*/
					if ((0u != mutualLockId) && (UINT16_MAX != mutualLockId))
					{/*障碍物继电器ID有效*/
						chGapDecMutualLockState = GetRelayCollState(mutualLockId);
						if (RELAY_STATE_UP == chGapDecMutualLockState)
						{    /*间隙探测互锁解除电器吸起表示已互锁解除，落下表示无互锁解除*/
							reVal = SetJXTCMutualLockState(psdId, JXTC_MUTUALLOCK_REMOVE_YES);
						}
						else if (RELAY_STATE_DOWN == chGapDecMutualLockState)
						{
							reVal = SetJXTCMutualLockState(psdId, JXTC_MUTUALLOCK_REMOVE_NO);
						}
						else
						{
							reVal = CI_ERROR;
						}
					}

				}
				if (reVal == CI_SUCCESS)
				{
					psdReopenButtonRelayId = GetPsdReOpenRelayId(psdId);
					/*屏蔽门开门按钮状态更新*/
					if ((0u != psdReopenButtonRelayId) && (UINT16_MAX != psdReopenButtonRelayId))
					{/*站台开门按钮继电器ID有效*/
						chPsdReOpenRelayState = GetRelayCollState(psdReopenButtonRelayId);
						if (RELAY_STATE_UP == chPsdReOpenRelayState)
						{
							dwCycNum = GetPOBPressCycNum(psdId);
							if (0u == dwCycNum)
							{/*若未计时，则设置起始周期*/
								(void)SetPOBPressCycNum(psdId, Get2oo2CurCycleNum());
							}
							reVal = SetPsdOpenButtonState(psdId, PSD_OPEN_BUTTON_STATE_VALID);
						}
						else if (RELAY_STATE_DOWN == chPsdReOpenRelayState)
						{
							(void)SetPOBPressCycNum(psdId, 0u);	/*清除POB按下起始周期号*/
							reVal = SetPsdOpenButtonState(psdId, PSD_OPEN_BUTTON_STATE_INVALID);
						}
						else
						{
							(void)SetPOBPressCycNum(psdId, 0u);	/*清除POB按下起始周期号*/
							reVal = CI_ERROR;
						}
					}
					else
					{/*有些线路PSD不配置开门按钮继电器，continue，继续执行*/
					}

				}

				if (reVal == CI_SUCCESS)
				{/*PDB按钮状态更新-PSL门控箱的PDB按钮与清客确认箱中PDB按钮一样的处理*/
					reVal = PsdCleFarePDBRelToDevStaProc(psdId);
				}

				if (reVal == CI_SUCCESS)
				{/*清客确认箱关门按钮状态更新*//*by cgh 20230526*/
					reVal = PsdCleFarePCBRelToDevStaProc(psdId);
				}
			}

		}
		if (reVal == CI_ERROR)
		{
			break;
		}
	}
}

#if 0
/*
* 功能描述： 屏蔽门状态转移处理函数
* 参数说明： void
* 返回值  ： void
*/
void PsdStateTransferProc(void)
{
	UINT16 ii = 0u;		 /*游标*/
	UINT16 jj = 0u;
	UINT16 psdId = 0u;	 /*屏蔽门ID*/
	UINT8 vobcToCiDataSum = GetVobcToCiSum();
	UINT16* routeIdBuf = NULL;
	UINT8* PsdOpenedBeforeSigCloseFlagBuf = NULL;
	RouteNearPhySectionStruct* routeNearPhySectionStruct = NULL;
	UINT16 phySecId = 0u;
	UINT8 routeSum = 0u;


	VobcToCiDataStruct* vobcToCiDataStru = GetVobcToCiDataStru();
	for (ii = 0u; ii < vobcToCiDataSum; ii++)
	{
		for (jj = 0u; jj < vobcToCiDataStru[ii].PsdSum; jj++)
		{
			psdId = vobcToCiDataStru[ii].PsdData[jj].PsdId;
			/*屏蔽门状态转移处理*/
			switch (GetPsdStateTransferFlag(psdId))
			{
			case PSD_INITIAL_STATE:
				SetBuildedOutStationRouteSum(psdId, 0u);
				break;
			case PSD_OPEN_CMD:
				if ((Get2oo2CurCycleNum() - vobcToCiDataStru[ii].PsdData[jj].CmdStartCycNum) > GetCiAndVobcTransBadEnsureCnt())
				{/*已经超时*/
					if (PSD_STATE_OPEN != GetPsdState(psdId))
					{/*屏蔽门还未成功打开则PsdStateTransferFlag 恢复成初始状态*/
						SetPsdStateTransferFlag(psdId, PSD_INITIAL_STATE);
						SetBuildedOutStationRouteSum(psdId, 0u);
					}
				}
				else
				{/*未超时*/
					if (PSD_STATE_OPEN == GetPsdState(psdId))
					{/*屏蔽门成功打开则PsdStateTransferFlag 转移到门成功打开状态*/
						SetPsdStateTransferFlag(psdId, PSD_OPEN_STATE);

					}
				}
				break;
			case PSD_OPEN_STATE:
				CalculatePsdOpenedLeadToSignalCloseRoute(psdId, 0u);/*对屏蔽门开导致出站进路信号关闭的出站进路进行记录*/
				if ((Get2oo2CurCycleNum() - vobcToCiDataStru[ii].PsdData[jj].CmdStartCycNum) > GetCiAndVobcTransBadEnsureCnt())
				{/*已经超时*/
					if ((PSD_STATE_CLOSE == GetPsdState(psdId)) ||
						(PSD_MUTUALLOCK_REMOVE_YES == GetPsdMutualLockRemoveState(psdId)))
					{/*没有收到关门命令，门却关闭，则PsdStateTransferFlag 恢复成初始状态*/
						SetPsdStateTransferFlag(psdId, PSD_INITIAL_STATE);
						SetBuildedOutStationRouteSum(psdId, 0u);
					}
				}
				break;
			case PSD_CLOSE_CMD:
				if ((Get2oo2CurCycleNum() - vobcToCiDataStru[ii].PsdData[jj].CmdStartCycNum) > GetCiAndVobcTransBadEnsureCnt())
				{/*已经超时*/
					if ((PSD_STATE_CLOSE != GetPsdState(psdId)) &&
						(PSD_MUTUALLOCK_REMOVE_YES != GetPsdMutualLockRemoveState(psdId)))
					{ /*已经超时，门未成功关闭，则PsdStateTransferFlag 恢复成初始状态*/
						SetPsdStateTransferFlag(psdId, PSD_INITIAL_STATE);
						SetBuildedOutStationRouteSum(psdId, 0u);
					}


				}
				else
				{
					if ((PSD_STATE_CLOSE == GetPsdState(psdId)) ||
						(PSD_MUTUALLOCK_REMOVE_YES == GetPsdMutualLockRemoveState(psdId)))
					{/*门成功关闭，则PsdStateTransferFlag 转移到门成功关闭状态*/
						SetPsdStateTransferFlag(psdId, PSD_CLOSE_STATE);
					}

				}
				break;
			case PSD_CLOSE_STATE:
				/*什么也不做*/
				break;
			default:
				break;
			}

			/*触发信号重开处理*/
			if (PSD_CLOSE_STATE == GetPsdStateTransferFlag(psdId))
			{/*屏蔽门状态正常转移一轮*/
				routeSum = GetBuildedOutStationRouteSum(psdId);    /*获取由于屏蔽门打开造成出站进路信号关闭的出站进路数目*/
				routeIdBuf = GetBuildedOutStationRouteIdBuf(psdId);/*获取由于屏蔽门打开造成出站进路信号关闭的出站进路Id数组*/
				PsdOpenedBeforeSigCloseFlagBuf = GetPsdOpenBeforeOutStationRouteIsBuildedFlagBuf(psdId);
				if ((1 == routeSum) && (PSD_OPEN_BEFORE_SIG_CLOSE_NO == PsdOpenedBeforeSigCloseFlagBuf[0u]))
				{/*有一条已经办理出来的出站进路(非自动进路 && 信号关闭在屏蔽门开之后发生):对此出站进路进行重开信号检查与处理*/

					routeNearPhySectionStruct = GetRouteBlocNearPhySectionStru(routeIdBuf[0u]);/*获取进路接近区段结构体*/
					if (NULL != routeNearPhySectionStruct)
					{/*存在接近区段*/
						phySecId = routeNearPhySectionStruct[0u].NearPhySecIdBuf[0u];/*获取接近区段第一个物理区段ID*/
						if (0u == phySecId)
						{/*第一个物理区段ID为0u*/
							SetPsdStateTransferFlag(psdId, PSD_INITIAL_STATE);
							SetBuildedOutStationRouteSum(psdId, 0u);
						}
						else
						{/*找到接近区段第一个物理区段ID*/
							if (0u != GetSecCurOccupyStartCycNum(phySecId))
							{/*列车顺序占压站台轨*/
								SetRouteRepeatOpenFlag(routeIdBuf[0u], ROUTE_REPEATOPEN_SET_YES);  /*设置进路信号重开标志*/
								SetRouteOpenSigStartCycNum(routeIdBuf[0u], Get2oo2CurCycleNum());  /*设置信号开放时间*/
								SetPsdStateTransferFlag(psdId, PSD_INITIAL_STATE);
								SetBuildedOutStationRouteSum(psdId, 0u);
							}
							else
							{/*故障占用即非正常顺序占用*/
								SetPsdStateTransferFlag(psdId, PSD_INITIAL_STATE);
								SetBuildedOutStationRouteSum(psdId, 0u);
							}
						}
					}
					else
					{/*不存在接近区段*/
						SetPsdStateTransferFlag(psdId, PSD_INITIAL_STATE);
						SetBuildedOutStationRouteSum(psdId, 0u);
					}

				}
				else
				{/*未办理出出站进路 || 办理出大于1条出站进路  :这种情况联锁软件不重开信号*/
					SetPsdStateTransferFlag(psdId, PSD_INITIAL_STATE);
					SetBuildedOutStationRouteSum(psdId, 0u);
				}
			}
		}
	}



}
#endif


/*
* 功能描述： 更新屏蔽门继电器状态
* 参数说明： void
* 返回值  ： 0u: 更新失败
*			 1: 更新成功
*/
UINT8 PsdDeviceToRelayStateProc(void)
{
	UINT16 ii = 0u;		/*游标*/
	UINT16 psdSum = 0u;	/*psd总数*/
	UINT16 psdId = 0u;	/*屏蔽门ID*/
	UINT16 psdKMRelayId = 0u;/*开门继电器ID*/
	UINT16 tmpPsdKMRelayId = 0u;/*开门继电器ID*/
	UINT16 psdGMRelayId = 0u;/*关门继电器ID*/
	UINT16 psdEditGroupInfo = 0u;/*屏蔽门编组信息*/
	UINT8 vobcInterFlag = 0u;/*vobc接口标识*/
	UINT16 startJXTCRelayId = 0u;		/*启动间隙探测继电器ID*/
	UINT16 stopJXTCRelayId = 0u;			/*停止间隙探测继电器ID*/
	UINT16 vobcDoorStateRelayId = 0u;    /*车门关门状态继电器ID*/
	UINT8 reVal = CI_SUCCESS;
	UINT8 doorState = 0u;/*车门状态继电器*/
	UINT8 JXCTInterfaceType = 0u;
	UINT8 psdDriveState = 0u;
	UINT8 JXTCStartState = 0u;
	UINT8 JXTCStopState = 0u;
	UINT8 psdVirtualState = 0u;
	UINT8 relayFlag = CI_ERROR;

	vobcInterFlag = GetCiFunctionSwitchConfig(VOBC_INTERFACE_IDENTITY);/*获取VOBC接口标识*/


	psdSum = GetPsdSum();
	for (ii = 0u; ii < psdSum; ii++)
	{
		psdId = GetPsdId(ii);
		psdVirtualState = GetPsdVirtualAttribute(psdId);
		if (PSD_VIRTUAL_ATTR_NO == psdVirtualState)
		{/*非虚拟屏蔽门才驱动相关继电器*/
			psdEditGroupInfo = GetPsdEditGroupInfoFromPsdData(psdId);
			/*编组定义统一化处理*/
			if ((LINE_HLHT == vobcInterFlag) || (LINE_FAOHLHT == vobcInterFlag) || (LINE_FAOHLHT_ONESELF == vobcInterFlag) || (LINE_FAOHLHT_ONESELFSECOND == vobcInterFlag))
			{
				/*互联互通和FAO互联互通的编组信息由VOBC发送*/
			}
			else if (LINE_FAO == vobcInterFlag)
			{
				if (PSD_FOUR_EDIT_GROUP_FAO_YF == psdEditGroupInfo)/*燕房线4编组*/
				{
					psdEditGroupInfo = PSD_FOUR_EDIT_GROUP;
				}
				else if (PSD_SIX_EDIT_GROUP_FAO_YF == psdEditGroupInfo)/*燕房线6编组*/
				{
					psdEditGroupInfo = PSD_SIX_EDIT_GROUP;
				}
				else
				{
					/*编组信息错误*/
				}
			}
			else
			{
				/*线路信息错误，do nothing*/
			}

			if (PSD_FOUR_EDIT_GROUP == psdEditGroupInfo)
			{/*四编组屏蔽门*/
				psdKMRelayId = GetFourGroupPsdOpenDrvRelayId(psdId);
			}
			else if (PSD_SIX_EDIT_GROUP == psdEditGroupInfo)
			{/*六编组屏蔽门*/
				psdKMRelayId = GetSixGroupPsdOpenDrvRelayId(psdId);
			}
			else if (PSD_EIGHT_EDIT_GROUP == psdEditGroupInfo)
			{/*八编组屏蔽门*/
				psdKMRelayId = GetEightGroupPsdOpenDrvRelayId(psdId);
			}
			else
			{/*编组无效*/
				psdKMRelayId = 0u;
			}
			psdGMRelayId = GetPsdCloseDriveRelayId(psdId);
			psdDriveState = GetPsdDriveState(psdId);

			if (PSD_DRIVE_STATE_CLOSE == psdDriveState)/*驱动为关门*/
			{
				relayFlag = SetRelayDriveState(psdGMRelayId, RELAY_DRIVE_STATE_UP);
				if (CI_ERROR == relayFlag)
				{/*关门继电器*/
					reVal = CI_ERROR;
				}
				else
				{
					tmpPsdKMRelayId = GetFourGroupPsdOpenDrvRelayId(psdId);
					if (tmpPsdKMRelayId > 0u)
					{
						relayFlag = SetRelayDriveState(tmpPsdKMRelayId, RELAY_DRIVE_STATE_DOWN);
						/*所有开门继电器驱落下*/
						if (CI_ERROR == relayFlag)
						{/*开门继电器*/
							reVal = CI_ERROR;
						}

					}
					tmpPsdKMRelayId = GetSixGroupPsdOpenDrvRelayId(psdId);
					if (tmpPsdKMRelayId > 0u)
					{
						relayFlag = SetRelayDriveState(tmpPsdKMRelayId, RELAY_DRIVE_STATE_DOWN);
						/*所有开门继电器驱落下*/
						if (CI_ERROR == relayFlag)
						{/*开门继电器*/
							reVal = CI_ERROR;
						}
					}


					tmpPsdKMRelayId = GetEightGroupPsdOpenDrvRelayId(psdId);
					if (tmpPsdKMRelayId > 0u)
					{
						/*所有开门继电器驱落下*/
						relayFlag = SetRelayDriveState(tmpPsdKMRelayId, RELAY_DRIVE_STATE_DOWN);
						if (CI_ERROR == relayFlag)
						{/*开门继电器*/
							reVal = CI_ERROR;
						}
					}

				}
			}
			else if (PSD_DRIVE_STATE_OPEN == psdDriveState)/*驱动为开门*/
			{
				if (0u != psdKMRelayId)
				{/*获取继电器有效*/
					/*修改前：互锁解除时不响应VOBC的开关PSD命令，对外驱动无效*/
					/*修改后：对外输出时不再判断是否互锁解除状态（需求变化）*/
					relayFlag = SetRelayDriveState(psdGMRelayId, RELAY_DRIVE_STATE_DOWN);
					if (CI_ERROR == relayFlag)
					{/*关门继电器*/
						reVal = CI_ERROR;
					}
					else
					{
						relayFlag = SetRelayDriveState(psdKMRelayId, RELAY_DRIVE_STATE_UP);
						if (CI_ERROR == relayFlag)
						{/*开门继电器*/
							reVal = CI_ERROR;
						}
					}


				}
			}
			else if (PSD_DRIVE_STATE_INVALID == psdDriveState)
			{/*驱动无效*/
				relayFlag = SetRelayDriveState(psdGMRelayId, RELAY_DRIVE_STATE_DOWN);
				if (CI_ERROR == relayFlag)
				{/*关门继电器*/
					reVal = CI_ERROR;
				}
				else
				{
					tmpPsdKMRelayId = GetFourGroupPsdOpenDrvRelayId(psdId);
					if (tmpPsdKMRelayId > 0u)
					{
						/*所有开门继电器驱落下*/
						relayFlag = SetRelayDriveState(tmpPsdKMRelayId, RELAY_DRIVE_STATE_DOWN);
						if (CI_ERROR == relayFlag)
						{/*开门继电器*/
							reVal = CI_ERROR;
						}

					}
					tmpPsdKMRelayId = GetSixGroupPsdOpenDrvRelayId(psdId);
					if (tmpPsdKMRelayId > 0u)
					{
						/*所有开门继电器驱落下*/
						relayFlag = SetRelayDriveState(tmpPsdKMRelayId, RELAY_DRIVE_STATE_DOWN);
						if (CI_ERROR == relayFlag)
						{/*开门继电器*/
							reVal = CI_ERROR;
						}
					}


					tmpPsdKMRelayId = GetEightGroupPsdOpenDrvRelayId(psdId);
					if (tmpPsdKMRelayId > 0u)
					{
						/*所有开门继电器驱落下*/
						relayFlag = SetRelayDriveState(tmpPsdKMRelayId, RELAY_DRIVE_STATE_DOWN);
						if (CI_ERROR == relayFlag)
						{/*开门继电器*/
							reVal = CI_ERROR;
						}
					}
				}
			}
			else
			{/*不应出现的值*/
				reVal = CI_ERROR;
			}

			if ((LINE_FAOHLHT == vobcInterFlag)||(LINE_CC == vobcInterFlag) || (LINE_FAOHLHT_ONESELF == vobcInterFlag) || (LINE_FAOHLHT_ONESELFSECOND == vobcInterFlag))
			{/*当前只有互联互通FAO线路有间隙探测功能*/
				/*联锁根据VOBC启动间隙探测命令和停止间隙探测命令来驱动相应继电器*/
				startJXTCRelayId = GetPsdDetStartRelayId(psdId);	/*获取启动间隙探测继电器ID*/
				stopJXTCRelayId = GetPsdDetStopRelayId(psdId);	/*获取停止间隙探测继电器ID*/
				JXCTInterfaceType = GetCiFunctionSwitchConfig(FUNC_JXTC_INTERFACE_MODE);/*获取接口方式*/
				/*启动间隙探测继电器ID有效*/
				if ((0u != startJXTCRelayId) && (0u != stopJXTCRelayId))
				{
					/*采用脉冲*/
					if (FUNC_SWITCH_ON == JXCTInterfaceType)
					{
						/*处理启动和停止驱动*/
						ProcessJXTCPulseInterfStartDrv(startJXTCRelayId, stopJXTCRelayId, psdId);
						ProcessJXTCPulseInterfStopDrv(startJXTCRelayId, stopJXTCRelayId, psdId);

					}
					/*电平模式*/
					else
					{
						JXTCStartState = GetStartDetectionState(psdId);
						JXTCStopState = GetStopDetectionState(psdId);
						if (JXTC_START_DETECTION_YES == JXTCStartState)
						{
							if (0u == GetStartDetectionCycNum(psdId))
							{/*若未计时，则设置驱动启动探测继电器周期*/
								SetStartDetectionCycNum(psdId, Get2oo2CurCycleNum());
							}
							relayFlag = SetRelayDriveState(startJXTCRelayId, RELAY_DRIVE_STATE_UP);
							if (CI_ERROR == relayFlag)
							{/*启动探测继电器吸起*/
								reVal = CI_ERROR;
							}
							else
							{
								relayFlag = SetRelayDriveState(stopJXTCRelayId, RELAY_DRIVE_STATE_DOWN);
								if (CI_ERROR == relayFlag)
								{/*停止探测继电器落下*/
									reVal = CI_ERROR;
								}
							}
						}
						else
						{
							SetStartDetectionCycNum(psdId, 0u);	/*清除间隙探测开始时间*/
							relayFlag = SetRelayDriveState(startJXTCRelayId, RELAY_DRIVE_STATE_DOWN);
							if (CI_ERROR == relayFlag)
							{/*启动探测继电器落下*/
								reVal = CI_ERROR;
							}
						}

						/*停止间隙探测继电器ID有效*/
						if (JXTC_STOP_DETECTION_YES == JXTCStopState)
						{   /*停止探测状态时，设置停止探测继电器吸起*/
							relayFlag = SetRelayDriveState(stopJXTCRelayId, RELAY_DRIVE_STATE_UP);
							if (CI_ERROR == relayFlag)
							{/*停止探测继电器吸起*/
								reVal = CI_ERROR;
							}
							else
							{
								relayFlag = SetRelayDriveState(startJXTCRelayId, RELAY_DRIVE_STATE_DOWN);
								if (CI_ERROR == relayFlag)
								{/*启动探测继电器落下*/
									reVal = CI_ERROR;
								}
							}
						}
						else
						{
							relayFlag = SetRelayDriveState(stopJXTCRelayId, RELAY_DRIVE_STATE_DOWN);
							if (CI_ERROR == relayFlag)
							{/*停止探测继电器落下*/
								reVal = CI_ERROR;
							}
						}
					}
				}

				vobcDoorStateRelayId = GetPsdDoorStateRelayId(psdId);	/*获取车门关门状态继电器ID*/
				if (0u != vobcDoorStateRelayId)
				{/*获取车门关门状态继电器ID有效*/
					doorState = GetVOBCDoorState(psdId);
					if (PSD_DOOR_CLOSEDANDLOCKED_VALID == doorState)
					{/*车门关门状态为关闭且锁闭*/
						relayFlag = SetRelayDriveState(vobcDoorStateRelayId, RELAY_DRIVE_STATE_UP);
						if (CI_ERROR == relayFlag)
						{/*启动车门关门继电器*/
							reVal = CI_ERROR;
						}
					}
					else if (PSD_DOOR_CLOSEDANDLOCKED_INVALID == doorState)
					{/*车门关门状态为非关闭且锁闭*/
						relayFlag = SetRelayDriveState(vobcDoorStateRelayId, RELAY_DRIVE_STATE_DOWN);
						if (CI_ERROR == relayFlag)
						{/*停止车门关门继电器*/
							reVal = CI_ERROR;
						}
					}
					else
					{
						/*车门关门状态无效无操作继电器*/
					}
				}
				/*站台清客，闪灯稳灯处理*/
				StationCearPassenagerProcess(psdId);
				/*by cgh 成都四线清客需求--清客确认箱发车按钮指示灯闪灯处理*/
				PsdCleFarePDBFlashProcess(psdId);
				/*成都13、27、30三线再开门/再关门按钮表示灯处理*/
				PsdOpenAndCloseBsdProc(psdId);
				/*by cgh 屏蔽门视频清客处理*/
				PsdVideoQkDriveStateProc(psdId);
			}
		}
		else
		{
			/*虚拟屏蔽门或虚拟属性获取失败*/
		}
	}

	return reVal;
}

/*
* 功能描述： 间隙探测脉冲接口方式启动驱动处理
* 参数说明： UINT16 startJXTCRelayId 启动继电器
			 UINT16 stopJXTCRelayId 停止继电器
			 UINT16 psdId 屏蔽门ID
* 返回值  ： 无
*/
void ProcessJXTCPulseInterfStartDrv(UINT16 startJXTCRelayId, UINT16 stopJXTCRelayId, UINT16 psdId)
{
	/*变量初始化*/
	UINT32 JXTCStarCycNum = 0u;
	UINT8 JXTCState = 0u;     /*间隙探测状态*/
	UINT8 jxtcStarFlag = 0u;
	UINT8 startRelayState = 0u; /*继电器状态*/
	UINT32 JXTCdriveCount = 0u;
	UINT8 secStopTimeState = 0u;
	UINT32 JXTCStartCount = 0u;
	UINT32 CIPresentCycNum = 0u;
	UINT8 jxtcStopCmdState = 0u;
	UINT8 jxtcStartCmdState = 0u;


	/*获取初始数值*/
	JXTCStarCycNum = GetStartDetectionCycNum(psdId);
	CIPresentCycNum = Get2oo2CurCycleNum();
	jxtcStartCmdState = GetStartDetectionState(psdId);
	jxtcStopCmdState = GetStopDetectionState(psdId);
	jxtcStarFlag = GetJXTCDriveStartFlag(psdId);

	/*启动间隙探测*/
	if ((JXTC_START_DETECTION_YES == jxtcStartCmdState) && (JXTC_STOP_DETECTION_NO == jxtcStopCmdState))
	{
		/*设置未驱动停止*/
		SetJXTCDriveStopFlag(psdId, JXTC_DRIVE_START_STOP_NO);
		/*间隙探测驱动启动标志未设置*/
		if (JXTC_DRIVE_START_STOP_NO == jxtcStarFlag)
		{
			if (0u == JXTCStarCycNum)
			{/*若未计时，则设置驱动启动探测继电器周期*/
				SetStartDetectionCycNum(psdId, CIPresentCycNum);
			}

			/*驱动停止落下*/
			(void)SetRelayDriveState(stopJXTCRelayId, RELAY_DRIVE_STATE_DOWN);

			/*获取间隙探测所处状态：起始状态、驱动脉冲状态、结束状态*/
			JXTCState = GetJXTCStartState(psdId);
			/*起始状态*/
			if (JXTC_NO_DRIVE_STATE == JXTCState)
			{
				/*清驱动计时时间*/
				SetJXTCStartUpCycNum(psdId, 0u);
				/*驱动启动继电器*/
				(void)SetRelayDriveState(startJXTCRelayId, RELAY_DRIVE_STATE_UP);

				/*采集启动吸起*/
				startRelayState = GetRelayCollState(startJXTCRelayId);
				if (RELAY_STATE_UP == startRelayState)
				{
					/*设置间隙探测开始继电器吸起周期*/
					SetJXTCStartUpCycNum(psdId, CIPresentCycNum);
					/*设置状态2*/
					SetJXTCStartState(psdId, JXTC_DRIVE_UP_KEEP_STATE);
				}
			}
			/*步骤2：保持驱动一定时间*/
			else if (JXTC_DRIVE_UP_KEEP_STATE == JXTCState)
			{
				/*驱动启动*/
				(void)SetRelayDriveState(startJXTCRelayId, RELAY_DRIVE_STATE_UP);
				/*计时*/
				JXTCStartCount = GetJXTCStartUpCycNum(psdId);
				JXTCdriveCount = GetJXTCPulseContinueTimeCount();
				secStopTimeState = SystemOverTimeCheck(JXTCStartCount, JXTCdriveCount);
				startRelayState = GetRelayCollState(startJXTCRelayId);
				/*超时*/
				if (CI_TIME_OUT == secStopTimeState)
				{
					/*步骤3*/
					SetJXTCStartState(psdId, JXTC_DRIVE_DOWN_STATE);
				}
				else
				{
					/*采集落下，返回步骤1*/
					if (RELAY_STATE_DOWN == startRelayState)
					{
						SetJXTCStartState(psdId, JXTC_NO_DRIVE_STATE);
					}
				}
			}
			/*步骤3：回采落下，再跳转*/
			else if (JXTC_DRIVE_DOWN_STATE == JXTCState)
			{
				/*启动驱动落下*/
				(void)SetRelayDriveState(startJXTCRelayId, RELAY_DRIVE_STATE_DOWN);
				startRelayState = GetRelayCollState(startJXTCRelayId);
				/*采集落下*/
				if (RELAY_STATE_DOWN == startRelayState)
				{
					/*回到步骤1*/
					SetJXTCStartState(psdId, JXTC_NO_DRIVE_STATE);
					/*设置已驱动启动标志*/
					SetJXTCDriveStartFlag(psdId, JXTC_DRIVE_START_STOP_YES);
				}
			}
			else
			{
				/*跳到步骤1*/
				SetJXTCStartState(psdId, JXTC_NO_DRIVE_STATE);
			}
		}
	}
	/*间隙探测启动命令无效*/
	else
	{
		SetStartDetectionCycNum(psdId, 0u);	/*清除间隙探测开始时间*/
		(void)SetRelayDriveState(startJXTCRelayId, RELAY_DRIVE_STATE_DOWN);
		/*清计时，设为步骤1*/
		SetJXTCStartState(psdId, JXTC_NO_DRIVE_STATE);
		SetJXTCStartUpCycNum(psdId, 0u);
		/*设置没有驱动*/
		SetJXTCDriveStartFlag(psdId, JXTC_DRIVE_START_STOP_NO);
	}
}

/*
* 功能描述： 间隙探测脉冲接口方式停止驱动处理
* 参数说明： UINT16 startJXTCRelayId 启动继电器
			 UINT16 stopJXTCRelayId 停止继电器
			 UINT16 psdId 屏蔽门ID
* 返回值  ： 无
*/
void ProcessJXTCPulseInterfStopDrv(UINT16 startJXTCRelayId, UINT16 stopJXTCRelayId, UINT16 psdId)
{
	/*变量初始化*/
	UINT8 JXTCState = 0u;
	UINT8 stopRelayState = 0u;
	UINT32 CIPresentCycNum = 0u;
	UINT32 JXTCStopCount = 0u;
	UINT32 JXTCdriveCount = 0u;
	UINT8 secStopTimeState = 0u;
	UINT8 jxtcStopFlag = 0u;
	UINT8 jxtcStopCmdState = 0u;
	UINT8 jxtcStartCmdState = 0u;

	jxtcStopCmdState = GetStopDetectionState(psdId);
	jxtcStartCmdState = GetStartDetectionState(psdId);
	CIPresentCycNum = Get2oo2CurCycleNum();
	jxtcStopFlag = GetJXTCDriveStopFlag(psdId);

	/*间隙探测停止命令有效*/
	if ((JXTC_STOP_DETECTION_YES == jxtcStopCmdState) && (JXTC_START_DETECTION_NO == jxtcStartCmdState))
	{
		/*设置不驱动启动*/
		SetJXTCDriveStartFlag(psdId, JXTC_DRIVE_START_STOP_NO);
		/*未驱动停止*/
		if (JXTC_DRIVE_START_STOP_NO == jxtcStopFlag)
		{
			/*启动落下*/
			(void)SetRelayDriveState(startJXTCRelayId, RELAY_DRIVE_STATE_DOWN);
			/*获取间隙探测状态*/
			JXTCState = GetJXTCStopState(psdId);
			if (JXTC_NO_DRIVE_STATE == JXTCState)
			{
				/*清驱动计时时间*/
				SetJXTCStopUpCycNum(psdId, 0u);
				/*设置停止吸起*/
				(void)SetRelayDriveState(stopJXTCRelayId, RELAY_DRIVE_STATE_UP);

				stopRelayState = GetRelayCollState(stopJXTCRelayId);
				if (RELAY_STATE_UP == stopRelayState)
				{
					/*设置间隙探测开始继电器吸起周期*/
					SetJXTCStopUpCycNum(psdId, CIPresentCycNum);
					/*设置状态2*/
					SetJXTCStopState(psdId, JXTC_DRIVE_UP_KEEP_STATE);
				}
			}
			/*步骤2，保持驱动一定时间*/
			else if (JXTC_DRIVE_UP_KEEP_STATE == JXTCState)
			{
				/*设置停止吸起*/
				(void)SetRelayDriveState(stopJXTCRelayId, RELAY_DRIVE_STATE_UP);
				/*计时*/
				JXTCStopCount = GetJXTCStopUpCycNum(psdId);
				JXTCdriveCount = GetJXTCPulseContinueTimeCount();
				secStopTimeState = SystemOverTimeCheck(JXTCStopCount, JXTCdriveCount);
				stopRelayState = GetRelayCollState(stopJXTCRelayId);
				/*超时*/
				if (CI_TIME_OUT == secStopTimeState)
				{
					/*步骤3*/
					SetJXTCStopState(psdId, JXTC_DRIVE_DOWN_STATE);
				}
				else
				{
					/*采集落下，回到步骤1*/
					if (RELAY_STATE_DOWN == stopRelayState)
					{
						/*回到步骤1*/
						SetJXTCStopState(psdId, JXTC_NO_DRIVE_STATE);
					}
				}
			}
			/*步骤3，回采落下状态*/
			else if (JXTC_DRIVE_DOWN_STATE == JXTCState)
			{
				/*停止驱动落下*/
				(void)SetRelayDriveState(stopJXTCRelayId, RELAY_DRIVE_STATE_DOWN);
				stopRelayState = GetRelayCollState(stopJXTCRelayId);
				/*采集落下*/
				if (RELAY_STATE_DOWN == stopRelayState)
				{
					/*回到步骤1*/
					SetJXTCStopState(psdId, JXTC_NO_DRIVE_STATE);
					/*设置驱动停止*/
					SetJXTCDriveStopFlag(psdId, JXTC_DRIVE_START_STOP_YES);
				}
			}
			else
			{
				/*跳到步骤1*/
				SetJXTCStopState(psdId, JXTC_NO_DRIVE_STATE);
			}
		}
	}
	/*间隙探测停止命令无效*/
	else
	{
		(void)SetRelayDriveState(stopJXTCRelayId, RELAY_DRIVE_STATE_DOWN);
		/*清计时，设为步骤1*/
		SetJXTCStopState(psdId, JXTC_NO_DRIVE_STATE);
		SetJXTCStopUpCycNum(psdId, 0u);
		SetJXTCDriveStopFlag(psdId, JXTC_DRIVE_START_STOP_NO);
	}
}


/*
* 功能描述： 更新洗车机继电器状态
* 参数说明： void
* 返回值  ： 0u: 更新失败
*			 1: 更新成功
*/
UINT8 WashMachineDevToRelayStaProc(void)
{
	UINT16 ii = 0u;		                                                    /*游标*/
	UINT16 washMachineSum = 0u;	                                            /*洗车机总数*/
	UINT16 washMachineId = 0u;                                               /*洗车机ID*/
	UINT16 WashTrainRequestRelayId = 0u;                                         /*洗车请求继电器*/
	UINT16 TrainHeadStopSteadyRelayId = 0u;                                      /*车头停稳继电器*/
	UINT16 TrainTailStopSteadyRelayId = 0u;                                      /*车尾停稳继电器*/
	UINT16 pauseTrainWashRelayId = 0u;											/*暂停洗车继电器*/
	UINT16 passRequestRelayId = 0u;                                              /*通过请求继电器*/
	UINT8 retVal = CI_SUCCESS;
	UINT8 lineIdentity = 0u;														/*CI-VOBC接口标识*/

	UINT8 xtaLogicState = 0u;/*洗车同意按钮逻辑状态*/

	lineIdentity = GetCiFunctionSwitchConfig(VOBC_INTERFACE_IDENTITY);/*获取CI-VOBC接口标识*/

	washMachineSum = GetWashMachineSum();                                   /*获取洗车机当前总数*/

	for (ii = 0u; ii < washMachineSum; ii++)
	{

		washMachineId = GetWashMachineId(ii);
		if (CI_ERROR == washMachineId)
		{
			retVal = CI_ERROR;
		}
		if (CI_SUCCESS == retVal)
		{
			WashTrainRequestRelayId = GetWashTrainRequestRelayId(washMachineId);     /*获取洗车请求继电器，合肥为洗车同意状态继电器*/

			if (0u != WashTrainRequestRelayId)
			{/*洗车请求继电器ID有效*/
				if (LINE_HLHT == lineIdentity)
				{/*互联互通线路，洗车请求继电器即反向通过同意继电器XTJ*/
					xtaLogicState = GetWashmachineXTALogicState(washMachineId);
					if (XTA_STATE_PRESS_DOWN == xtaLogicState)
					{/*CI检查到同意按钮逻辑状态按下，驱动洗车同意继电器吸起*/
						if (CI_ERROR == SetRelayDriveState(WashTrainRequestRelayId, RELAY_STATE_UP))
						{/*反向通过同意继电器*/
							retVal = CI_ERROR;
						}
					}
					else
					{/*驱动洗车同意继电器落下*/
						if (CI_ERROR == SetRelayDriveState(WashTrainRequestRelayId, RELAY_STATE_DOWN))
						{/*反向通过同意继电器*/
							retVal = CI_ERROR;
						}
					}
				}
				else
				{/*其他线路类型*/
					if (WASHMACHINE_DRVSTATE_REQ_TRUE == GetWashTrainRequestDrvState(washMachineId))
					{
						if (CI_ERROR == SetRelayDriveState(WashTrainRequestRelayId, RELAY_STATE_UP))
						{/*洗车请求继电器*/
							retVal = CI_ERROR;
						}
					}
					else if (WASHMACHINE_DRVSTATE_REQ_FALSE == GetWashTrainRequestDrvState(washMachineId))
					{
						if (CI_ERROR == SetRelayDriveState(WashTrainRequestRelayId, RELAY_STATE_DOWN))
						{/*洗车请求继电器*/
							retVal = CI_ERROR;
						}
					}
					else
					{
						if (CI_ERROR == SetRelayDriveState(WashTrainRequestRelayId, RELAY_STATE_DOWN))
						{/*洗车请求继电器*/
							retVal = CI_ERROR;
						}
					}
				}
			}
			else
			{
				/*未配置该继电器，继续执行*/
			}

		}
		if (CI_SUCCESS == retVal)
		{
			TrainHeadStopSteadyRelayId = GetTrainHeadStopSteadyRelayId(washMachineId);             /*获取头部洗位停稳继电器*/

			if (0u != TrainHeadStopSteadyRelayId)
			{/*头部洗位停稳继电器ID有效*/
				if (WASHMACHINE_HEAD_STEADY_YES == GetTrainHeadStopSteadyDrvState(washMachineId))
				{
					if (CI_ERROR == SetRelayDriveState(TrainHeadStopSteadyRelayId, RELAY_STATE_UP))
					{/*头端停稳继电器*/
						retVal = CI_ERROR;
					}
				}
				else if (WASHMACHINE_HEAD_STEADY_NO == GetTrainHeadStopSteadyDrvState(washMachineId))
				{
					if (CI_ERROR == SetRelayDriveState(TrainHeadStopSteadyRelayId, RELAY_STATE_DOWN))
					{/*头端停稳继电器**/
						retVal = CI_ERROR;
					}

				}
				else
				{
					if (CI_ERROR == SetRelayDriveState(TrainHeadStopSteadyRelayId, RELAY_STATE_DOWN))
					{/*头端停稳继电器**/
						retVal = CI_ERROR;
					}

				}
			}
			else
			{
				/*未配置该继电器，继续执行*/
			}

		}
		if (CI_SUCCESS == retVal)
		{
			TrainTailStopSteadyRelayId = GetTrainTailStopSteadyRelayId(washMachineId);             /*获取尾部洗位停稳继电器*/

			if (0u != TrainTailStopSteadyRelayId)
			{/*尾部洗位停稳继电器ID有效*/
				if (WASHMACHINE_TAIL_STEADY_YES == GetTrainTailStopSteadyDrvState(washMachineId))
				{
					if (CI_ERROR == SetRelayDriveState(TrainTailStopSteadyRelayId, RELAY_STATE_UP))
					{/*尾端停稳继电器*/
						retVal = CI_ERROR;
					}
				}
				else if (WASHMACHINE_TAIL_STEADY_NO == GetTrainTailStopSteadyDrvState(washMachineId))
				{
					if (CI_ERROR == SetRelayDriveState(TrainTailStopSteadyRelayId, RELAY_STATE_DOWN))
					{/*尾端停稳继电器*/
						retVal = CI_ERROR;
					}

				}
				else
				{
					if (CI_ERROR == SetRelayDriveState(TrainTailStopSteadyRelayId, RELAY_STATE_DOWN))
					{/*尾端停稳继电器*/
						retVal = CI_ERROR;
					}
				}
			}
			else
			{
				/*未配置该继电器，继续执行*/
			}

		}
		if (CI_SUCCESS == retVal)
		{
			pauseTrainWashRelayId = GetPauseTrainWashRelayId(washMachineId);		/*获取暂停洗车请求继电器*/

			if (0u != pauseTrainWashRelayId)
			{/*暂停洗车请求继电器ID有效*/
				if (WASHMACHINE_PAUSE_DRVREQ_TRUE == GetPauseTrainWashRequestDrvSta(washMachineId))
				{
					if (CI_ERROR == SetRelayDriveState(pauseTrainWashRelayId, RELAY_STATE_UP))
					{/*暂停洗车请求继电器*/
						retVal = CI_ERROR;
					}
				}
				else if (WASHMACHINE_PAUSE_DRVREQ_FALSE == GetPauseTrainWashRequestDrvSta(washMachineId))
				{
					if (CI_ERROR == SetRelayDriveState(pauseTrainWashRelayId, RELAY_STATE_DOWN))
					{/*暂停洗车请求继电器*/
						retVal = CI_ERROR;
					}
				}
				else
				{
					if (CI_ERROR == SetRelayDriveState(pauseTrainWashRelayId, RELAY_STATE_DOWN))
					{/*暂停洗车请求继电器*/
						retVal = CI_ERROR;
					}
				}
			}
			else
			{
				/*未配置该继电器，继续执行*/
			}

		}
		if (CI_SUCCESS == retVal)
		{
			passRequestRelayId = GetPassRequestRelayId(washMachineId);		/*获取通过请求继电器*/

			if (0u != passRequestRelayId)
			{/*通过请求继电器*/
				if (PASS_WASHMACHINE_DRVREQ_TRUE == GetPassWashMachineReqDrvSta(washMachineId))
				{
					if (CI_ERROR == SetRelayDriveState(passRequestRelayId, RELAY_STATE_UP))
					{/*通过请求继电器*/
						retVal = CI_ERROR;
					}
				}
				else if (PASS_WASHMACHINE_DRVREQ_FALSE == GetPassWashMachineReqDrvSta(washMachineId))
				{
					if (CI_ERROR == SetRelayDriveState(passRequestRelayId, RELAY_STATE_DOWN))
					{/*通过请求继电器*/
						retVal = CI_ERROR;
					}
				}
				else
				{
					if (CI_ERROR == SetRelayDriveState(passRequestRelayId, RELAY_STATE_DOWN))
					{/*通过请求继电器*/
						retVal = CI_ERROR;
					}
				}
			}
			else
			{
				/*未配置该继电器，继续执行*/
			}

		}
		if (CI_SUCCESS == retVal)
		{
			/*洗车模式继电器驱动处理*/
			retVal = WashMachineWorkModeRelayProc(washMachineId);
		}

		if (CI_SUCCESS == retVal)
		{
			/*降级洗车对应继电器驱动处理*/
			retVal = DownWashDevToRelayStaProc(washMachineId);
		}
	}

	return retVal;
}

/*
* 功能描述： 更新紧急停车按钮逻辑状态
* 参数说明： void
* 返回值  ： 0u: 更新失败
*			 1: 更新成功
*/
UINT8 EsbRelayToDeviceStateProc(void)
{
	UINT16 ii = 0u;		/*游标*/
	UINT16 esbSum = 0u;	/*esb总数*/
	UINT16 esbId = 0u;	/*紧急停车按钮ID*/
	UINT16 esbRelayId = 0u;/*紧急停车按钮继电器ID*/
	UINT16 wEsbRelayId2 = 0u;/*紧急停车按钮继电器ID*/
	UINT8 reVal = CI_ERROR;
	UINT8 relaySta = 0u;
	UINT16 esbRepRelayId = 0u;/*esb复视继电器ID*/
	UINT8 esbBelongCi = 0u;/*esb所属联锁*/
	UINT8 esbRepRelayBelongCi = 0u;/*esb复视继电器所属联锁*/
	UINT8 commState = 0u;/*通信状态*/
	/*相邻联锁是否支持继电接口*/
	UINT8 funcSwitchSupportRelayInterface = GetCiFunctionSwitchConfig(FUNC_SWITCH_USE_RELAY_INTERFACE_BETWEEN_NEIGHBOURCI);
	UINT8 localCi = GetSystemParaLocalCiId();/*本机联锁*/
	UINT16 esbCutRelayId = 0u;/*紧急停车按钮旁路继电器ID*/
	UINT8 chEsbVirtualAtt = 0U;
	UINT8 chEsbCutRelayState = 0U;
	UINT8 chEsbRelayState = 0U;
	UINT8 chEsbRelay2State = 0U;
	UINT8 chDsnLinSwitch = 0U;
	UINT8 funcswitchZfsBtn = 0U;      /*自复式按钮开关*/

	chDsnLinSwitch = GetCiFunctionSwitchConfig(FUNC_DSN_LINE_SWITCH);
	funcswitchZfsBtn = GetCiFunctionSwitchConfig(FUNC_ZIFUSHI_BUTTON);

	esbSum = GetTotalEsbCurNum();

	for (ii = 0u; ii < esbSum; ii++)
	{
		esbId = GetEsbId(ii);
		if (CI_ERROR == esbId)
		{
			reVal = CI_ERROR;
		}
		else
		{
			chEsbVirtualAtt = GetEsbVirtualAttribute(esbId);
			if (ESB_VIRTUAL_ATTR_YES != chEsbVirtualAtt)
			{/*不为虚拟设备才采集继电器状态*/
				esbRelayId = GetEsbRelayId(esbId);
				wEsbRelayId2 = GetEsbRelayId2(esbId);
				esbBelongCi = GetEsbBelongCiId(esbId);/*esb所属联锁*/
				if (esbBelongCi == localCi)
				{/*esb所属联锁为本联锁*/
					if (FUNC_SWITCH_ON != chDsnLinSwitch)
					{
						if (FUNC_SWITCH_ON == funcswitchZfsBtn)
						{
							/*自复式紧急停车按钮处理*/
							EsbZfsBtnProc(esbId);
							EsbZfsCancelBtnProc(esbId);
						}
						else if (FUNC_SWITCH_ESB_NINGXIANG_RAIL == funcswitchZfsBtn)
						{
							/*宁象市域铁路紧急停车处理：紧急按钮为普通按钮，紧急取消按钮和紧急旁路按钮为自复式按钮*/
							/*1.紧急关闭按钮处理*/
							EsbNXRailBtnProc(esbId);
							/*2.紧急关闭取消按钮处理*/
							EsbNXRailCancelBtnProc(esbId);
						}
						else
						{
							/*获取非自复式ESB当前需设置的状态*/
							chEsbRelayState = GetEsbCurNeedSetState(esbId);
							reVal = SetEsbState(esbId, chEsbRelayState);
						}
					}
					else
					{
						chEsbRelayState = GetRelayCollState(esbRelayId);
						chEsbRelay2State = GetRelayCollState(wEsbRelayId2);
						if ((RELAY_STATE_DOWN == chEsbRelayState) && (RELAY_STATE_DOWN == chEsbRelay2State))
						{
							reVal = SetEsbState(esbId, ESB_STATE_VALID_YES);
						}
						else if ((RELAY_STATE_UP == chEsbRelayState) && (RELAY_STATE_UP == chEsbRelay2State))
						{
							reVal = SetEsbState(esbId, ESB_STATE_VALID_NO);
						}
						else
						{
							reVal = SetEsbState(esbId, ESB_STATE_VALID_YES);
						}
					}

					if (FUNC_SWITCH_ESB_NINGXIANG_RAIL == funcswitchZfsBtn)
					{
						/*宁象市域铁路紧急关闭旁路按钮处理*/
						EsbNXRailCutBtnProc(esbId);
					}
					else
					{
						/*其它线路旁路状态处理*/
						esbCutRelayId = GetEsbCutRelayId(esbId);
						if (0u != esbCutRelayId)
						{   /*当没有配置旁路按钮时，不作处理*/
							chEsbCutRelayState = GetRelayCollState(esbCutRelayId);
							if (RELAY_STATE_DOWN == chEsbCutRelayState)
							{
								SetEsbCutState(esbId, ESB_CUT_NO);
							}
							else if (RELAY_STATE_UP == chEsbCutRelayState)
							{
								SetEsbCutState(esbId, ESB_CUT_YES);
							}
							else
							{
								SetEsbCutState(esbId, ESB_CUT_NO);
								reVal = CI_ERROR;
							}
						}
					}
				}
				else
				{/*esb不为本联锁*/
					esbRepRelayId = GetEsbRepRelayId(esbId);
					if (esbRepRelayId > 0u)
					{
						esbRepRelayBelongCi = GetRelayBelongCiId(esbRepRelayId);
						commState = GetLocalCiAndOtherCiTransSta(esbBelongCi);/*本联锁与其它联锁通信通信状态*/
						if ((esbRepRelayBelongCi == localCi) && (TRANSMIT_STATE_BAD == commState) &&
							(FUNC_SWITCH_ON == funcSwitchSupportRelayInterface))
						{
							/*esb复视继电器属于本联锁，且本联锁与esb所在联锁通信中断，且支持继电接口打开*/
							relaySta = GetRelayCollState(esbRepRelayId);
							if (RELAY_STATE_DOWN == relaySta)
							{
								reVal = SetEsbState(esbId, ESB_STATE_VALID_YES);

							}
							else if (RELAY_STATE_UP == relaySta)
							{
								reVal = SetEsbState(esbId, ESB_STATE_VALID_NO);

							}
							else
							{
								reVal = SetEsbState(esbId, ESB_STATE_VALID_YES);
							}
						}
					}


				}

			}
		}
	}

	return reVal;
}


/*
* 功能描述： 更新Spks按钮逻辑状态
* 参数说明： void
* 返回值  ： 0u: 更新失败
*			 1: 更新成功
*/
UINT8 SpksRelayToDeviceStateProc(void)
{
	UINT16 ii = 0u;		/* 游标 */
	UINT16 tmpSpksSum = 0u;	/* Spks总数 */
	UINT16 spksId = 0u;	/* SpksID */
	UINT16 spksRelayId = 0u;/* Spks采集继电器ID */
	UINT16 spksCutRelayId = 0u;/* Spks采集继电器ID */
	UINT8 ret = CI_ERROR;

	UINT8 spksBelongCi = 0u;/*spks所属联锁*/
	UINT8 commState = 0u;/*通信状态*/
	/*相邻联锁是否支持继电接口*/
	UINT8 funcSwitchSupportRelayInterface = GetCiFunctionSwitchConfig(FUNC_SWITCH_USE_RELAY_INTERFACE_BETWEEN_NEIGHBOURCI);
	UINT8 localCi = GetSystemParaLocalCiId();/*本机联锁*/
	UINT16 spksRepRelayId = 0u;/*spks复视继电器ID*/
	UINT8 spksRepRelayBelongCi = 0u;/*spks复视继电器所属联锁*/
	UINT8 relaySta = 0u;
	UINT8 execRes = 0u;
	UINT32 curCycNum = Get2oo2CurCycleNum();
	UINT8 spksVirAttribute = 0U;
	UINT8 chStartFlock = CI_START_FLOCK_YES;
	UINT8 cFunRet = 0U;

	tmpSpksSum = GetTotalSpksCurNum();/*包括相邻联锁的SPKS*/
	for (ii = 0u; ii < tmpSpksSum; ii++)
	{
		spksId = GetSpksIdByIndex(ii);
		if (spksId > 0u)
		{
			ret = CI_SUCCESS;
			spksVirAttribute = GetSpksVirtualAttribute(spksId);
			if (SPKS_VIRTUAL_ATTR_NO == spksVirAttribute)
			{/*不为虚拟设备才采集继电器状态*/
				spksRelayId = GetSpksColRelayId(spksId);
				if (spksRelayId > 0u)
				{
					spksBelongCi = GetSpksBelongCiId(spksId);
					if (spksBelongCi == localCi)
					{
						cFunRet = GetSpksBtnCollTolerateRet(spksId);  /*获取SPKS按钮采集容忍结果*/

						if (CI_SUCCESS == cFunRet)
						{
							(void)SetSpksState(spksId, SPKS_STATUS_NO);
							
							SetSpksflockStartNum(spksId, 0U);
						}
						else
						{
							(void)SetSpksState(spksId, SPKS_STATUS_YES);
							
							SetSpksflockStartNum(spksId, curCycNum);
						}

						/*旁路状态*/
						spksCutRelayId = GetSpksCutRelayId(spksId);
						if (0U != spksCutRelayId)
						{   /*当没有配置旁路按钮时，不作处理*/
							relaySta = GetRelayCollState(spksCutRelayId);
							if (RELAY_STATE_DOWN == relaySta)
							{
								SetSpksCutState(spksId, SPKS_CUT_NO);
							}
							else if (RELAY_STATE_UP == relaySta)
							{
								SetSpksCutState(spksId, SPKS_CUT_YES);
							}
							else
							{
								ret = CI_ERROR;
							}
						}
					}
					else
					{/*spks不属于本联锁*/
						spksRepRelayId = GetSpksRepRelayId(spksId);

						if (spksRepRelayId > 0u)
						{
							spksRepRelayBelongCi = GetRelayBelongCiId(spksRepRelayId);
							commState = GetLocalCiAndOtherCiTransSta(spksBelongCi);/*本联锁与其它联锁通信通信状态*/
							if ((localCi == spksRepRelayBelongCi) && (TRANSMIT_STATE_BAD == commState) &&
								(FUNC_SWITCH_ON == funcSwitchSupportRelayInterface))
							{
								relaySta = GetRelayCollState(spksRepRelayId);
								if (RELAY_STATE_DOWN == relaySta)
								{
									execRes = SetSpksState(spksId, SPKS_STATUS_YES);
									SetSpksflockStartNum(spksId,curCycNum);
									if (CI_ERROR == execRes)
									{
										debug_infor_printf((const)"SetSpksState %d,%d error.", spksId, relaySta);
									}
								}
								else if (RELAY_STATE_UP == relaySta)
								{
									execRes = SetSpksState(spksId, SPKS_STATUS_NO);
									SetSpksflockStartNum(spksId,0u);
									if (CI_ERROR == execRes)
									{
										debug_infor_printf((const)"SetSpksState %d,%d error.", spksId, relaySta);
									}
								}
								else
								{
									ret = CI_ERROR;
								}
							}
							else
							{
							/*无操作*/
							}
						}
						else
						{
						/*无操作*/
						}
					}
				}
				else
				{
				/*无操作*/
				}


			}
			else
			{
			/*无操作*/
			}
		}
		else
		{
			ret = CI_ERROR;
		}
		if (CI_ERROR == ret)
		{
			break;
		}
		else
		{
		/*无操作*/
		}
	}
	chStartFlock = GetStartFLockFlag();
	if (CI_START_FLOCK_NO == chStartFlock)
	{	/* 全站解封状态才可以进行逻辑区段及物理区段封锁状态设置判断 */
		SpksRelayToLogSecFlockStatus();
		SpksRelayToPhySecFlockStatus();

	}
	else
	{
    	/*无操作*/
	}
	return ret;


}

/*
* 功能描述： 根据SPKS状态更新物理区段封锁状态
* 参数说明： UINT16 phySecId
* 返回值  ： 无
*/
void SpksRelayToPhySecFlockStatus(void)
{
	UINT16 phySecCurSum = 0U;	 /* 物理区段总数目*/
	UINT8 spksNum = 0U;			/* spks总数 */
	UINT16 spksId = 0U;			/* spksID */

	UINT16 phySecId = 0U;	     /* 物理区段ID */
	UINT16 ii = 0U;        /* 循环索引 */
	UINT16 jj = 0U;                       /* 循环索引 */
	UINT8 spksState = 0U;
	UINT8 spksCutState = 0U;
	UINT8 secFlockType = 0U;
	UINT8 retValue = CI_ERROR;


	phySecCurSum = GetPhySecCurSum();		/*获取物理区段总数*/

	/*处理物理区段*/
	for (ii = 0U; ii < phySecCurSum; ii++)
	{
		phySecId = 0U;	      /*物理区段ID*/
		phySecId = GetPhySecId(ii);                      /*获取物理区段ID*/

		if ((0U != phySecId) && (phySecId < PHYSICAL_SECTION_SUM_MAX))
		{
			spksNum = GetPhySecSpksSum(phySecId);           /*获取所有物理区段关联的SPKS数目*/
			for (jj = 0U; jj < spksNum; jj++)
			{
				spksId = GetPhySecSpksIdBySpksIdx(phySecId, jj);
				if (0u< spksId)
				{
					spksState = GetSpksState(spksId);
					spksCutState = GetSpksCutState(spksId);
					if ((SPKS_STATUS_YES == spksState) && (SPKS_CUT_YES != spksCutState))
					{  /*旁路按钮继电器为0U时，此时旁路按钮状态为0U，区段也应为封锁状态，20180726*/
						retValue = SetPhySecFLockState(phySecId, PHYSICAL_SECTION_FLOCK_YES);
						if (CI_ERROR == retValue)
						{
							/*设置物理区段封锁状态失败*/
						}
						secFlockType = GetPhySecFLockType(phySecId);
						if (PHY_SEC_FLOCK_TYPE_CMD == secFlockType)
						{
							SetPhySecFLockType(phySecId, PHY_SEC_FLOCK_TYPE_SPKSCMD);/*封锁类型设置SPKS按下 且区段封锁命令 封锁*/
						}
						else if (PHY_SEC_FLOCK_TYPE_NONE == secFlockType)
						{
							SetPhySecFLockType(phySecId, PHY_SEC_FLOCK_TYPE_SPKS);/*记录物理区段封锁是由于SPKS按下导致*/
						}
						else
						{
							/*已经设置SPKS封锁类型*/
						}

						break;
					}
				}
			}
#if 0
			secFLockState = GetPhySecFLockState(phySecId);
			if (PHYSICAL_SECTION_FLOCK_YES == secFLockState)
			{
				routeSum = GetRouteCurSum();/*获取进路条数*/
				for (kk = 0U; kk < routeSum; kk++)
				{
					routeId = GetRouteId(kk);/*获取进路ID*/

					reVal = CheckCancleAutoFlag(routeId, phySecId);/*检查是否区段自动触发标志，针对区段属于本联锁的但进路属于相邻联锁的情况，不再取消本联锁的自动触发标志*/

					if (CI_SUCCESS == reVal)
					{
						dataIdBuf = GetRouteSectionData(routeId);
						checkSum = GetRoutePhysicalSectionSum(routeId);
						proRouteId = GetPhySecProLockRouteIdBuf(phySecId);
						proRouteIdSum = GetPhySecProLockRouteSum(phySecId);
						flag = 0U;  /*每条进路都遍历一遍*/
						for (ll = 0U; ll < checkSum; ll++)
						{     /*新机场线新需求，当区段封锁后取消包含该区段的进路的自动属性，2018.9.17*/
							if ((0U != proRouteIdSum) && (NULL != proRouteId))
							{
								for (i = 0U; i < proRouteIdSum; i++)
								{  /*进路中保护区段包含的区段*/
									if ((phySecId == dataIdBuf[ll].PhysicalSectionId) || (routeId == proRouteId[i]))
									{  /*当进路包含封锁的信号机，则取消该进路的自动属性*/
										retValue = CancleAutoFlag(routeId);
										if (CI_ERROR == retValue)
										{   /*已取消自动属性*/
											SetErrorData(EFUNC_SET_SECTION_FLOCK, CI_DEVICE_TYPE_PHYSEC, phySecId, ETYPE_PS_FLOCK_STATE, PHYSICAL_SECTION_FLOCK_YES, ESEND_LEVEL_ATS);

										}
										flag = 1U;
										break;
									}

								}
							}
							else
							{    /*进路不包含保护区段，则只检查进路内方区段*/
								if (phySecId == dataIdBuf[ll].PhysicalSectionId)
								{  /*当进路包含封锁的信号机，则取消该进路的自动属性*/
									retValue = CancleAutoFlag(routeId);
									if (CI_ERROR == retValue)
									{   /*已取消自动属性*/
										SetErrorData(EFUNC_SET_SECTION_FLOCK, CI_DEVICE_TYPE_PHYSEC, phySecId, ETYPE_PS_FLOCK_STATE, PHYSICAL_SECTION_FLOCK_YES, ESEND_LEVEL_ATS);

									}
									flag = 1U;
								}

							}

							if (1U == flag)
							{
								break;
							}
						}
					}
				}
			}
#endif
			/*此处即可判断处区段没有封锁 */
			if ((jj == spksNum) && (0u< jj))
			{
				secFlockType = GetPhySecFLockType(phySecId);
				if (PHY_SEC_FLOCK_TYPE_SPKSCMD == secFlockType)
				{
					SetPhySecFLockType(phySecId, PHY_SEC_FLOCK_TYPE_CMD);/*已有封锁命令区段封锁不能取消封锁 封锁类型降为仅命令封锁*/
				}
				else if (PHY_SEC_FLOCK_TYPE_SPKS == secFlockType)
				{
					retValue = SetPhySecFLockState(phySecId, PHYSICAL_SECTION_FLOCK_NO);
					if (CI_ERROR == retValue)
					{
						/*设置物理区段封锁状态失败*/
					}
					SetPhySecFLockType(phySecId, PHY_SEC_FLOCK_TYPE_NONE);/*封锁类型设置成无封锁*/
				}
				else
				{
					/*已有封锁命令区段封锁不能取消封锁*/
				}
			}
			else
			{
				/*无操作*/
			}
		}
	}
}


/*
* 功能描述： 更新车库门的逻辑状态
* 参数说明： void
* 返回值  ： 0u: 更新失败
*			 1: 更新成功
*/
UINT8 GaragedoorRelayToDevStaProc(void)
{
	UINT16 ii = 0u;		/* 游标 */
	UINT16 garagedoorSum = 0u;	/* Garagedoor总数 */
	UINT16 garagedoorId = 0u;	/* Garagedoor ID */
	UINT16 garagedoorOpenRelayId = 0u;/* Garagedoor采集开门继电器ID */
	UINT16 garagedoorCloseRelayId = 0u;/* Garagedoor采集关门继电器ID */
	UINT16 garagedoorModeRelayId = 0u;/* Garagedoor采集模式继电器ID */
	UINT16 garagedoorFaultRelayId = 0u;/* Garagedoor故障继电器ID */
	UINT16 garagedoorPangLuRelayId = 0u;/* Garagedoor旁路继电器ID */
	UINT16 garagedoorKGHRelayId = 0u;/* Garagedoor开关状态后节点继电器ID */
	UINT8 doorState = 0u;
	UINT8 doorDrvState = 0u;

	UINT8 gdOpenRelayState = 0U;/*Garagedoor采集开门继电器状态*/
	UINT8 gdCloseRelayState = 0U;/*Garagedoor采集关门继电器状态*/
	UINT8 gdKGHRelayState = 0U;/*Garagedoor开关状态后节点继电器状态*/
	UINT8 gdPangLuRelayState = 0U;/*Garagedoor旁路继电器状态*/
	UINT8 gdGuZhangRelayState = 0U;/*Garagedoor故障继电器状态*/
	UINT8 gdModeRelayState = 0U; /*车库门模式继电器状态*/
	UINT8 ret = CI_ERROR;


	garagedoorSum = GetGaragedoorSum();
	if (GARAGE_DOOR_SUM_MAX > garagedoorSum)
	{
		ret = CI_SUCCESS;
		for (ii = 0u; ii < garagedoorSum; ii++)
		{
			garagedoorId = GetGaragedoorId(ii);
			if (CI_ERROR == garagedoorId)
			{
				ret = CI_ERROR;
			}
			else
			{
				garagedoorOpenRelayId = GetGaragedoorOpenRelayId(garagedoorId);
				garagedoorCloseRelayId = GetGardoorCloseRelayId(garagedoorId);
				garagedoorModeRelayId = GetGardoorModeStateRelayId(garagedoorId);
				garagedoorFaultRelayId = GetGardoorFaultStateRelayId(garagedoorId);
				garagedoorPangLuRelayId = GetGardoorPangLuRelayId(garagedoorId);
				garagedoorKGHRelayId = GetGardoorKGHRelayId(garagedoorId);

				gdOpenRelayState = GetRelayCollState(garagedoorOpenRelayId);
				gdCloseRelayState = GetRelayCollState(garagedoorCloseRelayId);
				gdKGHRelayState = GetRelayCollState(garagedoorKGHRelayId);
				gdPangLuRelayState = GetRelayCollState(garagedoorPangLuRelayId);
				gdGuZhangRelayState = GetRelayCollState(garagedoorFaultRelayId);
				gdModeRelayState = GetRelayCollState(garagedoorModeRelayId);


				/*新增状态判断模式：只存在开门和旁路继电器，其他继电器未配置*/
				if ((0U != garagedoorOpenRelayId) && (0U != garagedoorPangLuRelayId)
					&& (0U == garagedoorCloseRelayId) && (0U == garagedoorModeRelayId) && (0U == garagedoorFaultRelayId) && (0U == garagedoorKGHRelayId))
				{
					ret = GDRelayToDeviceStateOnlyOpenPL(garagedoorId);

				}
				else
				{
					/* 状态设置 : 只有门开继电器 门关继电器只有一个吸起
					 *  门开: 门开继电器↑ 门关继电器↓ 门关: 门开继电器↓ 门关继电器↑
					 */

					 /*车库门开关*/
					if ((RELAY_STATE_DOWN == gdOpenRelayState) && (RELAY_STATE_UP == gdCloseRelayState)
						&& (RELAY_STATE_DOWN == gdKGHRelayState) && (RELAY_STATE_DOWN == gdPangLuRelayState))
						/*门开↓&&门关↑&&开关后↓&&旁路↓*/
					{
						ret = SetGaragedoorState(garagedoorId, GARAGE_DOOR_STATE_CLOSE);

					}
					else if (((RELAY_STATE_UP == gdOpenRelayState) && (RELAY_STATE_DOWN == gdCloseRelayState)
						&& (RELAY_STATE_DOWN == gdKGHRelayState)) || (RELAY_STATE_UP == gdPangLuRelayState))
						/*(门开↑&&门关↓&&开关后↓)||旁路↑*/
					{
						ret = SetGaragedoorState(garagedoorId, GARAGE_DOOR_STATE_OPEN);

					}
					else
					{
						ret = SetGaragedoorState(garagedoorId, GARAGE_DOOR_STATE_UNVALID);

					}
				}
				/*车库门模式*/
				if (CI_SUCCESS == ret)
				{
					if (RELAY_STATE_DOWN == gdModeRelayState)
					{
						ret = SetGaragedoorModeState(garagedoorId, GARAGE_DOOR_STATE_MODE_LOCAL);

					}
					else if (RELAY_STATE_UP == gdModeRelayState)
					{
						ret = SetGaragedoorModeState(garagedoorId, GARAGE_DOOR_STATE_MODE_REMOTE);

					}
					else
					{
						/*未配置继电器或继电器采集错误，置为本地模式*/
						ret = SetGaragedoorModeState(garagedoorId, GARAGE_DOOR_STATE_MODE_LOCAL);
					}
				}
				else
				{
					;
				}
				/*车库门故障*/
				if (CI_SUCCESS == ret)
				{
					if (RELAY_STATE_DOWN == gdGuZhangRelayState)
					{
						ret = SetGaragedoorFaultState(garagedoorId, GARAGE_DOOR_FAULT_TRUE);

					}
					else
					{
						ret = SetGaragedoorFaultState(garagedoorId, GARAGE_DOOR_FAULT_FALSE);

					}
				}
				else
				{
					;
				}

				/*车库门旁路*/
				if (CI_SUCCESS == ret)
				{
					if (RELAY_STATE_UP == gdPangLuRelayState)
					{
						ret = SetGaragedoorPangLuState(garagedoorId, GARAGE_DOOR_PANGLU_TRUE);

					}
					else
					{
						ret = SetGaragedoorPangLuState(garagedoorId, GARAGE_DOOR_PANGLU_FALSE);

					}
				}
				else
				{
					;
				}


				/* 驱动处理，驱动到门到位后，清除状态 */
				doorDrvState = GetDrvGaragedoorState(garagedoorId);
				doorState = GetGaragedoorState(garagedoorId);
				if (((GARAGE_DOOR_DRV_OPEN == doorDrvState) && (GARAGE_DOOR_STATE_OPEN == doorState))
					|| ((GARAGE_DOOR_DRV_CLOSE == doorDrvState) && (GARAGE_DOOR_STATE_CLOSE == doorState)))
				{
					ret = SetDrvGaragedoorState(garagedoorId, GARAGE_DOOR_DRV_NULL);
				}
				else
				{
					;
				}

			}
		}
	}
	else
	{
	    ret = CI_ERROR;
	}
	return ret;
}

/*
* 功能描述： 更新车库门的逻辑开关门状态(仅配置开门、旁路继电器)
* 参数说明： void
* 返回值  ： 0u: 更新失败
*			 1: 更新成功
*/
UINT8 GDRelayToDeviceStateOnlyOpenPL(const UINT16 garagedoorId)
{
	UINT16 garagedoorOpenRelayId = 0u;/* Garagedoor采集开门继电器ID */
	UINT16 garagedoorPangLuRelayId = 0u;/* Garagedoor旁路继电器ID */

	UINT8 gdOpenRelayState = 0U;/*Garagedoor采集开门继电器状态*/
	UINT8 gdPangLuRelayState = 0U;/*Garagedoor旁路继电器状态*/
	UINT8 ret = CI_ERROR;

	garagedoorOpenRelayId = GetGaragedoorOpenRelayId(garagedoorId);
	garagedoorPangLuRelayId = GetGardoorPangLuRelayId(garagedoorId);

	gdOpenRelayState = GetRelayCollState(garagedoorOpenRelayId);
	gdPangLuRelayState = GetRelayCollState(garagedoorPangLuRelayId);


	/*车库门开关状态*/
	if ((RELAY_STATE_DOWN == gdOpenRelayState) && (RELAY_STATE_DOWN == gdPangLuRelayState))
	{
		ret = SetGaragedoorState(garagedoorId, GARAGE_DOOR_STATE_CLOSE);
		
	}
	else if ((RELAY_STATE_UP == gdOpenRelayState) || (RELAY_STATE_UP == gdPangLuRelayState))
	{
		ret = SetGaragedoorState(garagedoorId, GARAGE_DOOR_STATE_OPEN);
		
	}
	else
	{
		ret = SetGaragedoorState(garagedoorId, GARAGE_DOOR_STATE_UNVALID);
		
	}
	return ret;
}

/*
* 功能描述： 更新车库门继电器状态
* 参数说明： void
* 返回值  ： 无
*/
void GaragedoorDevToRelayStaProc(void)
{
	UINT16 ii = 0u;		/* 游标 */
	UINT16 garagedoorSum = 0u;	/* Garagedoor总数 */
	UINT16 garagedoorId = 0u;	/* Garagedoor ID */
	UINT16 relayId = 0u;
	UINT8 doorDrvState = 0u;

	garagedoorSum = GetGaragedoorSum();
	for (ii = 0u; ii < garagedoorSum; ii++)
	{
		garagedoorId = GetGaragedoorId(ii);
		doorDrvState = GetDrvGaragedoorState(garagedoorId);

		if (GARAGE_DOOR_DRV_OPEN == doorDrvState)
		{
			/*获取车库门开门继电器ID*/
			relayId = GetGardoorOpenOrderRelayId(garagedoorId);

			if (GARAGE_DOOR_STATE_OPEN == GetGaragedoorState(garagedoorId))
			{
				/*如果车库门状态为已打开 则清除记录的开始驱动周期 继续处理其他车库门*/
				(void)SetGaragedoorOpenStartCycNum(garagedoorId, 0u);
			}
			else
			{
				if (CI_TIME_OUT == SystemOverTimeCheck(GetGaragedoorOpenStartCycNum(garagedoorId), GetSysParaGaragedoorOperateCnt()))
				{
					/*如果超时 则清除记录的开始驱动周期 停止驱动继电器 反馈报警信息*/
					(void)SetGaragedoorOpenStartCycNum(garagedoorId, 0u);
					(void)SetRelayDriveState(relayId, RELAY_DRIVE_STATE_DOWN);
					SetCiSendCmdBackInfoData(CI_BACK_GARAGEDOOR_TIMEOUT, CI_DEVICE_TYPE_GARAGEDOOR, garagedoorId, 0u, 0u);/*反馈车库门动作超时*/

					(void)SetDrvGaragedoorState(garagedoorId, GARAGE_DOOR_DRV_NULL);
				}
				else
				{
					/*没有超时 则驱动车库门开门*/
					(void)SetRelayDriveState(relayId, RELAY_DRIVE_STATE_UP);
				}
			}
		}
		else if (GARAGE_DOOR_DRV_CLOSE == doorDrvState)
		{
			/*获取车库门关门继电器ID*/
			relayId = GetGardoorCloseOrderRelayId(garagedoorId);

			if (GARAGE_DOOR_STATE_CLOSE == GetGaragedoorState(garagedoorId))
			{
				/*如果车库门状态为已关闭 则清除记录的开始驱动周期 继续处理其他车库门*/
				SetGaragedoorCloseStartCycNum(garagedoorId, 0u);
			}
			else
			{
				if (CI_TIME_OUT == SystemOverTimeCheck(GetGaragedoorCloseStartCycNum(garagedoorId), GetSysParaGaragedoorOperateCnt()))
				{
					/*如果超时 则清除记录的开始驱动周期 停止驱动继电器 反馈报警信息*/
					SetGaragedoorCloseStartCycNum(garagedoorId, 0u);
					(void)SetRelayDriveState(relayId, RELAY_DRIVE_STATE_DOWN);
					SetCiSendCmdBackInfoData(CI_BACK_GARAGEDOOR_TIMEOUT, CI_DEVICE_TYPE_GARAGEDOOR, garagedoorId, 0u, 0u);/*反馈车库门动作超时*/

					(void)SetDrvGaragedoorState(garagedoorId, GARAGE_DOOR_DRV_NULL);
				}
				else
				{
					/*没有超时 则驱动车库门关门*/
					(void)SetRelayDriveState(relayId, RELAY_DRIVE_STATE_UP);
				}
			}
		}
		else
		{
			(void)SetGaragedoorOpenStartCycNum(garagedoorId, 0u);
			SetGaragedoorCloseStartCycNum(garagedoorId, 0u);
		}
	}
}

/*
* 功能描述： 更新防淹门的设备逻辑状态
* 参数说明： void
* 返回值  ： void
*/
void FloodGateRelayToDeviceStateProc(void)
{
	UINT16 ii = 0u;		                     /*游标*/
	UINT16 floodGateSum = 0u;	             /*防淹门总数*/
	UINT16 floodGateId = 0u;	             /*防淹门ID*/
	UINT32 curCycle = 0u;/*当前周期*/
	UINT8 localCi = 0u;
	UINT8 belongCi = 0u;

	UINT8 tmpExecRes = CI_ERROR;/*临时执行结果*/
	UINT8 reVal = CI_ERROR;/*返回值*/


	UINT16 closeApplyRelayId = 0u;/*关门请求继电器id*/
	UINT16 openLockRelayId = 0u; /*开门锁闭继电器id*/
	UINT16 allowCloseRelayId = 0u; /*允许关门继电器id*/

	UINT8 closeApplyRelayState = 0u;/*关门请求继电器状态*/
	UINT8 openLockRelayState = 0u; /*开门锁闭继电器状态*/
	UINT8 allowCloseRelayState = 0u; /*允许关门继电器状态*/

	curCycle = Get2oo2CurCycleNum();
	floodGateSum = GetFloodGateCurSum();
	localCi = GetSystemParaLocalCiId();/*本机联锁*/
	for (ii = 0u; ii < floodGateSum; ii++)
	{
		floodGateId = GetFloodGateId(ii);

		/*验证防淹门id必须不为0u*/
		if (CI_ERROR == floodGateId)
		{
			reVal = CI_ERROR;
		}
		else
		{
			reVal = CI_SUCCESS;
		}

		if (CI_SUCCESS == reVal)
		{/*验证防淹门必须为本机联锁*/
			belongCi = GetFloodGateBelongCiId(floodGateId);

			if (belongCi == localCi)
			{
				reVal = CI_SUCCESS;
			}
			else
			{
				reVal = CI_ERROR;
			}
		}


		if (CI_SUCCESS == reVal)
		{
			openLockRelayId = GetFloodGateOpenLockRelayId(floodGateId);/*获取防淹门开门锁闭继电器id*/
			closeApplyRelayId = GetFloodGateCloseApplyRelayId(floodGateId);/*获取防淹门关门请求继电器id*/
			allowCloseRelayId = GetFloodGateAllowRequestRelayId(floodGateId);/*获取防淹门运行关门继电器id*/

			/*更新防淹门开启且锁定状态*/
			if (openLockRelayId > 0u)
			{
				openLockRelayState = GetRelayCollState(openLockRelayId);/*更新防淹门开门锁闭状态*/

				if (RELAY_STATE_UP == openLockRelayState)
				{/*KSJ常态励磁，吸起设置为开启且锁定*/
					tmpExecRes = SetFloodGateCurOpenLockState(floodGateId, FLOOD_GATE_OPENLOCK);
					if (CI_ERROR == tmpExecRes)
					{
						/*错误*/
					}
				}
				else if (RELAY_STATE_DOWN == openLockRelayState)
				{/*KSJ落下，设为非开*/
					tmpExecRes = SetFloodGateCurOpenLockState(floodGateId, FLOOD_GATE_NOT_OPENLOCK);/*非开启且锁定*/
					if (CI_ERROR == tmpExecRes)
					{
						/*错误*/
					}
				}
				else
				{/*非法值，既不吸起，也不落下，设为安全侧，非开*/
					tmpExecRes = SetFloodGateCurOpenLockState(floodGateId, FLOOD_GATE_NOT_OPENLOCK);/*非开启且锁定*/
					if (CI_ERROR == tmpExecRes)
					{
						/*错误*/
					}
				}
			}

			/*更新防淹门关门请求状态*/
			if (closeApplyRelayId > 0u)
			{
				closeApplyRelayState = GetRelayCollState(closeApplyRelayId);/*更新防淹门关门请求状态*/

				if (RELAY_STATE_UP == closeApplyRelayState)
				{/*GQJ吸起，设为有关门请求*/
					tmpExecRes = SetFloodGateCurCloseRequestSta(floodGateId, FLOOD_GATE_CLOSEREQ);/*有关门请求*/
					if (CI_ERROR == tmpExecRes)
					{
						/*错误结果*/
					}
				}
				else if (RELAY_STATE_DOWN == closeApplyRelayState)
				{/*GQJ常态落下，落下设置为无关门请求*/
					tmpExecRes = SetFloodGateCurCloseRequestSta(floodGateId, FLOOD_GATE_NOT_CLOSEREQ);/*无关门请求*/
					if (CI_ERROR == tmpExecRes)
					{
						/*错误结果*/
					}
				}
				else
				{/*非法值，既不吸起，也不落下，设为安全侧，有关门请求*/
					tmpExecRes = SetFloodGateCurCloseRequestSta(floodGateId, FLOOD_GATE_CLOSEREQ);/*有关门请求*/
					if (CI_ERROR == tmpExecRes)
					{
						/*错误结果*/
					}
				}
			}

			/*更新防淹门允许关门采集状态*/
			if (allowCloseRelayId > 0u)
			{
				allowCloseRelayState = GetRelayCollState(allowCloseRelayId);/*更新防淹门关门请求状态*/

				if (RELAY_STATE_UP == allowCloseRelayState)
				{/*YGJ常态落下，吸起设置为允许关门*/
					tmpExecRes = SetFloodGateCurAgreeCloseSta(floodGateId, FLOOD_GATE_AGREE_CLOSE);
					if (CI_ERROR == tmpExecRes)
					{
						/*错误结果*/
					}
				}
				else if (RELAY_STATE_DOWN == allowCloseRelayState)
				{/*YGJ落下，设为不允许关门*/
					tmpExecRes = SetFloodGateCurAgreeCloseSta(floodGateId, FLOOD_GATE_NOT_AGREE_CLOSE);/*不允许关门*/
					if (CI_ERROR == tmpExecRes)
					{
						/*错误结果*/
					}
				}
				else
				{/*非法值，既不吸起，也不落下，设为不允许关门*/
					tmpExecRes = SetFloodGateCurAgreeCloseSta(floodGateId, FLOOD_GATE_NOT_AGREE_CLOSE);/*不允许关门*/
					if (CI_ERROR == tmpExecRes)
					{
						/*错误结果*/
					}
				}
			}






		}
	}
}

/*
* 功能描述： 更新防淹门继电器状态
* 参数说明： void
* 返回值  ： 无
*/
void FloodGateDeviceToRelayStateProc(void)
{
	UINT16 ii = 0u;		/* 游标 */
	UINT16 floodGateSum = 0u;	/* Garagedoor总数 */
	UINT16 floodGateId = 0u;	/* Garagedoor ID */
	UINT16 floodGateAgreeCloseRelayId = 0u;
	UINT8 floodGateAgreeCloseState = 0u;

	UINT32 startCount = 0u;/*混线起始周期*/
	UINT8 ygjDrvState = 0u;/*YGJ驱动状态*/
	UINT8 ygjCollState = 0u;/*YGJ采集状态*/

	UINT8 localCi = 0u;
	UINT8 belongCi = 0u;

	UINT8 reVal = CI_ERROR;
	UINT8 exeVal = 0u;/*执行结果*/
	UINT32 curCycle = 0u;/*当前周期*/
	INT32 deltCycle = 0;/*周期差值*/

	localCi = GetSystemParaLocalCiId();/*本机联锁*/
	floodGateSum = GetFloodGateCurSum();
	curCycle = Get2oo2CurCycleNum();/*当前周期*/

	for (ii = 0u; ii < floodGateSum; ii++)
	{
		floodGateId = GetFloodGateId(ii);

		/*验证防淹门id必须不为0u*/
		if (CI_ERROR == floodGateId)
		{
			reVal = CI_ERROR;
		}
		else
		{
			reVal = CI_SUCCESS;
		}

		if (CI_SUCCESS == reVal)
		{/*验证防淹门必须为本机联锁*/
			belongCi = GetFloodGateBelongCiId(floodGateId);

			if (belongCi == localCi)
			{
				reVal = CI_SUCCESS;
			}
			else
			{
				reVal = CI_ERROR;
			}
		}

		/*设置防淹门允许关门继电器驱动状态*/
		if (CI_SUCCESS == reVal)
		{
			floodGateAgreeCloseState = GetFloodGateCurAgreeCloseOutSta(floodGateId);/*允许关门驱动状态*/
			floodGateAgreeCloseRelayId = GetFloodGateAllowRequestRelayId(floodGateId);
			if (FLOOD_GATE_AGREE_CLOSE == floodGateAgreeCloseState)
			{/*允许关门，驱吸起*/
				(void)SetRelayDriveState(floodGateAgreeCloseRelayId, RELAY_DRIVE_STATE_UP);
			}
			else if (FLOOD_GATE_NOT_AGREE_CLOSE == floodGateAgreeCloseState)
			{/*不允许关门，驱落下*/
				(void)SetRelayDriveState(floodGateAgreeCloseRelayId, RELAY_DRIVE_STATE_DOWN);
			}
			else
			{/*非法值，驱落下*/
				(void)SetRelayDriveState(floodGateAgreeCloseRelayId, RELAY_DRIVE_STATE_DOWN);
			}

			/*增加防淹门YGJ混线报警判断，没有驱吸起，但是回采吸起，报警混线*/

			/*先判断是否混线：没有驱吸起，但回采吸起*/
			ygjDrvState = GetRelayDriveState(floodGateAgreeCloseRelayId);/*YGJ驱动状态*/
			ygjCollState = GetRelayCollState(floodGateAgreeCloseRelayId);/*YGJ采集状态*/

			if ((RELAY_STATE_UP == ygjCollState) && (RELAY_DRIVE_STATE_DOWN == ygjDrvState))
			{/*YGJ驱动落下，但回采吸起，判混线*/
				startCount = GetFloodGateCurYGJCrosLStartCnt(floodGateId);

				if (0u == startCount)
				{
					exeVal = SetFloodGateCurYGJCrosLStartCnt(floodGateId, curCycle);
					if (CI_ERROR == exeVal)
					{
						debug_infor_printf((const)"SetFloodGateCurYGJCrossLineStartCount %d cnt %d faile.", floodGateId, curCycle);
					}
				}
				else
				{/*当混线起始周期不为0u时，再判断是否混线持续了5周期，5周期报警*/
					deltCycle = (INT32)(curCycle - startCount);/*混线持续周期*/
					if (deltCycle == (INT32)FLOOD_GATE_YGJ_CROSS_LINE_MAX_COUNT)/*等于混线最大周期，只报一次，防止多次上报ATS卡死*/
					{
						SetErrorData(EFUNC_FloodGateDeviceToRelayStateProc, CI_DEVICE_TYPE_FLOODGATE, floodGateId,
							ETYPE_FLOOD_GATE_YGJ_CROSS_LINE, 0u, ESEND_LEVEL_ATS);/*防淹门混线报警*/
					}
				}
			}
			else
			{/*没有混线，则清零混线起始周期*/
				exeVal = SetFloodGateCurYGJCrosLStartCnt(floodGateId, 0u);
				if (CI_ERROR == exeVal)
				{
					debug_infor_printf((const)"SetFloodGateCurYGJCrossLineStartCount %d cnt 0 faile.", floodGateId);
				}
			}



		}



	}
}



/*
* 功能描述： 更新洗车机的逻辑状态
* 参数说明： void
* 返回值  ： 0u: 更新失败
*			 1: 更新成功
*/
UINT8 WashMachineToDeviceStateProc(void)
{
	UINT16 ii = 0u;		                     /*游标*/
	UINT16 washMachineSum = 0u;	             /*洗车机总数*/
	UINT16 washMachineId = 0u;	             /*洗车机ID*/
	UINT16 washMachineReadyRelayId = 0u;      /*洗车机工作就绪继电器ID*/
	UINT16 washMachineReVeriRelayId = 0u;     /*洗车机请求确认继电器ID*/
	UINT16 headWashAllowRelayId = 0u;         /*洗车机允许车头清洗继电器ID*/
	UINT16 emergencyStopRelayId = 0u;         /*洗车机列车紧急停车ID*/
	UINT16 tailWashAllowRelayId = 0u;         /*洗车机允许车尾清洗继电器ID*/
	UINT16 outWashTrainPortAllowRelayId = 0u; /*洗车机允许出洗车库继电器ID*/
	UINT8 ret = CI_SUCCESS;
	UINT8 lineIdentity = 0u;						 /*CI-VOBC接口标识*/
	UINT8 xtaCurState = 0u;/*洗车同意按钮当前状态*/
	UINT8 xtaPreStae = 0u;/*洗车同意按钮之前状态*/
	UINT8 xtaLogicState = 0u;/*洗车同意按钮逻辑状态*/
	UINT32 pressDownCycle = 0u;/*按下周期*/
	UINT32 curCycle = 0u;/*当前周期*/
	INT32 deltCycle = 0;/*临时变量，周期差值*/
	UINT16 washModeBackRelayId = 0U;
	UINT8 washModeState = 0U;
	UINT8 retRsult = 0U;
	UINT8 relayCollState = 0U;
	UINT8 cleanXTAPressDownCyc = 0U;
	UINT16 wDownWashAllowRelayId = 0U;/*降级模式洗车同意按钮继电器*/
	UINT16 wDownWashAllowPassRelayId = 0U;/*降级模式洗车同意通过按钮继电器*/
	UINT8 chDownWashAllowState = 0U;/*降级模式洗车同意状态*/
	UINT8 chDownWashAllowPassState = 0U;/*降级模式洗车同意通过状态*/

	lineIdentity = GetCiFunctionSwitchConfig(VOBC_INTERFACE_IDENTITY);/*获取CI-VOBC接口标识*/
	curCycle = Get2oo2CurCycleNum();
	washMachineSum = GetWashMachineSum();
	for (ii = 0u; ii < washMachineSum; ii++)
	{
		washMachineId = GetWashMachineId(ii);
		if (CI_ERROR == washMachineId)
		{
			ret = CI_ERROR;
		}

		if (CI_SUCCESS == ret)
		{
			/*洗车请求确认状态更新*/
			washMachineReVeriRelayId = GetWashMachineReqVerifyRelayId(washMachineId);
			if (0U != washMachineReVeriRelayId)
			{/*洗车机请求确认继电器ID有效*/
				relayCollState = GetRelayCollState(washMachineReVeriRelayId);
				if (RELAY_STATE_UP == relayCollState)
				{
					retRsult = SetWashMachineRequestVerifySta(washMachineId, WASHMACHINE_COL_REQUEST_VALID);
					if (CI_ERROR == retRsult)
					{
						ret = CI_ERROR;
					}
				}
				else if (RELAY_STATE_DOWN == relayCollState)
				{
					retRsult = SetWashMachineRequestVerifySta(washMachineId, WASHMACHINE_COL_REQUEST_INVALID);
					if (CI_ERROR == retRsult)
					{
						ret = CI_ERROR;
					}
				}
				else
				{
					ret = CI_ERROR;
				}
			}
			else
			{
				/*若不配置该继电器，继续执行*/
			}
		}

		if (CI_SUCCESS == ret)
		{
			/*头部洗车允许状态更新*/
			headWashAllowRelayId = GetHeadWashAllowRelayId(washMachineId);
			if (0U != headWashAllowRelayId)
			{
				/*洗车机允许车头清洗继电器ID有效*/
				relayCollState = GetRelayCollState(headWashAllowRelayId);
				if (RELAY_STATE_UP == relayCollState)
				{
					retRsult = SetHeadWashAllowState(washMachineId, WASHMACHINE_COL_HEADWASH_YES);
					if (CI_ERROR == retRsult)
					{
						ret = CI_ERROR;
					}
				}
				else if (RELAY_STATE_DOWN == relayCollState)
				{
					retRsult = SetHeadWashAllowState(washMachineId, WASHMACHINE_COL_HEADWASH_NO);
					if (CI_ERROR == retRsult)
					{
						ret = CI_ERROR;
					}
				}
				else
				{
					ret = CI_ERROR;
				}
			}
			else
			{
				/*若不配置该继电器，继续执行*/
			}
		}

		if (CI_SUCCESS == ret)
		{
			/*尾部洗车允许状态更新*/
			tailWashAllowRelayId = GetTailWashAllowRelayId(washMachineId);
			if (0U != tailWashAllowRelayId)
			{
				/*洗车机允许车尾清洗继电器ID有效*/
				relayCollState = GetRelayCollState(tailWashAllowRelayId);
				if (RELAY_STATE_UP == relayCollState)
				{
					retRsult = SetTailWashAllowState(washMachineId, WASHMACHINE_COL_TAILWASH_YES);
					if (CI_ERROR == retRsult)
					{
						ret = CI_ERROR;
					}
				}
				else if (RELAY_STATE_DOWN == relayCollState)
				{
					retRsult = SetTailWashAllowState(washMachineId, WASHMACHINE_COL_TAILWASH_NO);
					if (CI_ERROR == retRsult)
					{
						ret = CI_ERROR;
					}
				}
				else
				{
					ret = CI_ERROR;
				}
			}
			else
			{
				/*若不配置该继电器，继续执行*/
			}
		}

		if (CI_SUCCESS == ret)
		{
			/*洗车机故障状态更新*/
			emergencyStopRelayId = GetTrainEmergencyStopRelayId(washMachineId);
			if (0U != emergencyStopRelayId)
			{
				relayCollState = GetRelayCollState(emergencyStopRelayId);
				/*洗车机列车紧急停车继电器ID有效*/
				if (RELAY_STATE_UP == relayCollState)
				{
					if (LINE_FAO == lineIdentity)
					{/*FAO线路*/
						retRsult = SetTrainEmergencyStopState(washMachineId, WASHMACHINE_COL_FALUT_NO);
						if (CI_ERROR == retRsult)
						{
							ret = CI_ERROR;
						}
					}
					else if ((LINE_FAOHLHT == lineIdentity) || (LINE_FAOHLHT_ONESELF == lineIdentity) || (LINE_FAOHLHT_ONESELFSECOND == lineIdentity)
						|| (LINE_CC == lineIdentity))
					{/*FAO+HLHT线路*/
						retRsult = SetTrainEmergencyStopState(washMachineId, WASHMACHINE_COL_FALUT_NO_2);
						if (CI_ERROR == retRsult)
						{
							ret = CI_ERROR;
						}
					}
					else
					{/*其他线路类型*/
						ret = CI_ERROR;
					}

				}
				else if (RELAY_STATE_DOWN == relayCollState)
				{
					if (LINE_FAO == lineIdentity)
					{/*FAO线路*/
						retRsult = SetTrainEmergencyStopState(washMachineId, WASHMACHINE_COL_FALUT_YES);
						if (CI_ERROR == retRsult)
						{
							ret = CI_ERROR;
						}
					}
					else if ((LINE_FAOHLHT == lineIdentity) || (LINE_FAOHLHT_ONESELF == lineIdentity) || (LINE_FAOHLHT_ONESELFSECOND == lineIdentity)
						|| (LINE_CC == lineIdentity))
					{/*FAO+HLHT线路*/
						retRsult = SetTrainEmergencyStopState(washMachineId, WASHMACHINE_COL_FALUT_YES_2);
						if (CI_ERROR == retRsult)
						{
							ret = CI_ERROR;
						}
					}
					else
					{/*其他线路类型*/
						ret = CI_ERROR;
					}

				}
				else
				{
					ret = CI_ERROR;
				}
			}
			else
			{
				/*若不配置该继电器，继续执行*/
			}
		}
		if (CI_SUCCESS == ret)
		{
			/*洗车机就绪状态更新，合肥为洗车同意按钮状态*/
			washMachineReadyRelayId = GetWashMachineReadyRelayId(washMachineId);
			if (0U != washMachineReadyRelayId)
			{
				if (LINE_HLHT == lineIdentity)
				{/*HLHT线路*/
					relayCollState = GetRelayCollState(washMachineReadyRelayId);
					/*洗车机就绪继电器ID有效*/
					if (RELAY_STATE_UP == relayCollState)
					{
						retRsult = SetWashMachineReadyState(washMachineId, WASHMACHINE_COL_READY_YES);
						if (CI_ERROR == retRsult)
						{
							ret = CI_ERROR;
						}
					}
					else if (RELAY_STATE_DOWN == GetRelayCollState(washMachineReadyRelayId))
					{
						retRsult = SetWashMachineReadyState(washMachineId, WASHMACHINE_COL_READY_NO);
						if (CI_ERROR == retRsult)
						{
							ret = CI_ERROR;
						}
					}
					else
					{
						ret = CI_ERROR;
					}


					xtaCurState = GetWashmachineXTACurState(washMachineId);/*获取洗车同意按钮当前状态*/

					if (xtaCurState != CI_ERROR)
					{
						retRsult = SetWashmachineXTAPreState(washMachineId, xtaCurState);/*用当前状态更新之前状态*/
						if (CI_ERROR == retRsult)
						{
							ret = CI_ERROR;
						}
					}

					relayCollState = GetRelayCollState(washMachineReadyRelayId);
					/*更新洗车机洗车同意按钮当前状态、之前状态,吸起为按下， 落下为抬起*/
					if (RELAY_STATE_UP == relayCollState)
					{
						retRsult = SetWashmachineXTACurState(washMachineId, XTA_STATE_PRESS_DOWN);
						/*更新XTA当前状态,吸起为按下*/
						if (CI_ERROR == retRsult)
						{
							ret = CI_ERROR;
						}
					}
					else if (RELAY_STATE_DOWN == relayCollState)
					{
						retRsult = SetWashmachineXTACurState(washMachineId, XTA_STATE_RAISE_UP);
						/*更新XTA当前状态,落下为抬起*/
						if (CI_ERROR == retRsult)
						{
							ret = CI_ERROR;
						}
						else
						{
							/*抬起时，清按下时间*/
							cleanXTAPressDownCyc = SetWashMachineXTAPressDownCyc(washMachineId, 0U);
							if (CI_ERROR == cleanXTAPressDownCyc)
							{
								/*清洗车机洗车同按钮按下周期失败*/
							}
						}
					}
					else
					{
						ret = CI_ERROR;
					}

				}
				else
				{
					relayCollState = GetRelayCollState(washMachineReadyRelayId);
					if (RELAY_STATE_UP == relayCollState)
					{
						retRsult = SetWashMachineReadyState(washMachineId, WASHMACHINE_COL_READY_YES);
						if (CI_ERROR == retRsult)
						{
							ret = CI_ERROR;
						}
					}
					else if (RELAY_STATE_DOWN == relayCollState)
					{
						retRsult = SetWashMachineReadyState(washMachineId, WASHMACHINE_COL_READY_NO);
						if (CI_ERROR == retRsult)
						{
							ret = CI_ERROR;
						}
					}
					else
					{
						ret = CI_ERROR;
					}
				}

			}
			else
			{
				/*若不配置该继电器，继续执行*/
			}
		}

		if (CI_SUCCESS == ret)
		{
			/*洗车机允许出库状态更新*/
			outWashTrainPortAllowRelayId = GetTrainOutWashPortAllowRelay(washMachineId);
			if (0U != outWashTrainPortAllowRelayId)
			{
				/*洗车机允许出洗车库继电器ID有效*/
				relayCollState = GetRelayCollState(outWashTrainPortAllowRelayId);
				if (RELAY_STATE_UP == relayCollState)
				{
					if (LINE_FAO == lineIdentity)
					{/*FAO线路*/
						retRsult = SetTrainOutWashPortAllowSta(washMachineId, WASHMACHINE_COL_OUT_YES);
						if (CI_ERROR == retRsult)
						{
							ret = CI_ERROR;
						}
					}
					else if ((LINE_FAOHLHT == lineIdentity) || (LINE_FAOHLHT_ONESELF == lineIdentity) || (LINE_FAOHLHT_ONESELFSECOND == lineIdentity)
						|| (LINE_CC == lineIdentity))
					{/*FAO+HLHT线路*/
						retRsult = SetTrainOutWashPortAllowSta(washMachineId, WASHMACHINE_COL_OUT_YES_2);
						if (CI_ERROR == retRsult)
						{
							ret = CI_ERROR;
						}
					}
					else
					{/*其他线路类型*/
						ret = CI_ERROR;
					}
				}
				else if (RELAY_STATE_DOWN == relayCollState)
				{
					if (LINE_FAO == lineIdentity)
					{/*FAO线路*/
						retRsult = SetTrainOutWashPortAllowSta(washMachineId, WASHMACHINE_COL_OUT_NO);
						if (CI_ERROR == retRsult)
						{
							ret = CI_ERROR;
						}
					}
					else if ((LINE_FAOHLHT == lineIdentity) || (LINE_FAOHLHT_ONESELF == lineIdentity) || (LINE_FAOHLHT_ONESELFSECOND == lineIdentity)
						|| (LINE_CC == lineIdentity))
					{/*FAO+HLHT线路*/
						retRsult = SetTrainOutWashPortAllowSta(washMachineId, WASHMACHINE_COL_OUT_NO_2);
						if (CI_ERROR == retRsult)
						{
							ret = CI_ERROR;
						}
					}
					else
					{/*其他线路类型*/
						ret = CI_ERROR;
					}
				}
				else
				{
					ret = CI_ERROR;
				}
			}
			else
			{
				/*若不配置该继电器，继续执行*/
			}
		}


		if (CI_SUCCESS == ret)
		{/*更新洗车机洗车同意按钮按下周期、抬起周期*/

			if (LINE_HLHT == lineIdentity)
			{/*HLHT线路*/
				xtaLogicState = GetWashmachineXTALogicState(washMachineId);

				if (XTA_STATE_PRESS_DOWN == xtaLogicState)
				{/*洗车同意按钮逻辑状态为按下时，清周期*/
					cleanXTAPressDownCyc = SetWashMachineXTAPressDownCyc(washMachineId, 0U);
					if (CI_ERROR == cleanXTAPressDownCyc)
					{
						/*清洗车机洗车同按钮按下周期失败*/
					}
				}
				else if (XTA_STATE_RAISE_UP == xtaLogicState)
				{/*洗车同意按钮逻辑状态为抬起时,更新周期*/
					xtaPreStae = GetWashmachineXTAPreState(washMachineId);
					xtaCurState = GetWashmachineXTACurState(washMachineId);
					if ((xtaCurState != CI_ERROR) && (xtaPreStae != CI_ERROR))
					{/*状态都有效时*/
						if ((XTA_STATE_PRESS_DOWN == xtaCurState) && (XTA_STATE_RAISE_UP == xtaPreStae))
						{/*当前按下，之前抬起,更新按下周期*/
							ret = SetWashMachineXTAPressDownCyc(washMachineId, curCycle);
						}


					}
				}
				else
				{/*逻辑状态非法，清洗车同意按钮按下/抬起周期*/
					cleanXTAPressDownCyc = SetWashMachineXTAPressDownCyc(washMachineId, 0U);
					if (CI_ERROR == cleanXTAPressDownCyc)
					{
						/*清洗车机洗车同按钮按下周期失败*/
					}
				}
			}
			else
			{
				/*其它线路不处理*/
			}

		}

		if (CI_SUCCESS == ret)
		{/*更新洗车同意按钮逻辑状态，只更新按下，抬起由现地的取消命令更新*/
			pressDownCycle = GetWashMachineXTAPressDownCyc(washMachineId);/*获取按下周期*/
			xtaCurState = GetWashmachineXTACurState(washMachineId);
			if ((pressDownCycle > 0U) && (XTA_STATE_PRESS_DOWN == xtaCurState))
			{
				if (curCycle > pressDownCycle)
				{/*当前周期大于按下周期，确保减法不为负值*/
					deltCycle = (INT32)(curCycle - pressDownCycle);
					if (deltCycle >= PRESSING_TIME_MIN)/*超过3个周期*/
					{
						ret = SetWashmachineXTALogicState(washMachineId, XTA_STATE_PRESS_DOWN);/*置逻辑状态为按下*/
					}
				}
			}
		}
		if (CI_SUCCESS == ret)
		{/*cgh-合并CID-3037-9：*/
			washModeBackRelayId = GetWashModeBackRelayId(washMachineId);
			if ((0U != washModeBackRelayId) && (UINT16_MAX != washModeBackRelayId))
			{
				washModeState = GetRelayCollState(washModeBackRelayId);
				/*继电器吸起*/
				if (RELAY_STATE_UP == washModeState)
				{
					/*设置端洗模式*/
					SetWashModeState(washMachineId, XTA_MODE_STATE_UP);
				}
				else
				{
					/*设置通过洗模式*/
					SetWashModeState(washMachineId, XTA_MODE_STATE_DOWN);
				}
			}
			else
			{
				/*设置无模式*/
				SetWashModeState(washMachineId, XTA_MODE_STATE_NO);
			}
		}

		if (CI_SUCCESS == ret)
		{
			wDownWashAllowRelayId = GetDownWashAllowRelayId(washMachineId);
			if ((0U != wDownWashAllowRelayId) && (UINT16_MAX != wDownWashAllowRelayId))
			{
				chDownWashAllowState = GetRelayCollState(wDownWashAllowRelayId);
				/*继电器吸起*/
				if (RELAY_STATE_UP == chDownWashAllowState)
				{
					/*设置降级模式洗车同意状态为允许*/
					SetDownWashAllowState(washMachineId, WASH_COL_STATE_ALLOW_YES);
				}
				else
				{
					/*设置降级模式洗车同意状态为不允许*/
					SetDownWashAllowState(washMachineId, WASH_COL_STATE_ALLOW_NO);
				}
			}
			else
			{
				/*设置降级模式洗车同意状态为不允许*/
				SetDownWashAllowState(washMachineId, WASH_COL_STATE_ALLOW_NO);
			}
		}

		if (CI_SUCCESS == ret)
		{
			wDownWashAllowPassRelayId = GetDownWashAllowPassRelayId(washMachineId);
			if ((0U != wDownWashAllowPassRelayId) && (UINT16_MAX != wDownWashAllowPassRelayId))
			{
				chDownWashAllowPassState = GetRelayCollState(wDownWashAllowPassRelayId);
				/*继电器吸起*/
				if (RELAY_STATE_UP == chDownWashAllowPassState)
				{
					/*设置降级模式洗车同意通过状态为允许*/
					SetDownWashAllowPassState(washMachineId, WASH_COL_STATE_ALLOW_PASS_YES);
				}
				else
				{
					/*设置降级模式洗车同意通过状态为不允许*/
					SetDownWashAllowPassState(washMachineId, WASH_COL_STATE_ALLOW_PASS_NO);
				}
			}
			else
			{
				/*设置降级模式洗车同意通过状态为不允许*/
				SetDownWashAllowPassState(washMachineId, WASH_COL_STATE_ALLOW_PASS_NO);
			}
		}
	}

	return ret;
}


/*
* 功能描述： 根据继电器采集数据获取指定ID信号机的显示颜色
* 参数说明： const UINT16 signalId
* 返回值  ： 0u: SIGNAL_SHOWCOLOUR_INVALID
*			 >0u: 当前显示颜色
*/
UINT8 GetRelayToDeviceSignalColor(const UINT16 signalId)
{
	UINT16 lxRelayStatus = 0u;    	/*列车信号继电器ID*/
	UINT16 zxRelayStatus = 0u;    	/*正线信号继电器ID*/
	UINT16 yxRelayStatus = 0u;    	/*引导信号继电器ID*/
	UINT16 ddRelayStatus = 0u;    	/*点灯继电器ID*/
	UINT16 dxRelayStatus = 0u;		/*调车信号继电器ID*/
	UINT8 fengDengType = 0u;	/*信号机点封灯类型*/
	UINT8 returnValue = 0u;/*返回值*/

	lxRelayStatus = GetRelayCollState(GetSignalLxRelayId(signalId));  /*获取信号机列车信号继电器ID*/
	zxRelayStatus = GetRelayCollState(GetSignalZxRelayId(signalId));  /*获取信号机正线信号继电器ID*/
	yxRelayStatus = GetRelayCollState(GetSignalYxRelayId(signalId));  /*获取信号机引导信号继电器ID*/
	dxRelayStatus = GetRelayCollState(GetSignalDxRelayId(signalId));	/*获取信号机调车信号继电器ID*/
	ddRelayStatus = GetRelayCollState(GetSignalDdRelayId(signalId));  /*获取信号机点灯继电器ID*/
	fengDengType = GetSignalFengDengType(signalId);	/*获取信号机点灯逻辑类型*/


	if ((RELAY_STATE_UP == lxRelayStatus)
		&& (RELAY_STATE_DOWN != zxRelayStatus)
		&& (RELAY_STATE_UP != yxRelayStatus)
		&& (CI_ERROR == dxRelayStatus))
	{/*绿灯：
	  * 列车信号继电器吸起、其余继电器默认态：正线信号继电器吸起或无、引导信号机落下或无、
	  * 非封绿灯、无调车信号继电器
	  * 若只配置LXJ进该分支，即只配置LXJ，封黄灯
	  */
		if (SIGNAL_TYPE_FENG_GREEN != fengDengType)
		{
			returnValue = SIGNAL_SHOWCOLOUR_GREEN;  /*绿灯*/

		}
		else
		{    /*封绿灯*/
			returnValue = SIGNAL_SHOWCOLOUR_YELLOW;       /*黄灯*/
		}
	}
	else if ((RELAY_STATE_UP == lxRelayStatus)
		&& (RELAY_STATE_UP != zxRelayStatus)
		&& (RELAY_STATE_UP != yxRelayStatus)
		&& (RELAY_STATE_UP != dxRelayStatus))
	{/*黄灯：LXJ吸起, zxj落下或者无，DXJ落下或者无，YXJ落下或者无。
	  * 若只配置LXJ不进该分支。
	  */

		returnValue = SIGNAL_SHOWCOLOUR_YELLOW;            /*黄灯*/

	}
	else if ((RELAY_STATE_UP != lxRelayStatus)
		&& (RELAY_STATE_DOWN != zxRelayStatus)
		&& (RELAY_STATE_UP != yxRelayStatus)
		&& (RELAY_STATE_UP != dxRelayStatus))
	{/*红灯：
	  * 若配置该继电器，则继电器状态为电路默认态。ZXJ:吸起 LXJ:落下 YXJ:落下 DXJ:落下
	  * 若没有配置则状态获取都是CI_ERROR，因此只需要判断是否 不等于 默认状态相反状态。
	  */
		returnValue = SIGNAL_SHOWCOLOUR_RED;            /*红灯*/

	}
	else if ((RELAY_STATE_DOWN == lxRelayStatus)
		&& (RELAY_STATE_UP == yxRelayStatus)
		&& (CI_ERROR == dxRelayStatus))
	{/*红黄灯：LXJ落下，YXJ状态必须吸起，其余状态默认状态,DXJ无
	  *
	  */

		returnValue = SIGNAL_SHOWCOLOUR_REDYELLOW;       /*红黄灯*/
	}
	else if ((RELAY_STATE_UP != lxRelayStatus)
		&& (CI_ERROR == zxRelayStatus)
		&& (CI_ERROR == yxRelayStatus)
		&& (RELAY_STATE_UP == dxRelayStatus))
	{/*白灯：列车信号继电器落下或无、正线信号继电器无、引导信号机无、调车信号继电器吸起*/

		returnValue = SIGNAL_SHOWCOLOUR_WHITE;       /*白灯*/
	}
	else
	{
		returnValue = SIGNAL_SHOWCOLOUR_INVALID;
	}

	/* 若点灯吸起,则认为灭灯 */
	if (RELAY_STATE_UP == ddRelayStatus)
	{
		if ((returnValue != SIGNAL_SHOWCOLOUR_WHITE) && (returnValue != SIGNAL_SHOWCOLOUR_REDYELLOW))
		{
			/*点灯继电器吸起则为灭灯*/
			returnValue = GetCloseSignaleColor(returnValue);       /*灭灯*/
		}
		else
		{
			returnValue = SIGNAL_SHOWCOLOUR_INVALID; /* 红黄灯,白灯不存在灭灯情况 */
		}
	}

	return returnValue;
}

/*
* 功能描述： 根据颜色获取对应灭灯状态
* 参数说明： const UINT8 color
* 返回值  ： 0u: SIGNAL_SHOWCOLOUR_INVALID
*			 >0u: 当前显示颜色
*/
UINT8 GetCloseSignaleColor(const UINT8 color)
{
	UINT8 ret = SIGNAL_SHOWCOLOUR_INVALID;
	switch (color)
	{
	case SIGNAL_SHOWCOLOUR_RED:
		ret = SIGNAL_SHOWCOLOUR_REDCLOSE;
		break;
	case SIGNAL_SHOWCOLOUR_YELLOW:
		ret = SIGNAL_SHOWCOLOUR_YELLOWCLOSE;
		break;
	case SIGNAL_SHOWCOLOUR_GREEN:
		ret = SIGNAL_SHOWCOLOUR_GREENCLOSE;
		break;
	default:
		/*不可达分支*/
		break;
	}

	return ret;
}

/*
* 功能描述： 根据继电器采集数据获取指定ID信号机的显示颜色-没有配置DDJ的特殊处理
* 参数说明： const UINT16 signalId
* 返回值  ： 0u: SIGNAL_SHOWCOLOUR_INVALID
*			 >0u: 当前显示颜色
*/
UINT8 GetNoDDJSignalColor(const UINT16 signalId)
{
	UINT16 firDsRelayId = 0u;  	/*1灯丝继电器ID */
	UINT16 secDsRelayId = 0u;  	/*2灯丝继电器ID*/
	UINT16 lxRelayId = 0u;    	/*列车信号继电器ID*/
	UINT16 zxRelayId = 0u;    	/*正线信号继电器ID*/
	UINT16 yxRelayId = 0u;    	/*引导信号继电器ID*/
	UINT16 dxRelayId = 0u;		/*调车信号继电器ID*/
	UINT16 yellowRelayId = 0u;	/*黄灯继电器ID*/
	UINT16 greenRelayId = 0u;	/*绿灯继电器ID*/
	UINT16 blueRelayId = 0u;		/*蓝灯继电器ID*/
	UINT8 signalType = 0u;	/*信号机点灯电路类型*/
	UINT8 returnValue = 0u;/*返回值*/
	UINT8 bCiSwitchShowGreenYellow = FUNC_SWITCH_OFF;/*ci显示绿黄开关,默认是关闭的*/

	UINT8 firDsRelaySta = RELAY_STATE_DOWN;  	/*1灯丝继电器状态*/
	UINT8 secDsRelaySta = RELAY_STATE_DOWN;  	/*2灯丝继电器状态*/
	UINT8 lxRelaySta = RELAY_STATE_DOWN;    	/*列车信号继电器状态*/
	UINT8 zxRelaySta = RELAY_STATE_DOWN;    	/*正线信号继电器状态*/
	UINT8 yxRelaySta = RELAY_STATE_DOWN;    	/*引导信号继电器状态*/
	UINT8 dxRelaySta = RELAY_STATE_DOWN;		/*调车信号继电器状态*/
	UINT8 yellowRelaySta = RELAY_STATE_DOWN;	/*黄灯继电器状态*/
	UINT8 greenRelaySta = RELAY_STATE_DOWN;		/*绿灯继电器状态*/
	UINT8 blueRelaySta = RELAY_STATE_DOWN;		/*蓝灯继电器状态*/

	firDsRelayId = GetSignalFirstDsRelayId(signalId);  /*获取信号机1灯丝继电器ID*/
	secDsRelayId = GetSignalSecondDsRelayId(signalId);  /*获取信号机2灯丝继电器ID*/
	lxRelayId = GetSignalLxRelayId(signalId);  /*获取信号机列车信号继电器ID*/
	zxRelayId = GetSignalZxRelayId(signalId);  /*获取信号机正线信号继电器ID*/
	yxRelayId = GetSignalYxRelayId(signalId);  /*获取信号机引导信号继电器ID*/
	dxRelayId = GetSignalDxRelayId(signalId);	/*获取信号机调车信号继电器ID*/
	yellowRelayId = GetSignalYellowRelayId(signalId);	/*黄灯继电器ID*/
	greenRelayId = GetSignalGreenRelayId(signalId);		/*绿灯继电器ID*/
	blueRelayId = GetSignalBlueRelayId(signalId);		/*蓝灯继电器ID*/

	signalType = GetSignalType(signalId);	/*获取信号机点灯逻辑类型*/

	firDsRelaySta = GetRelayCollState(firDsRelayId);	/*获取信号机1灯丝继电器状态*/
	secDsRelaySta = GetRelayCollState(secDsRelayId);	/*获取信号机2灯丝继电器状态*/
	lxRelaySta = GetRelayCollState(lxRelayId);	/*获取信号机列车信号继电器状态*/
	yxRelaySta = GetRelayCollState(yxRelayId);	/*获取信号机引导信号继电器状态*/
	zxRelaySta = GetRelayCollState(zxRelayId);  /*获取信号机正线信号继电器状态*/
	dxRelaySta = GetRelayCollState(dxRelayId);	/*获取信号机调车信号继电器状态*/
	yellowRelaySta = GetRelayCollState(yellowRelayId);
	greenRelaySta = GetRelayCollState(greenRelayId);
	blueRelaySta = GetRelayCollState(blueRelayId);

	bCiSwitchShowGreenYellow = GetCiFunctionSwitchConfig(CI_FUNCTION_SWITCH_SHOW_SIGNAL_GreenYellow);

	switch (signalType)
	{
	case SIGNAL_TYPE_5_NOGREEN_YINDAO_CD:/*0x2C	高柱五显示（封绿灯、带引导、可点亮双黄灯）红、黄、绿、白、双黄*/
	{
		if (FUNC_SWITCH_ON == bCiSwitchShowGreenYellow)/*如果显示绿黄灯开关【打开】*/
		{
			if ((RELAY_STATE_UP == lxRelaySta) && (RELAY_STATE_DOWN == yxRelaySta)
				&& (RELAY_STATE_UP == firDsRelaySta) && (RELAY_STATE_UP == secDsRelaySta))
			{
				returnValue = SIGNAL_SHOWCOLOUR_DOUBLE_YELLOW;/*双黄灯*/
			}
			else if ((RELAY_STATE_DOWN == lxRelaySta) && (RELAY_STATE_DOWN == yxRelaySta)
				&& (RELAY_STATE_UP == firDsRelaySta) && (RELAY_STATE_DOWN == secDsRelaySta))
			{
				returnValue = SIGNAL_SHOWCOLOUR_RED;/*红灯*/
			}
			else if ((RELAY_STATE_DOWN == lxRelaySta) && (RELAY_STATE_UP == yxRelaySta)
				&& (RELAY_STATE_UP == firDsRelaySta) && (RELAY_STATE_UP == secDsRelaySta))
			{
				returnValue = SIGNAL_SHOWCOLOUR_RED_WHITE;/*红白灯*/
			}
			else
			{
				returnValue = SIGNAL_SHOWCOLOUR_INVALID;/*无效*/
			}

		}
		break;
	}
	case SIGNAL_TYPE_5_NOY_NOYINDAO_CD:/*0x2D	矮柱五显示（封黄灯、不带引导）红、绿、双绿、白*/
	{
		if (FUNC_SWITCH_ON == bCiSwitchShowGreenYellow)/*如果显示绿黄灯开关【打开】*/
		{
			if ((RELAY_STATE_UP == lxRelaySta) && (RELAY_STATE_UP == zxRelaySta) && (RELAY_STATE_DOWN == dxRelaySta)
				&& (RELAY_STATE_UP == firDsRelaySta) && (RELAY_STATE_DOWN == secDsRelaySta))
			{
				returnValue = SIGNAL_SHOWCOLOUR_GREEN;/*绿灯*/
			}
			else if ((RELAY_STATE_UP == lxRelaySta) && (RELAY_STATE_DOWN == zxRelaySta) && (RELAY_STATE_DOWN == dxRelaySta)
				&& (RELAY_STATE_UP == firDsRelaySta) && (RELAY_STATE_UP == secDsRelaySta))
			{
				returnValue = SIGNAL_SHOWCOLOUR_DOUBLE_GREEN;/*双绿灯*/
			}
			else if ((RELAY_STATE_DOWN == lxRelaySta) && (RELAY_STATE_DOWN == zxRelaySta) && (RELAY_STATE_UP == dxRelaySta)
				&& (RELAY_STATE_UP == firDsRelaySta) && (RELAY_STATE_DOWN == secDsRelaySta))
			{
				returnValue = SIGNAL_SHOWCOLOUR_WHITE;/*白灯*/
			}
			else if ((RELAY_STATE_DOWN == lxRelaySta) && (RELAY_STATE_DOWN == zxRelaySta) && (RELAY_STATE_DOWN == dxRelaySta)
				&& (RELAY_STATE_UP == firDsRelaySta) && (RELAY_STATE_DOWN == secDsRelaySta))
			{
				returnValue = SIGNAL_SHOWCOLOUR_RED;/*红灯*/
			}
			else
			{
				returnValue = SIGNAL_SHOWCOLOUR_INVALID;/*无效*/
			}
		}
		break;
	}
	case SIGNAL_TYPE_4_ALL_NOYINDAO_CD:/*0x2E	矮柱四显示（不带引导）*/
	{
		if (FUNC_SWITCH_ON == bCiSwitchShowGreenYellow)/*如果显示绿黄灯开关【打开】*/
		{
			if ((RELAY_STATE_UP == lxRelaySta) && (RELAY_STATE_UP == greenRelaySta) && (RELAY_STATE_DOWN == dxRelaySta)
				&& (RELAY_STATE_UP == firDsRelaySta))
			{
				returnValue = SIGNAL_SHOWCOLOUR_GREEN;/*绿灯*/
			}
			else if ((RELAY_STATE_UP == lxRelaySta) && (RELAY_STATE_DOWN == greenRelaySta) && (RELAY_STATE_DOWN == dxRelaySta)
				&& (RELAY_STATE_UP == firDsRelaySta))
			{
				returnValue = SIGNAL_SHOWCOLOUR_YELLOW;/*黄灯*/
			}
			else if ((RELAY_STATE_DOWN == lxRelaySta) && (RELAY_STATE_DOWN == greenRelaySta) && (RELAY_STATE_UP == dxRelaySta)
				&& (RELAY_STATE_UP == firDsRelaySta))
			{
				returnValue = SIGNAL_SHOWCOLOUR_WHITE;/*白灯*/
			}
			else if ((RELAY_STATE_DOWN == lxRelaySta) && (RELAY_STATE_DOWN == greenRelaySta) && (RELAY_STATE_DOWN == dxRelaySta)
				&& (RELAY_STATE_UP == firDsRelaySta))
			{
				returnValue = SIGNAL_SHOWCOLOUR_RED;/*红灯*/
			}
			else
			{
				returnValue = SIGNAL_SHOWCOLOUR_INVALID;/*无效*/
			}

		}
		break;
	}
	case SIGNAL_TYPE_5_NOY_NOYINDAO_WB:/*0x2f		矮柱五灯位信号机封黄灯（不带引导）白、蓝*/
	{
		if (FUNC_SWITCH_ON == bCiSwitchShowGreenYellow)/*如果显示绿黄灯开关【打开】*/
		{
			if ((RELAY_STATE_UP == lxRelaySta) && (RELAY_STATE_DOWN == dxRelaySta) && (RELAY_STATE_UP == firDsRelaySta)
				&& (RELAY_STATE_UP == secDsRelaySta))
			{
				returnValue = SIGNAL_SHOWCOLOUR_DOUBLE_GREEN;/*双绿灯*/
			}
			else if ((RELAY_STATE_DOWN == lxRelaySta) && (RELAY_STATE_UP == dxRelaySta) && (RELAY_STATE_UP == firDsRelaySta)
				&& (RELAY_STATE_DOWN == secDsRelaySta))
			{
				returnValue = SIGNAL_SHOWCOLOUR_WHITE;/*白灯*/
			}
			else if ((RELAY_STATE_DOWN == lxRelaySta) && (RELAY_STATE_DOWN == dxRelaySta) && (RELAY_STATE_UP == firDsRelaySta)
				&& (RELAY_STATE_DOWN == secDsRelaySta))
			{
				returnValue = SIGNAL_SHOWCOLOUR_RED;/*红灯*/
			}
			else
			{
				returnValue = SIGNAL_SHOWCOLOUR_INVALID;/*无效*/
			}

		}
		break;
	}
	case SIGNAL_TYPE_3_RGG_CD:/*0x30		矮柱3灯位：红、双绿*/
	{
		if (FUNC_SWITCH_ON == bCiSwitchShowGreenYellow)/*如果显示绿黄灯开关【打开】*/
		{
			if ((RELAY_STATE_UP == lxRelaySta) && (RELAY_STATE_UP == dxRelaySta))
			{
				returnValue = SIGNAL_SHOWCOLOUR_DOUBLE_GREEN;	/*双绿灯*/
			}
			else if ((RELAY_STATE_DOWN == lxRelaySta) && (RELAY_STATE_UP == dxRelaySta))
			{
				returnValue = SIGNAL_SHOWCOLOUR_RED;	/*红灯*/
			}
			else
			{
				returnValue = SIGNAL_SHOWCOLOUR_INVALID;/*无效*/
			}

		}
		break;
	}
	case SIGNAL_TYPE_3_RGG_NOGREEN_CD:/*0x31	矮柱3灯位：红、双绿、封绿灯*/
	{
		if (FUNC_SWITCH_ON == bCiSwitchShowGreenYellow)/*如果显示绿黄灯开关【打开】*/
		{
			if ((RELAY_STATE_UP == lxRelaySta) && (RELAY_STATE_UP == firDsRelaySta))
			{
				returnValue = SIGNAL_SHOWCOLOUR_GREEN;	/*绿灯*/
			}
			else if ((RELAY_STATE_DOWN == lxRelaySta) && (RELAY_STATE_UP == firDsRelaySta))
			{
				returnValue = SIGNAL_SHOWCOLOUR_RED;	/*红灯*/
			}
			else
			{
				returnValue = SIGNAL_SHOWCOLOUR_INVALID;/*无效*/
			}

		}
		break;
	}
	case SIGNAL_TYPE_3_NOGREENWHITE_CD:/*0x32	矮柱3灯位：绿、红、白，封绿、白灯*/
	{
		if (FUNC_SWITCH_ON == bCiSwitchShowGreenYellow)/*如果显示绿黄灯开关【打开】*/
		{
			if ((RELAY_STATE_UP == firDsRelaySta))
			{
				returnValue = SIGNAL_SHOWCOLOUR_RED;	/*红灯*/
			}
			else
			{
				returnValue = SIGNAL_SHOWCOLOUR_INVALID;/*无效*/
			}

		}
		break;
	}

	case SIGNAL_TYPE_4_NOGREENBLUE_NOYINDAO_ZX:/*0x34 联络线信号机（黄、绿、红、蓝四灯位，封绿、蓝灯，可单独点亮黄灯）*/
	{
		if (FUNC_SWITCH_ON == bCiSwitchShowGreenYellow)/*如果显示绿黄灯开关【打开】*/
		{
			if ((RELAY_STATE_UP == lxRelaySta) && (RELAY_STATE_UP == firDsRelaySta))
			{
				returnValue = SIGNAL_SHOWCOLOUR_YELLOW;/*亮黄灯*/
			}
			else if ((RELAY_STATE_DOWN == lxRelaySta) && (RELAY_STATE_UP == firDsRelaySta))
			{
				returnValue = SIGNAL_SHOWCOLOUR_RED;/*亮红灯*/
			}
			else
			{
				returnValue = SIGNAL_SHOWCOLOUR_INVALID;/*无效*/
			}

		}
		break;
	}
	case SIGNAL_TYPE_3_ALL_NOYINDAO_CD:/*0x35 矮柱三显信号机(不封灯、不带引导)（红白绿）*/
	{
		if ((RELAY_STATE_DOWN == lxRelaySta) && (RELAY_STATE_DOWN == dxRelaySta) && (RELAY_STATE_UP == firDsRelaySta))
		{
			returnValue = SIGNAL_SHOWCOLOUR_RED;/*亮红灯*/
		}
		else if ((RELAY_STATE_UP == lxRelaySta) && (RELAY_STATE_DOWN == dxRelaySta) && (RELAY_STATE_UP == firDsRelaySta))
		{
			returnValue = SIGNAL_SHOWCOLOUR_GREEN;/*亮绿灯*/
		}
		else if ((RELAY_STATE_DOWN == lxRelaySta) && (RELAY_STATE_UP == dxRelaySta) && (RELAY_STATE_UP == firDsRelaySta))
		{
			returnValue = SIGNAL_SHOWCOLOUR_WHITE;/*亮白灯*/
		}
		else
		{
			returnValue = SIGNAL_SHOWCOLOUR_INVALID;/*无效*/
		}
		break;
	}
	case SIGNAL_TYPE_1_ALL_END:/*0x36 单显示尽头阻挡信号机*/
	{
		if (RELAY_STATE_UP == firDsRelaySta)
		{
			returnValue = SIGNAL_SHOWCOLOUR_RED;/*亮红灯*/
		}
		else
		{
			returnValue = SIGNAL_SHOWCOLOUR_INVALID;/*无效*/
		}
		break;
	}
	case SIGNAL_TYPE_THREE_ALL_YINDAO:/*三显示（红、黄、绿、红黄）*/
	{
		if ((RELAY_STATE_DOWN == lxRelaySta)
			&& (RELAY_STATE_DOWN == yxRelaySta)
			&& (RELAY_STATE_UP == firDsRelaySta)
			&& (RELAY_STATE_DOWN == secDsRelaySta))
		{/*列车信号继电器落下、引导信号机落下、1灯丝继电器吸起、2灯丝继电器落下*/

			returnValue = SIGNAL_SHOWCOLOUR_RED;/*红亮*/
		}
		else if ((RELAY_STATE_UP == lxRelaySta)
			&& (RELAY_STATE_DOWN == zxRelaySta)
			&& (RELAY_STATE_DOWN == yxRelaySta)
			&& (RELAY_STATE_UP == firDsRelaySta)
			&& (RELAY_STATE_DOWN == secDsRelaySta))
		{/*列车信号继电器吸起、正线信号继电器落下、引导信号机落下、1灯丝继电器吸起、2灯丝继电器落下*/

			returnValue = SIGNAL_SHOWCOLOUR_YELLOW;/*黄亮*/
		}

		else if ((RELAY_STATE_DOWN == lxRelaySta)
			&& (RELAY_STATE_UP == yxRelaySta)
			&& (RELAY_STATE_UP == firDsRelaySta)
			&& (RELAY_STATE_UP == secDsRelaySta))
		{/*列车信号继电器落下、引导信号机吸起、1灯丝继电器吸起、2灯丝继电器吸起*/

			returnValue = SIGNAL_SHOWCOLOUR_REDYELLOW;/*红黄亮*/
		}
		else if ((RELAY_STATE_UP == lxRelaySta)
			&& (RELAY_STATE_UP == zxRelaySta)
			&& (RELAY_STATE_DOWN == yxRelaySta)
			&& (RELAY_STATE_UP == firDsRelaySta)
			&& (RELAY_STATE_DOWN == secDsRelaySta))
		{/*列车信号继电器吸起、正线信号继电器吸起、引导信号机落下、1灯丝继电器吸起、2灯丝继电器落下*/

			returnValue = SIGNAL_SHOWCOLOUR_GREEN;/*绿亮*/
		}
		else
		{
			returnValue = SIGNAL_SHOWCOLOUR_INVALID;
		}
		break;
	}
	case SIGNAL_TYPE_THREE_ALL_NOYINDAO:/*三显示无引导（红、黄、绿）*/
	{
		if ((RELAY_STATE_DOWN == lxRelaySta)
			&& (RELAY_STATE_UP == firDsRelaySta))
		{/*列车信号继电器落下、1灯丝继电器吸起*/

			returnValue = SIGNAL_SHOWCOLOUR_RED;/*红亮*/
		}
		else if ((RELAY_STATE_UP == lxRelaySta)
			&& (RELAY_STATE_DOWN == zxRelaySta)
			&& (RELAY_STATE_UP == firDsRelaySta))
		{/*列车信号继电器吸起、正线信号继电器落下、1灯丝继电器吸起*/

			returnValue = SIGNAL_SHOWCOLOUR_YELLOW;/*黄亮*/
		}
		else if ((RELAY_STATE_UP == lxRelaySta)
			&& (RELAY_STATE_UP == zxRelaySta)
			&& (RELAY_STATE_UP == firDsRelaySta))
		{/*列车信号继电器吸起、正线信号继电器吸起、1灯丝继电器吸起*/

			returnValue = SIGNAL_SHOWCOLOUR_GREEN;/*绿亮*/
		}
		else
		{
			returnValue = SIGNAL_SHOWCOLOUR_INVALID;
		}
		break;
	}
	case SIGNAL_TYPE_THREE_NOGREEN_YINDAO:/*三显示封绿灯（红、黄、红黄）*/
	{
		if ((RELAY_STATE_DOWN == lxRelaySta)
			&& (RELAY_STATE_DOWN == yxRelaySta)
			&& (RELAY_STATE_UP == firDsRelaySta)
			&& (RELAY_STATE_DOWN == secDsRelaySta))
		{/*列车信号继电器落下、引导信号机落下、1灯丝继电器吸起、2灯丝继电器落下*/

			returnValue = SIGNAL_SHOWCOLOUR_RED;/*红亮*/
		}
		else if ((RELAY_STATE_UP == lxRelaySta)
			&& (RELAY_STATE_DOWN == yxRelaySta)
			&& (RELAY_STATE_UP == firDsRelaySta)
			&& (RELAY_STATE_DOWN == secDsRelaySta))
		{/*列车信号继电器吸起、引导信号机落下、1灯丝继电器吸起、2灯丝继电器落下*/

			returnValue = SIGNAL_SHOWCOLOUR_YELLOW;/*黄亮*/
		}
		else if ((RELAY_STATE_DOWN == lxRelaySta)
			&& (RELAY_STATE_UP == yxRelaySta)
			&& (RELAY_STATE_UP == firDsRelaySta)
			&& (RELAY_STATE_UP == secDsRelaySta))
		{/*列车信号继电器落下、引导信号机吸起、1灯丝继电器吸起、2灯丝继电器吸起*/

			returnValue = SIGNAL_SHOWCOLOUR_REDYELLOW;/*红黄亮*/
		}
		else
		{
			returnValue = SIGNAL_SHOWCOLOUR_INVALID;
		}
		break;
	}
	case SIGNAL_TYPE_THREE_NOGREEN_NOYINDAO:/*三显示封绿灯无引导（红、黄）*/
	{
		if ((RELAY_STATE_DOWN == lxRelaySta)
			&& (RELAY_STATE_UP == firDsRelaySta))
		{/*列车信号继电器落下、1灯丝继电器吸起*/

			returnValue = SIGNAL_SHOWCOLOUR_RED;/*红亮*/
		}
		else if ((RELAY_STATE_UP == lxRelaySta)
			&& (RELAY_STATE_UP == firDsRelaySta))
		{/*列车信号继电器吸起、1灯丝继电器吸起*/

			returnValue = SIGNAL_SHOWCOLOUR_YELLOW;/*黄亮*/
		}
		else
		{
			returnValue = SIGNAL_SHOWCOLOUR_INVALID;
		}
		break;
	}
	case SIGNAL_TYPE_THREE_NOYELLOW_YINDAO:/*进段信号机(三显示，无黄灯，可引导，无灭灯)*/
	{
		if ((RELAY_STATE_DOWN == lxRelaySta)
			&& (RELAY_STATE_DOWN == yxRelaySta)
			&& (RELAY_STATE_UP == firDsRelaySta)
			&& (RELAY_STATE_DOWN == secDsRelaySta))
		{/*列车信号继电器落下、引导信号机落下、1灯丝继电器吸起、2灯丝继电器落下*/

			returnValue = SIGNAL_SHOWCOLOUR_RED;/*红亮*/
		}
		else if ((RELAY_STATE_UP == lxRelaySta)
			&& (RELAY_STATE_DOWN == yxRelaySta)
			&& (RELAY_STATE_UP == firDsRelaySta)
			&& (RELAY_STATE_DOWN == secDsRelaySta))
		{/*列车信号继电器吸起、引导信号机落下、1灯丝继电器吸起、2灯丝继电器落下*/

			returnValue = SIGNAL_SHOWCOLOUR_GREEN;/*绿亮*/
		}
		else if ((RELAY_STATE_DOWN == lxRelaySta)
			&& (RELAY_STATE_UP == yxRelaySta)
			&& (RELAY_STATE_UP == firDsRelaySta)
			&& (RELAY_STATE_UP == secDsRelaySta))
		{/*列车信号继电器落下、引导信号机吸起、1灯丝继电器吸起、2灯丝继电器吸起*/

			returnValue = SIGNAL_SHOWCOLOUR_REDYELLOW;/*红黄亮*/
		}
		else
		{
			returnValue = SIGNAL_SHOWCOLOUR_INVALID;
		}
		break;
	}
	case SIGNAL_TYPE_THREE_ALL_YINDAO_NOY:/*道岔防护信号机(三显示，不封灯，带引导，不可单独点亮黄灯)*/
	{
		if ((RELAY_STATE_DOWN == lxRelaySta)
			&& (RELAY_STATE_DOWN == yxRelaySta)
			&& (RELAY_STATE_UP == firDsRelaySta)
			&& (RELAY_STATE_DOWN == secDsRelaySta))
		{/*列车信号继电器落下、引导信号机落下、1灯丝继电器吸起、2灯丝继电器落下*/

			returnValue = SIGNAL_SHOWCOLOUR_RED;/*红亮*/
		}
		else if ((RELAY_STATE_UP == lxRelaySta)
			&& (RELAY_STATE_DOWN == yxRelaySta)
			&& (RELAY_STATE_UP == firDsRelaySta)
			&& (RELAY_STATE_DOWN == secDsRelaySta))
		{/*列车信号继电器吸起、引导信号机落下、1灯丝继电器吸起、2灯丝继电器落下*/

			returnValue = SIGNAL_SHOWCOLOUR_GREEN;/*绿亮*/
		}
		else if ((RELAY_STATE_DOWN == lxRelaySta)
			&& (RELAY_STATE_UP == yxRelaySta)
			&& (RELAY_STATE_UP == firDsRelaySta)
			&& (RELAY_STATE_UP == secDsRelaySta))
		{/*列车信号继电器落下、引导信号机吸起、1灯丝继电器吸起、2灯丝继电器吸起*/

			returnValue = SIGNAL_SHOWCOLOUR_REDYELLOW;/*红黄亮*/
		}
		else
		{
			returnValue = SIGNAL_SHOWCOLOUR_INVALID;
		}
		break;
	}
	case SIGNAL_TYPE_THREE_NOYELLOW_NOYINDAO:/*三显示封黄灯无引导（红、绿）*/
	case SIGNAL_TYPE_TWO_ALL_NOYINDAO:/*两显示（红、绿）*/
	{
		if ((RELAY_STATE_DOWN == lxRelaySta)
			&& (RELAY_STATE_UP == firDsRelaySta))
		{/*列车信号继电器落下、1灯丝继电器吸起*/

			returnValue = SIGNAL_SHOWCOLOUR_RED;/*红亮*/
		}
		else if ((RELAY_STATE_UP == lxRelaySta)
			&& (RELAY_STATE_UP == firDsRelaySta))
		{/*列车信号继电器吸起、1灯丝继电器吸起*/

			returnValue = SIGNAL_SHOWCOLOUR_GREEN;/*绿亮*/
		}
		else
		{
			returnValue = SIGNAL_SHOWCOLOUR_INVALID;
		}
		break;
	}
	case SIGNAL_TYPE_TWO_NOGREEN_NOYINDAO:/*两显示封绿灯（仅红）*/
	{
		if (RELAY_STATE_UP == firDsRelaySta)
		{/*1灯丝继电器吸起*/

			returnValue = SIGNAL_SHOWCOLOUR_RED;/*红亮*/
		}
		else
		{
			returnValue = SIGNAL_SHOWCOLOUR_INVALID;
		}
		break;
	}
	case SIGNAL_TYPE_DIAOCHE:/*调车信号机（红、白）*/
	{
		if ((RELAY_STATE_DOWN == dxRelaySta)
			&& (RELAY_STATE_UP == firDsRelaySta))
		{/*调车信号继电器落下、1灯丝继电器吸起*/

			returnValue = SIGNAL_SHOWCOLOUR_RED;/*红亮*/
		}
		else if ((RELAY_STATE_UP == dxRelaySta)
			&& (RELAY_STATE_UP == firDsRelaySta))
		{/*调车信号继电器吸起、1灯丝继电器吸起*/

			returnValue = SIGNAL_SHOWCOLOUR_WHITE;/*白亮*/
		}
		else
		{
			returnValue = SIGNAL_SHOWCOLOUR_INVALID;
		}
		break;
	}
	case SIGNAL_TYPE_JINKUCHUKU:/*进库出库信号机*/
	{
		if ((RELAY_STATE_DOWN == dxRelaySta)
			&& (RELAY_STATE_DOWN == lxRelaySta)
			&& (RELAY_STATE_UP == firDsRelaySta))
		{/*调车信号继电器落下、列车信号继电器落下、1灯丝继电器吸起*/

			returnValue = SIGNAL_SHOWCOLOUR_RED;/*红亮*/
		}
		else if ((RELAY_STATE_UP == dxRelaySta)
			&& (RELAY_STATE_DOWN == lxRelaySta)
			&& (RELAY_STATE_UP == firDsRelaySta))
		{/*调车信号继电器吸起、列车信号继电器落下、1灯丝继电器吸起*/

			returnValue = SIGNAL_SHOWCOLOUR_WHITE;/*白亮*/
		}
		else if ((RELAY_STATE_DOWN == dxRelaySta)
			&& (RELAY_STATE_UP == lxRelaySta)
			&& (RELAY_STATE_UP == firDsRelaySta))
		{/*调车信号继电器落下、列车信号继电器吸起、1灯丝继电器吸起*/

			returnValue = SIGNAL_SHOWCOLOUR_YELLOW;/*黄亮*/
		}
		else
		{
			returnValue = SIGNAL_SHOWCOLOUR_INVALID;
		}
		break;
	}
	case SIGNAL_TYPE_TWO_JINKU_RGY:/*进段/进库信号机(三显示),仅亮红灯、亮绿灯和亮红黄灯*/
	{
		if ((RELAY_STATE_UP == lxRelaySta)
			&& (RELAY_STATE_DOWN == yxRelaySta))
		{/*列车信号继电器吸起 && 引导信号继电器落下*/

			returnValue = SIGNAL_SHOWCOLOUR_GREEN;/*绿亮*/
		}
		else if ((RELAY_STATE_DOWN == lxRelaySta)
			&& (RELAY_STATE_UP == yxRelaySta))
		{/*列车信号继电器落下 && 引导信号继电器吸起*/

			returnValue = SIGNAL_SHOWCOLOUR_REDYELLOW;/*红黄灯*/
		}
		else if ((RELAY_STATE_DOWN == lxRelaySta)
			&& (RELAY_STATE_DOWN == yxRelaySta))
		{/*列车信号继电器落下 && 引导信号继电器落下*/

			returnValue = SIGNAL_SHOWCOLOUR_RED;/*红亮*/
		}
		else
		{
			returnValue = SIGNAL_SHOWCOLOUR_INVALID;
		}
		break;
	}
	case SIGNAL_TYPE_3_NOGREEN_YINDAO_NOL:/*道岔防护信号机(三显示，封绿灯，带引导，不能灭灯)*/
	{
		if ((RELAY_STATE_UP == lxRelaySta)
			&& (RELAY_STATE_DOWN == yxRelaySta)
			&& (RELAY_STATE_UP == firDsRelaySta)
			&& (RELAY_STATE_DOWN == secDsRelaySta))
		{/*列车信号继电器吸起 && 引导信号继电器落下 && 1灯丝继电器吸起 && 2灯丝继电器落下*/

			returnValue = SIGNAL_SHOWCOLOUR_YELLOW;/*黄亮*/
		}
		else if ((RELAY_STATE_DOWN == lxRelaySta)
			&& (RELAY_STATE_UP == yxRelaySta)
			&& (RELAY_STATE_UP == firDsRelaySta)
			&& (RELAY_STATE_UP == secDsRelaySta))
		{/*列车信号继电器落下 && 引导信号继电器吸起 && 1灯丝继电器吸起 && 2灯丝继电器吸起*/

			returnValue = SIGNAL_SHOWCOLOUR_REDYELLOW;/*红黄灯*/
		}
		else if ((RELAY_STATE_DOWN == lxRelaySta)
			&& (RELAY_STATE_DOWN == yxRelaySta)
			&& (RELAY_STATE_UP == firDsRelaySta)
			&& (RELAY_STATE_DOWN == secDsRelaySta))
		{/*列车信号继电器落下 && 引导信号继电器落下 && 1灯丝继电器吸起 && 2灯丝继电器落下*/

			returnValue = SIGNAL_SHOWCOLOUR_RED;/*红亮*/
		}
		else
		{
			returnValue = SIGNAL_SHOWCOLOUR_INVALID;
		}
		break;
	}
	case SIGNAL_TYPE_THREE_DIAOCHE_YINDAO:/*进段带引导调车信号机(三显示，可引导红白灯，无灭灯)*/
	{
		if ((RELAY_STATE_DOWN == dxRelaySta)
			&& (RELAY_STATE_DOWN == yxRelaySta)
			&& (RELAY_STATE_UP == firDsRelaySta)
			&& (RELAY_STATE_DOWN == secDsRelaySta))
		{/*调车信号继电器落下、引导信号继电器落下、1灯丝继电器吸起、2灯丝继电器落下*/

			returnValue = SIGNAL_SHOWCOLOUR_RED;/*红亮*/
		}
		else if ((RELAY_STATE_UP == dxRelaySta)
			&& (RELAY_STATE_DOWN == yxRelaySta)
			&& (RELAY_STATE_UP == firDsRelaySta)
			&& (RELAY_STATE_DOWN == secDsRelaySta))
		{/*调车信号继电器吸起、引导信号继电器落下、1灯丝继电器吸起、2灯丝继电器落下*/

			returnValue = SIGNAL_SHOWCOLOUR_WHITE;/*白亮*/
		}
		else if ((RELAY_STATE_DOWN == dxRelaySta)
			&& (RELAY_STATE_UP == yxRelaySta)
			&& (RELAY_STATE_UP == firDsRelaySta)
			&& (RELAY_STATE_UP == secDsRelaySta))
		{/*调车信号继电器落下、引导信号继电器吸起、1灯丝继电器吸起、2灯丝继电器吸起*/

			returnValue = SIGNAL_SHOWCOLOUR_RED_WHITE;/*红白亮*/
		}
		else
		{
			returnValue = SIGNAL_SHOWCOLOUR_INVALID;
		}
		break;
	}
	case SIGNAL_TYPE_THREE_JINKU_YINDAO:  /*进库信号机（三显示带引导）*/  /*新机场车辆段新增信号机类型2019.1.15*/
	{
		if ((RELAY_STATE_UP == lxRelaySta)
			&& (RELAY_STATE_DOWN == dxRelaySta)
			&& (RELAY_STATE_DOWN == yxRelaySta)
			&& (RELAY_STATE_UP == firDsRelaySta)
			&& (RELAY_STATE_DOWN == secDsRelaySta))
		{/*列车信号继电器吸起、调车信号继电器落下、引导信号继电器落下、1灯丝继电器吸起、2灯丝继电器落下*/
			returnValue = SIGNAL_SHOWCOLOUR_YELLOW;/*黄亮*/
		}
		else if ((RELAY_STATE_DOWN == lxRelaySta)
			&& (RELAY_STATE_UP == dxRelaySta)
			&& (RELAY_STATE_DOWN == yxRelaySta)
			&& (RELAY_STATE_UP == firDsRelaySta)
			&& (RELAY_STATE_DOWN == secDsRelaySta))
		{ /*列车信号继电器落下、调车信号继电器吸起、引导信号继电器落下、1灯丝继电器吸起、2灯丝继电器落下*/
			returnValue = SIGNAL_SHOWCOLOUR_WHITE;/*白亮*/
		}
		else if ((RELAY_STATE_DOWN == lxRelaySta)
			&& (RELAY_STATE_DOWN == dxRelaySta)
			&& (RELAY_STATE_DOWN == yxRelaySta)
			&& (RELAY_STATE_UP == firDsRelaySta)
			&& (RELAY_STATE_DOWN == secDsRelaySta))
		{ /*列车信号继电器落下、调车信号继电器落下、引导信号继电器落下、1灯丝继电器吸起、2灯丝继电器落下*/
			returnValue = SIGNAL_SHOWCOLOUR_RED;/*红亮*/
		}
		else if ((RELAY_STATE_DOWN == lxRelaySta)
			&& (RELAY_STATE_DOWN == dxRelaySta)
			&& (RELAY_STATE_UP == yxRelaySta)
			&& (RELAY_STATE_UP == firDsRelaySta)
			&& (RELAY_STATE_UP == secDsRelaySta))
		{/*列车信号继电器落下、调车信号继电器落下、引导信号继电器吸起、1灯丝继电器吸起、2灯丝继电器吸起*/
			returnValue = SIGNAL_SHOWCOLOUR_REDYELLOW;/*红黄灯*/
		}
		else
		{
			returnValue = SIGNAL_SHOWCOLOUR_INVALID;  /*无效继电器组合*/
		}
		break;
	}
	default:
	{
		returnValue = SIGNAL_SHOWCOLOUR_INVALID;
		break;
	}
	}
	return returnValue;
}


/*
* 功能描述： 更新进路的调车同意逻辑状态
* 参数说明： void
* 返回值  ： void
* BY CGH 20250523
*/
void RouteDCTYRelayToDeviceStateProc(void)
{
	UINT16 ii = 0U;		                     /*游标*/
	UINT16 routeCurSum = 0U;	             /*进路总数*/
	UINT16 routeId = 0U;	             /*进路ID*/
	UINT8 localCi = 0U;
	UINT8 belongCi = 0U;
	UINT8 tmpExecRes = CI_ERROR;/*临时执行结果*/
	UINT8 reVal = CI_ERROR;/*返回值*/
	UINT16 routeDCTYId = 0U;/*调车同意继电器id*/
	UINT8 relayCollState = 0U;/*继电器采集状态*/
	UINT8 chRouteType = 0U; /*进路类型*/
	UINT32 dwDcAgreeBtnPressCycNum = 0U;/*调车同意按钮按下起始周期*/
	UINT32 dwCurCycleNum = Get2oo2CurCycleNum(); /*当前周期号*/
	UINT32 dwZfsBtnFaultCycNum = 0U;  /*自复式按钮故障判断周期*/
	UINT32 dwZfsBtnRelayCollCycNum = 0U;   /*自复式按钮继电器采集周期*/
	UINT8 chOverTimeCheckFlag = 0U;/*超时检查标志*/
	UINT8 chDcAgreeButtonErrState = 0U;/*调车同意按钮故障状态*/

	routeCurSum = GetRouteCurSum();
	localCi = GetSystemParaLocalCiId();/*本机联锁*/

	for (ii = 0U; ii < routeCurSum; ii++)
	{
		routeId = GetRouteId(ii);

		if((0U < routeId) && (ROUTE_SUM_MAX > routeId))
		{
			/*验证进路必须为本机联锁*/
			belongCi = GetRouteBelongCiId(routeId);

			if (belongCi == localCi)
			{
				routeDCTYId = GetRouteDCTAJId(routeId);/*获取进路调车同意继电器id*/
				chRouteType = GetRouteType(routeId);

				if((0U < routeDCTYId) && (ROUTE_TYPE_DIAOCHE == chRouteType))
				{
					relayCollState = GetRelayCollState(routeDCTYId);
					if (RELAY_STATE_UP == relayCollState)
					{
						dwDcAgreeBtnPressCycNum = GetRouteDcAgreeBtnPressCycNum(routeId);

						if (0U == dwDcAgreeBtnPressCycNum)
						{
							SetRouteDcAgreeBtnPressCycNum(routeId, dwCurCycleNum);
						}
						else
						{
							; 
						}

					}
					else
					{
						SetRouteDcAgreeBtnPressCycNum(routeId, 0U);
					}

					dwDcAgreeBtnPressCycNum = GetRouteDcAgreeBtnPressCycNum(routeId);
					dwZfsBtnFaultCycNum = GetSelfButErrCount();
					chOverTimeCheckFlag = SystemOverTimeCheck(dwDcAgreeBtnPressCycNum, dwZfsBtnFaultCycNum);

					if (CI_TIME_OUT == chOverTimeCheckFlag)
					{
						/*按钮按下大于故障时间，设置故障*/
						SetRouteDcAgreeButtonErrState(routeId, ROUTE_DC_AGREE_BUTTON_ERR);
					}
					else
					{
						SetRouteDcAgreeButtonErrState(routeId, ROUTE_DC_AGREE_BUTTON_OK);
					}

					dwZfsBtnRelayCollCycNum = GetSelfButCollCount();
					chOverTimeCheckFlag = SystemOverOrEqualTimeCheck(dwDcAgreeBtnPressCycNum, dwZfsBtnRelayCollCycNum);
					chDcAgreeButtonErrState = GetRouteDcAgreeButtonErrState(routeId);


					/*按钮按下时间大于等于判断采集有效时间且未故障，设置调车同意按钮有效*/
					if ((CI_TIME_OUT == chOverTimeCheckFlag) && (ROUTE_DC_AGREE_BUTTON_OK == chDcAgreeButtonErrState))
					{
						SetRouteDCTYState(routeId, ROUTE_DCT_AGREE);
					}
					else
					{
						/*不处理*/
					}

				}
				else
				{
					; /*无配置或非调车进路不处理*/
				}
			}
			else
			{
				; /*非本联锁进路不处理*/
			}
		}
		else
		{
			; /*不处理*/
		}
	}
}


/*
* 功能描述： 更新调车同意继电器状态
* 参数说明： void
* 返回值  ： 无
*/
void RouteDCTYToRelayStateProc(void)
{
	UINT16 ii = 0U;		/* 游标 */
	UINT16 routeSum = 0U;	/* 进路总数 */
	UINT16 routeId = 0U;	/*  ID */
	UINT8 chRouteType = 0U;/*进路类型*/
	UINT16 routeDCQRelayId = 0U;
	UINT16 routeDCQRelayTwoId = 0U;
	UINT8 routeDCQState = 0U;
	UINT8 localCi = 0U;
	UINT8 belongCi = 0U;

	routeSum = GetRouteCurSum();
	localCi = GetSystemParaLocalCiId();/*本机联锁*/

	for (ii = 0U; ii < routeSum; ii++)
	{
		routeId = GetRouteId(ii);

		if ((0U < routeId) && (ROUTE_SUM_MAX > routeId))
		{
			/*验证进路必须为本机联锁*/
			belongCi = GetRouteBelongCiId(routeId);

			if (belongCi == localCi)
			{
				routeDCQRelayId = GetRouteDCQJId(routeId);
				routeDCQRelayTwoId = GetRouteDCQJTwoId(routeId);
				chRouteType = GetRouteType(routeId);

				if ((0U < routeDCQRelayId) && (0U < routeDCQRelayTwoId) && (ROUTE_TYPE_DIAOCHE == chRouteType))
				{			
					routeDCQState = GetRouteDCQState(routeId);

					if (ROUTE_DCQ_REQUEST == routeDCQState)
					{
						/*有调车请求，设置调车请求继电器驱动为吸起*/
						(void)SetRelayDriveState(routeDCQRelayId, RELAY_DRIVE_STATE_UP);
						(void)SetRelayDriveState(routeDCQRelayTwoId, RELAY_DRIVE_STATE_UP);
					}
					else
					{
						/*无调车请求，设置调车请求继电器驱动为落下*/
						(void)SetRelayDriveState(routeDCQRelayId, RELAY_DRIVE_STATE_DOWN);
						(void)SetRelayDriveState(routeDCQRelayTwoId, RELAY_DRIVE_STATE_DOWN);
					}
				}
				else
				{
					; /*无配置或非调车进路不处理*/
				}
			}
			else
			{
				; /*非本联锁进路不处理*/
			}
		}
		else
		{
			; /*不处理*/
		}
	}
	
}

/*
* 功能描述： 设置只有采集列车信号继电器状态的信号机颜色
* 参数说明： const UINT16 signalId :信号机ID
* 返回值  ： 无
*/
void SetNoDriveSignalCurColor(const UINT16 signalId)
{
	UINT16 firDsRelayId = 0u;  	/*1灯丝继电器ID */
	UINT16 secDsRelayId = 0u;  	/*2灯丝继电器ID*/
	UINT16 lxRelayId = 0u;    	/*列车信号继电器ID*/
	UINT16 zxRelayId = 0u;    	/*正线信号继电器ID*/
	UINT16 yxRelayId = 0u;    	/*引导信号继电器ID*/
	UINT16 dxRelayId = 0u;		/*调车信号继电器ID*/
	UINT16 yellowRelayId = 0u;	/*黄灯继电器ID*/
	UINT16 greenRelayId = 0u;	/*绿灯继电器ID*/
	UINT16 blueRelayId = 0u;		/*蓝灯继电器ID*/
	UINT16 replxRelayId = 0u;    /*复示列车信号继电器ID*/
	UINT16 ddRelayId = 0u;    	/*点灯继电器ID*/
	UINT8  blockOpenColor = 0u;  /*后备模式需要开放颜色*/
	UINT8 signalType = 0u;	/*信号机点灯电路类型*/
	UINT8 repLxRelaySta = RELAY_STATE_DOWN;     /*复示列车信号继电器状态*/

	firDsRelayId = GetSignalFirstDsRelayId(signalId);  /*获取信号机1灯丝继电器ID*/
	secDsRelayId = GetSignalSecondDsRelayId(signalId);  /*获取信号机2灯丝继电器ID*/
	lxRelayId = GetSignalLxRelayId(signalId);  /*获取信号机列车信号继电器ID*/
	zxRelayId = GetSignalZxRelayId(signalId);  /*获取信号机正线信号继电器ID*/
	yxRelayId = GetSignalYxRelayId(signalId);  /*获取信号机引导信号继电器ID*/
	dxRelayId = GetSignalDxRelayId(signalId);	/*获取信号机调车信号继电器ID*/
	yellowRelayId = GetSignalYellowRelayId(signalId);	/*黄灯继电器ID*/
	greenRelayId = GetSignalGreenRelayId(signalId);		/*绿灯继电器ID*/
	blueRelayId = GetSignalBlueRelayId(signalId);		/*蓝灯继电器ID*/
	replxRelayId = GetSignalRepLxRelayId(signalId);
	ddRelayId = GetSignalDdRelayId(signalId);  /*获取信号机点灯继电器ID*/
	signalType = GetSignalType(signalId);	/*获取信号机点灯逻辑类型*/
	repLxRelaySta = GetRelayCollState(replxRelayId); /*获取复示列车信号继电器继电器状态*/

	/*只有采集：判断除了LXJ，其他继电器ID全为0u；武汉5-8号线联络线需求*/
	if ((0u == firDsRelayId) && (0u == secDsRelayId) && (0u == lxRelayId) && (0u == zxRelayId)
		&& (0u == yxRelayId) && (0u == dxRelayId) && (0u == yellowRelayId) && (0u == greenRelayId)
		&& (0u == blueRelayId) && (0u != replxRelayId))
	{
		if (RELAY_STATE_UP == repLxRelaySta)
		{
			/*获取信号机后背模式开放颜色*/
			blockOpenColor = GetSignalBlockOpenColorValue((UINT16)signalType);
			/*设置灯色*/
			(void)SetSignalCurColor(signalId, blockOpenColor);
		}
		else
		{
			/*设置红灯*/
			(void)SetSignalCurColor(signalId, SIGNAL_SHOWCOLOUR_RED);
		}
	}

}

/*
* 功能描述： 检查取消自动触发标志是否执行
* 参数说明： const UINT16 routeId :进路ID
*            const UINT16 phySecId :物理区段ID
* 返回值  ： CI_ERROR  检查失败
*            CI_SUCCESS 检查成功
* 对于封锁区段属于本联锁但进路不属于本联锁（虚拟联锁）的，不清除本联锁（虚拟联锁）的自动触发标志
*/
UINT8 CheckCancleAutoFlag(const UINT16 routeId, const UINT16 phySecId)
{
	UINT8 includeVirFlag = GetCiFunctionSwitchConfig(FUNC_INCLUDEVIRCI_FLAG);
	UINT8 reVal = CI_ERROR;
	UINT8 routeBelongCiId = 0u;

	UINT8 phySecBelongVirCiId = 0u;
	UINT8 routeBelongVirCiId = 0u;
	UINT8 localCiId = GetSystemParaLocalCiId();

	routeBelongCiId = GetRouteBelongCiId(routeId);
	if (routeBelongCiId == localCiId)
	{
		if (FUNC_SWITCH_ON == includeVirFlag)
		{
			phySecBelongVirCiId = GetPhySecBelongVirCiId(phySecId);
			routeBelongVirCiId = GetRouteBelongVirCiId(routeId);
			if ((phySecBelongVirCiId == routeBelongVirCiId) && (0U != routeBelongVirCiId))
			{
				reVal = CI_SUCCESS;
			}
		}
		else
		{
			reVal = CI_SUCCESS;
		}
	}
	return reVal;
}


/*
* 功能描述： 更新联络线设备采集状态至逻辑状态
* 参数说明： void
* 返回值  ： 无
*
*/
void ConnectLineRelayToDevStateProc(void)
{
	/*初始化*/
	UINT16 i = 0u;
	UINT8 devType = 0u;
	UINT16 devId = 0u;
	UINT8 devIsThisLine = 0u; /*设备是否本进路*/
	UINT8 relayColleState = 0u;
	UINT16 relayId = 0u;
	UINT8 localCiId = 0u;
	UINT8 belongCi = 0u;
	UINT16 dbRelayId = 0u;
	UINT16 fbRelayId = 0u;
	UINT16 dsRelayId = 0u;
	UINT16 dsQRelayId = 0u;
	UINT16 dsHRelayId = 0u;
	UINT16 byPassRelayId = 0u;
	UINT8 dbRelayState = 0u;
	UINT8 fbRelayState = 0u;
	UINT8 dsRelayState = 0u;
	UINT8 dsQRelayState = 0u;
	UINT8 dsHRelayState = 0u;
	UINT8 byPassRelayState = 0u;
	UINT16 ocConnetDataDevNum = 0u;
	UINT16 LxrelayId = 0u;
	UINT16 YxrelayId = 0u;
	UINT16 DxrelayId = 0u;
	UINT8 LxrelayColleState = 0u;
	UINT8 YxrelayColleState = 0u;
	UINT8 DxrelayColleState = 0u;
	OcConnetDataCfgStruct* pOcConnetDataCfgStru = NULL;
	UINT8 chBlocOpenColor = 0U;

	/*获取配置信息*/
	ocConnetDataDevNum = GetOcConnetDataDevNum();
	pOcConnetDataCfgStru = GetOcConnetDataCfgStruc();
	localCiId = GetSystemParaLocalCiId(); /*获取本地联锁ID*/

	if ((0u < ocConnetDataDevNum) && (OC_LIAISON_DEV_SUM_MAX > ocConnetDataDevNum) && (NULL != pOcConnetDataCfgStru))
	{
		for (i = 0u; i < ocConnetDataDevNum; i++)
		{
			/*设备信息*/
			devId = pOcConnetDataCfgStru[i].DevId;
			devType = pOcConnetDataCfgStru[i].DevType;
			/*信号机LXJ*/
			if (CI_DEVICE_TYPE_SIGNAL == devType)
			{
				devIsThisLine = GetSignalIsThisLineState(devId);
				if (DEV_IS_THIS_LINE_NO == devIsThisLine)
				{/*非本线路*/
					/*获取继电器采集状态，设备所在联锁*/
					belongCi = GetSignalBelongCiId(devId);
					if (belongCi == localCiId)
					{
						LxrelayId = GetSignalLxRelayId(devId);
						YxrelayId = GetSignalYxRelayId(devId);
						DxrelayId = GetSignalDxRelayId(devId);
						
						LxrelayColleState = GetRelayCollState(LxrelayId);
						YxrelayColleState = GetRelayCollState(YxrelayId);
						DxrelayColleState = GetRelayCollState(DxrelayId);

						if (RELAY_STATE_UP == LxrelayColleState)
						{
							/*对两个继电器都吸起的异常情况做防护*/
							if ((RELAY_STATE_UP == YxrelayColleState) || (RELAY_STATE_UP == DxrelayColleState))
							{
								/*设置红灯*/
								(void)SetSignalCurColor(devId, SIGNAL_SHOWCOLOUR_RED);
							}
							else
							{
								/*若配置后备开放颜色按照后备开放显示*/
								chBlocOpenColor = GetSignalBlockOpenColorValue(devId);
								if (0U != chBlocOpenColor)
								{
									(void)SetSignalCurColor(devId, chBlocOpenColor);
								}
								else
								{
									/*设置黄灯*/
									(void)SetSignalCurColor(devId, SIGNAL_SHOWCOLOUR_YELLOW);
								}
							}
						}
						else if (RELAY_STATE_UP == YxrelayColleState)
						{
							/*对两个继电器都吸起的异常情况做防护*/
							if ((RELAY_STATE_UP == LxrelayColleState) || (RELAY_STATE_UP == DxrelayColleState))
							{
								/*设置红灯*/
								(void)SetSignalCurColor(devId, SIGNAL_SHOWCOLOUR_RED);
							}
							else
							{
								/*设置红黄灯*/
								(void)SetSignalCurColor(devId, SIGNAL_SHOWCOLOUR_REDYELLOW);
							}
						}
						else if (RELAY_STATE_UP == DxrelayColleState)
						{
							/*对两个继电器都吸起的异常情况做防护*/
							if ((RELAY_STATE_UP == LxrelayColleState) || (RELAY_STATE_UP == YxrelayColleState))
							{
								/*设置红灯*/
								(void)SetSignalCurColor(devId, SIGNAL_SHOWCOLOUR_RED);
							}
							else
							{
								/*设置白灯*/
								(void)SetSignalCurColor(devId, SIGNAL_SHOWCOLOUR_WHITE);
							}
						}
						else
						{
							/*设置红灯*/
							(void)SetSignalCurColor(devId, SIGNAL_SHOWCOLOUR_RED);
						}
					}
				}
			}
			/*物理区段GJ*/
			else if (CI_DEVICE_TYPE_PHYSEC == devType)
			{
				/*获取区段信息*/
				belongCi = GetPhySecBelongCiId(devId);
				relayId = GetPhySecGdRelayId(devId);
				relayColleState = GetRelayCollState(relayId);
				devIsThisLine = GetPhyIsThisLineState(devId);
				if (DEV_IS_THIS_LINE_NO == devIsThisLine)
				{/*非本线路*/
					if (belongCi == localCiId)
					{
						if (RELAY_STATE_UP == relayColleState)
						{
							/*设置区段空闲*/
							SetPhySecCurOccupyState(devId, SECTION_OCCUPY_NO);
						}
						else
						{
							/*设置区段占用*/
							SetPhySecCurOccupyState(devId, SECTION_OCCUPY_YES);
						}
					}
				}
			}
			/*道岔*/
			else if (CI_DEVICE_TYPE_SWITCH == devType)
			{
				/*获取道岔信息*/
				belongCi = GetSwitchBelongCiId(devId);
				devIsThisLine = GetSwitchIsThisLineState(devId);
				dbRelayId = GetSwitchDbRelayId(devId);
				fbRelayId = GetSwitchFbRelayId(devId);
				dsRelayId = GetSwitchDsRelayId(devId);
				dsQRelayId = GetSwitchDsQRelayId(devId);
				dsHRelayId = GetSwitchDsHRelayId(devId);
				byPassRelayId = GetSwitchByPassRelayId(devId);

				/*继电器状态*/
				dbRelayState = GetRelayCollState(dbRelayId);
				fbRelayState = GetRelayCollState(fbRelayId);
				dsRelayState = GetRelayCollState(dsRelayId);
				dsQRelayState = GetRelayCollState(dsQRelayId);
				dsHRelayState = GetRelayCollState(dsHRelayId);
				byPassRelayState = GetRelayCollState(byPassRelayId);

				if (DEV_IS_THIS_LINE_NO == devIsThisLine)
				{
					/*非本线路*/
					if (belongCi == localCiId)
					{
						/*定、反表ID大于0*/
						if ((0u < dbRelayId) && (0u < fbRelayId))
						{
							/*更新道岔位置*/
							if ((RELAY_STATE_UP == dbRelayState) && (RELAY_STATE_DOWN == fbRelayState))
							{
								/*设置道岔定位*/
								SetSwitchCurPosition(devId, SWITCH_POSITION_DINGWEI);
								/*设置道岔单独位置*/
								SetSingleSwitchCurPosition(devId, SWITCH_POSITION_DINGWEI);
							}
							else if ((RELAY_STATE_DOWN == dbRelayState) && (RELAY_STATE_UP == fbRelayState))
							{
								/*设置道岔反位*/
								SetSwitchCurPosition(devId, SWITCH_POSITION_FANWEI);
								/*设置道岔单独位置*/
								SetSingleSwitchCurPosition(devId, SWITCH_POSITION_FANWEI);
							}
							else
							{
								/*设置道岔四开*/
								SetSwitchCurPosition(devId, SWITCH_POSITION_SIKAI);
								/*设置道岔单独位置*/
								SetSingleSwitchCurPosition(devId, SWITCH_POSITION_SIKAI);

							}
						}
						/*旁路继电器大于0*/
						if (0u < byPassRelayId)
						{
							/*更新旁路状态*/
							if (RELAY_STATE_UP == byPassRelayState)
							{
								/*设置旁路状态*/
								SetConnetSwitchByPassState(devId, SWITCH_BYPASS_YES);
							}
							else
							{
								/*设置未旁路状态*/
								SetConnetSwitchByPassState(devId, SWITCH_BYPASS_NO);
							}
						}

						/*单锁不为0*/
						if (0u != dsRelayId)
						{
							if (RELAY_STATE_UP == dsRelayState)
							{
								/*设置未单锁*/
								SetConnetSwitchDsState(devId, CONNECT_SWITCH_DANSUO_NO);
							}
							else
							{
								/*设置单锁*/
								SetConnetSwitchDsState(devId, CONNECT_SWITCH_DANSUO_YES);
							}
						}
						/*前后节点两个继电器*/
						else
						{
							/*前后节点继电器*/
							if ((0u != dsQRelayId) && ((0u != dsHRelayId)))
							{
								/*前吸起，后落下*/
								if ((RELAY_STATE_UP == dsQRelayState) && (RELAY_STATE_DOWN == dsHRelayState))
								{
									/*设置未单锁*/
									SetConnetSwitchDsState(devId, CONNECT_SWITCH_DANSUO_NO);
								}
								else
								{
									/*设置单锁*/
									SetConnetSwitchDsState(devId, CONNECT_SWITCH_DANSUO_YES);
								}
							}
						}
					}
				}
				else if (DEV_IS_THIS_LINE_YES == devIsThisLine)
				{
					if (belongCi == localCiId)
					{
						/*旁路继电器大于0*/
						if (0u < byPassRelayId)
						{
							/*更新旁路状态*/
							if (RELAY_STATE_UP == byPassRelayState)
							{
								/*设置旁路状态*/
								SetConnetSwitchByPassState(devId, SWITCH_BYPASS_YES);
							}
							else
							{
								/*设置未旁路状态*/
								SetConnetSwitchByPassState(devId, SWITCH_BYPASS_NO);
							}
						}
					}
				}
				else
				{
				;	/*不处理*/
				}
			}
			else
			{
				/*不做处理*/
			}
		}
	}
}

/*
* 功能描述： 更新联络线设备逻辑状态至继电器驱动状态
* 参数说明： void
* 返回值  ： 无
*
*/
void UpdateConnectDriveRelayOutput(void)
{
	/*初始化*/
	UINT16 i = 0u;
	UINT8 devType = 0u;
	UINT16 devId = 0u;
	UINT16 relayId = 0u;				/*驱动继电器*/
	UINT16 LxrelayId = 0u;				/*驱动继电器*/
	UINT16 YxrelayId = 0u;				/*驱动继电器*/
	UINT16 DxrelayId = 0u;				/*驱动继电器*/
	UINT16 LxCollerelayId = 0u;			/*采集继电器*/
	UINT16 YxCollerelayId = 0u;			/*采集继电器*/
	UINT16 DxCollerelayId = 0u;			/*采集继电器*/
	UINT16 colleRelayId = 0u;			/*采集继电器*/
	UINT8 devIsThisLine = 0u; /*设备是否本进路*/
	UINT16 dbRelayId = 0u;				/*驱动继电器*/
	UINT16 fbRelayId = 0u;				/*驱动继电器*/
	UINT16 dsRelayId = 0u;				/*驱动继电器*/
	UINT16 dbColleRelayId = 0u;			/*采集继电器*/
	UINT16 fbColleRelayId = 0u;			/*采集继电器*/
	UINT16 dsColleRelayId = 0u;			/*采集继电器*/
	UINT8 localCiId = 0u;
	UINT8 belongCi = 0u;
	UINT8 devState = 0u;  /*设备状态*/
	UINT8 signalColor = 0u;
	UINT16 ocConnetDataDevNum = 0u;
	UINT8 switchBypassState = 0U;		/*本线路道岔旁路状态*/
	UINT8 switchCurPosition = 0U;		/*道岔当前状态*/
	UINT16 switchPhySecId = 0U;			/*道岔所在物理区段*/
	UINT8 switchPhyOccupyState = 0U;		/*道岔所在物理区段占用状态（融合占用状态）*/
	UINT32 switchBypassWaitCycSum = 0U;		/*本线路联络线道岔未及时取消旁路等待周期数*/
	UINT32 switchBypassStartCycNum = 0U;	/*联络线道岔旁路未及时取消起始周期*/
	UINT32 curCycle = 0U;
	UINT8 checkTimeState = CI_TIME_NO;
	OcConnetDataCfgStruct* pOcConnetDataCfgStru = NULL;
	UINT8 ciToAtsSendFlag = 0U;

	/*获取配置信息*/
	ocConnetDataDevNum = GetOcConnetDataDevNum();
	pOcConnetDataCfgStru = GetOcConnetDataCfgStruc();
	localCiId = GetSystemParaLocalCiId(); /*获取本地联锁ID*/
	switchBypassWaitCycSum = GetSwitchBypassWaitCount();		/*获取本线路联络线道岔未及时取消旁路等待时间*/
	curCycle = Get2oo2CurCycleNum();			/*获取当前周期*/

	if ((0u < ocConnetDataDevNum) && (OC_LIAISON_DEV_SUM_MAX > ocConnetDataDevNum) && (NULL != pOcConnetDataCfgStru))
	{
		for (i = 0u; i < ocConnetDataDevNum; i++)
		{
			/*设备信息*/
			devId = pOcConnetDataCfgStru[i].DevId;
			devType = pOcConnetDataCfgStru[i].DevType;
			/*信号机LXJ*/
			if (CI_DEVICE_TYPE_SIGNAL == devType)
			{
				belongCi = GetSignalBelongCiId(devId);
				if (belongCi == localCiId)
				{
					devIsThisLine = GetSignalIsThisLineState(devId);

					/*本线路*/
					if (DEV_IS_THIS_LINE_YES == devIsThisLine)
					{
						/*信号机信息*/
						signalColor = GetSignalCurColor(devId);
						devState = GetSignalOpenCloseState(signalColor);
						LxrelayId = GetSignalLxDrvRelayId(devId);
						YxrelayId = GetSignalYxDrvRelayId(devId);
						DxrelayId = GetSignalDxDrvRelayId(devId);
						
						/*信号开放*/
						if (SIGNAL_OPEN == devState)
						{
							if (SIGNAL_SHOWCOLOUR_REDYELLOW == signalColor)
							{
								/*驱动YXJ吸起*/
								(void)SetRelayDriveState(YxrelayId, RELAY_DRIVE_STATE_UP);
								(void)SetRelayDriveState(LxrelayId, RELAY_DRIVE_STATE_DOWN);
								(void)SetRelayDriveState(DxrelayId, RELAY_DRIVE_STATE_DOWN);
							}
							else if ((SIGNAL_SHOWCOLOUR_WHITE == signalColor) || (SIGNAL_SHOWCOLOUR_RED_WHITE == signalColor))
							{
								/*驱动DXJ吸起*/
								(void)SetRelayDriveState(DxrelayId, RELAY_DRIVE_STATE_UP);
								(void)SetRelayDriveState(LxrelayId, RELAY_DRIVE_STATE_DOWN);
								(void)SetRelayDriveState(YxrelayId, RELAY_DRIVE_STATE_DOWN);
							}
							else
							{
								/*驱动LXJ吸起*/
								(void)SetRelayDriveState(LxrelayId, RELAY_DRIVE_STATE_UP);
								(void)SetRelayDriveState(YxrelayId, RELAY_DRIVE_STATE_DOWN);
								(void)SetRelayDriveState(DxrelayId, RELAY_DRIVE_STATE_DOWN);
							}
						}
						else
						{
							/*驱动LXJ,YXJ,DXJ落下*/
							(void)SetRelayDriveState(LxrelayId, RELAY_DRIVE_STATE_DOWN);
							(void)SetRelayDriveState(YxrelayId, RELAY_DRIVE_STATE_DOWN);
							(void)SetRelayDriveState(DxrelayId, RELAY_DRIVE_STATE_DOWN);
						}

						/*检查驱采是否一致，不一致报混线*/
						LxCollerelayId = GetSignalLxRelayId(devId);
						ProcessCoupleRelayHunXianState(LxrelayId, LxCollerelayId);

						YxCollerelayId = GetSignalYxRelayId(devId);
						ProcessCoupleRelayHunXianState(YxrelayId, YxCollerelayId);

						DxCollerelayId = GetSignalDxRelayId(devId);
						ProcessCoupleRelayHunXianState(DxrelayId, DxCollerelayId);
					}
					else
					{
						/*不做处理*/
					}
				}
			}
			/*物理区段GJ*/
			else if (CI_DEVICE_TYPE_PHYSEC == devType)
			{
				/*获取区段信息*/
				belongCi = GetPhySecBelongCiId(devId);
				devIsThisLine = GetPhyIsThisLineState(devId);

				if (belongCi == localCiId)
				{
					/*本线路*/
					if (DEV_IS_THIS_LINE_YES == devIsThisLine)
					{
						/*获取区段当前采集状态*/
						devState = GetPhySecCurOccupyState(devId);
						relayId = GetPhySecGdDrvRelayId(devId);

						if (SECTION_OCCUPY_NO == devState)
						{
							/*空闲驱动GJ吸起*/
							(void)SetRelayDriveState(relayId, RELAY_DRIVE_STATE_UP);
						}
						else
						{
							/*驱动落下*/
							(void)SetRelayDriveState(relayId, RELAY_DRIVE_STATE_DOWN);
						}

						/*检查驱采是否一致，不一致报混线*/
						colleRelayId = GetPhySecGdRelayId(devId);
						ProcessCoupleRelayHunXianState(relayId, colleRelayId);
					}
					else
					{
						/*不做处理*/
					}
				}
			}
			/*道岔*/
			else if (CI_DEVICE_TYPE_SWITCH == devType)
			{
				/*获取道岔信息*/
				belongCi = GetSwitchBelongCiId(devId);
				devIsThisLine = GetSwitchIsThisLineState(devId);
				dbRelayId = GetSwitchDbDrvRelayId(devId);
				fbRelayId = GetSwitchFbDrvRelayId(devId);
				dsRelayId = GetSwitchDsDrvRelayId(devId);

				if (belongCi == localCiId)
				{
					/*本线路*/
					if (DEV_IS_THIS_LINE_YES == devIsThisLine)
					{
						/*获取单锁状态*/
						devState = GetSwitchLockStatus(devId);
						/*设置道岔单锁继电器状态*/
						if ((SWITCH_LOCK_STATUS_DANSUO == devState) || (SWITCH_LOCK_STATUS_DAP == devState))
						{
							/*落下*/
							(void)SetRelayDriveState(dsRelayId, RELAY_DRIVE_STATE_DOWN);
						}
						else
						{
							/*吸起*/
							(void)SetRelayDriveState(dsRelayId, RELAY_DRIVE_STATE_UP);
						}
						/*设置道岔位置继电器状态*/
						SetConnectSwitchPosRelayDrvSta(devId, dbRelayId, fbRelayId);

						/*检查本线路内的道岔是否被旁路，旁路了需要检查道岔是否在定位且区段未占压，开始计时*/
						switchBypassState = GetConnetSwitchByPassState(devId);
						if (SWITCH_BYPASS_YES == switchBypassState)
						{
							switchCurPosition = GetSwitchCurPosition(devId);
							switchPhySecId = GetSwitchPhySectionId(devId);
							switchPhyOccupyState = GetPhySecCurMergeState(switchPhySecId);
							switchBypassStartCycNum = GetSwitchBypassStartCycNum(devId);		/*获取指定ID联络线道岔旁路未及时取消起始周期*/
							ciToAtsSendFlag = GetCiToAtsByPassNoCancelFlag(devId);
							if ((SWITCH_POSITION_DINGWEI == switchCurPosition) && (SECTION_OCCUPY_NO == switchPhyOccupyState))
							{/*定位且空闲，开始计时，超时向ATS报警旁路未及时取消*/

								checkTimeState = SystemOverTimeCheck(switchBypassStartCycNum, switchBypassWaitCycSum);

								if (CI_TIME_NO == checkTimeState)
								{
									SetSwitchBypassStartCycNum(devId, curCycle);		/*设置指定ID联络线道岔旁路未及时取消起始周期*/
								}
								else if (CI_TIME_OUT == checkTimeState)
								{
									/*向ATS报警，联络线道岔旁路未及时取消*/
									if (CI_ATS_SW_BYPASS_NOCANCEL_NO == ciToAtsSendFlag)
									{
										SetCiSendCmdBackInfoData(CI_BACK_SWT_BYPASS_CANCEL_NO, CI_DEVICE_TYPE_SWITCH, devId, 0u, 0u);
										SetCiToAtsByPassNoCancelFlag(devId, CI_ATS_SW_BYPASS_NOCANCEL_YES);		/*已向ATS发报警，不再发，命令类型报警只报警一次*/
									}
									else
									{
										/*已发送过报警，不再发送*/
									}
								}
								else
								{
									;	/*未超时，不处理*/
								}
							}
							else
							{
								/*出清计时，等待再空闲时重新计时*/
								SetSwitchBypassStartCycNum(devId, 0U);
								SetCiToAtsByPassNoCancelFlag(devId, CI_ATS_SW_BYPASS_NOCANCEL_NO);		/*出清发送记录*/
							}
						}
						else
						{
							/*未旁路，出清起始周期号*/
							SetSwitchBypassStartCycNum(devId, 0U);
							SetCiToAtsByPassNoCancelFlag(devId, CI_ATS_SW_BYPASS_NOCANCEL_NO);		/*出清发送记录*/
						}

						/*检查驱采是否一致，不一致报混线*/
						dbColleRelayId = GetSwitchDbRelayId(devId);
						ProcessCoupleRelayHunXianState(dbRelayId, dbColleRelayId);

						fbColleRelayId = GetSwitchFbRelayId(devId);
						ProcessCoupleRelayHunXianState(fbRelayId, fbColleRelayId);

						dsColleRelayId = GetSwitchDsRelayId(devId);
						ProcessCoupleRelayHunXianState(dsRelayId, dsColleRelayId);
					}
				}
			}
			else
			{
				/*不做处理*/
			}
		}
	}
}

/*
* 功能描述： 设置联络线道岔定反表继电器驱动状态
* 参数说明： const UINT16 devId 设备ID
*            const UINT16 dbRelayId 定表继电器ID
*            const UINT16 fbRelayId 反表继电器ID
* 返回值  ： 无
*
*/
void SetConnectSwitchPosRelayDrvSta(const UINT16 devId, const UINT16 dbRelayId, const UINT16 fbRelayId)
{
	UINT8 devState = 0u;  /*设备状态*/

	devState = GetSwitchCurPosition(devId);
	/*定反表ID大于0 */
	if ((0u < dbRelayId) && (0u < fbRelayId))
	{
		if (SWITCH_POSITION_DINGWEI == devState)
		{
			/*定表吸起、反表落下*/
			(void)SetRelayDriveState(dbRelayId, RELAY_DRIVE_STATE_UP);
			(void)SetRelayDriveState(fbRelayId, RELAY_DRIVE_STATE_DOWN);
		}
		else if (SWITCH_POSITION_FANWEI == devState)
		{
			/*定表落下、反表吸起*/
			(void)SetRelayDriveState(dbRelayId, RELAY_DRIVE_STATE_DOWN);
			(void)SetRelayDriveState(fbRelayId, RELAY_DRIVE_STATE_UP);
		}
		else
		{
			/*都驱落下*/
			(void)SetRelayDriveState(dbRelayId, RELAY_DRIVE_STATE_DOWN);
			(void)SetRelayDriveState(fbRelayId, RELAY_DRIVE_STATE_DOWN);
		}
	}
}

/*
* 功能描述： 检查是否混线状态
* 参数说明：
*
* 返回值  ： 1：不是混线状态
*            0：混线状态
*
*/
UINT8 CheckRelayHunXiandState(const UINT16 relayId)
{
	/*初始化*/
	UINT8 relayColleState = 0u;
	UINT8 relayDriveState = 0u;
	UINT8 retValue = CI_ERROR;
	UINT32 curCycNum = 0u;
	UINT8 checkRelayRes = 0u;
	UINT32 relayCycNum = 0u;

	curCycNum = Get2oo2CurCycleNum();

	if (0u < relayId)
	{
		retValue = CI_SUCCESS;
		/*获取继电器状态*/
		relayColleState = GetRelayCollState(relayId); /*采集状态*/
		relayDriveState = GetRelayDriveState(relayId); /*驱动状态*/

		/*驱动是落下*/
		if((RELAY_DRIVE_STATE_DOWN == relayDriveState) || (RELAY_DRIVE_STATE_NULL == relayDriveState))
		{
			/*吸起*/
			if (RELAY_STATE_UP == relayColleState)
			{
				relayCycNum = GetRelayHunXianStarCycNum(relayId);
				checkRelayRes = SystemOverTimeCheck(relayCycNum, RELAY_HUNXIAN_NUM);
				/*未计时*/
				if (CI_TIME_NO == checkRelayRes)
				{
					SetRelayHunXianStarCycNum(relayId, curCycNum);/*设置继电器有效周期*/
				}
				/*超时*/
				else if (CI_TIME_OUT == checkRelayRes)
				{
					retValue = CI_ERROR;
				}
				else
				{
					/*计时中，返回成功*/
				}
			}
			else
			{
				SetRelayHunXianStarCycNum(relayId, 0u);/*设置继电器有效周期*/
			}
		}
		/*驱动吸起不做混线检查*/
		else
		{
			SetRelayHunXianStarCycNum(relayId, 0u);/*设置继电器有效周期*/
		}
	}
	return(retValue);
}

/*
* 功能描述： 更新倒切装置状态
* 参数说明： void
* 返回值  ： 无
*/
void RvrsCutRlyToDvicSttPrc(void)
{
	UINT16 ii = 0u;		/*游标*/
	UINT16 wReverseCutSum = 0u;	/*倒切设备总数*/
	UINT16 wReverseCutId = 0u;	/*倒切设备ID*/
	UINT16 wReverseCutRelayId = 0u;/*倒切设备继电器ID*/
	UINT8 reVal = CI_ERROR;
	UINT8 chRelayState = 0u;
	UINT8 chReverseCutState = 0U;
	UINT8 chAllReverseCutState = 0U;
	UINT8 localCi = GetSystemParaLocalCiId();/*本机联锁*/
	UINT8 chBelongCiId = 0U;

	wReverseCutSum = GetReverseCutCurSum();

	for (ii = 0u; ii < wReverseCutSum; ii++)
	{
		wReverseCutId = GetReverseCutId(ii);
		if (CI_ERROR == wReverseCutId)
		{
			reVal = CI_ERROR;
		}
		else
		{

			wReverseCutRelayId = GetReverseCutRelayId(wReverseCutId);
			chBelongCiId = GetRelayBelongCiId(wReverseCutRelayId);/*esb所属联锁*/
			if (chBelongCiId == localCi)
			{
				/*继电器所属联锁为本联锁*/
				chRelayState = GetRelayCollState(wReverseCutRelayId);
				if (RELAY_STATE_DOWN == chRelayState)
				{
					SetReverseCutState(wReverseCutId, REVERSE_DEVICE_CUT_STATE_DOWN);
				}
				else if (RELAY_STATE_UP == chRelayState)
				{
					SetReverseCutState(wReverseCutId, REVERSE_DEVICE_CUT_STATE_UP);
				}
				else
				{
					SetReverseCutState(wReverseCutId, REVERSE_DEVICE_CUT_STATE_DOWN);
				}

			}
		}
	}

	for (ii = 0u; ii < wReverseCutSum; ii++)
	{
		wReverseCutId = GetReverseCutId(ii);
		if (CI_ERROR == wReverseCutId)
		{
			reVal = CI_ERROR;
		}
		else
		{
			chBelongCiId = GetReverseCutBelongCiId(wReverseCutId);/*esb所属联锁*/
			if (chBelongCiId == localCi)
			{
				/*继电器所属联锁为本联锁*/
				chReverseCutState = GetReverseCutState(wReverseCutId);
				if (REVERSE_DEVICE_CUT_STATE_DOWN == chReverseCutState)
				{
					chAllReverseCutState |= REVERSE_DEVICE_CUT_STATE_DOWN;
				}
				else if (REVERSE_DEVICE_CUT_STATE_UP == chReverseCutState)
				{
					chAllReverseCutState |= REVERSE_DEVICE_CUT_STATE_UP;
				}
				else
				{
					chAllReverseCutState |= REVERSE_DEVICE_CUT_STATE_DOWN;
				}

			}
		}
	}

	if (REVERSE_DEVICE_CUT_STATE_UP != chAllReverseCutState)
	{
		if (0U != chAllReverseCutState)
		{
			SetTiocSystemMode(REVERSE_MODE_SHADOW);
		}
		else
		{

		}
	}
	else
	{
		SetTiocSystemMode(REVERSE_MODE_MAIN);
	}

	ReverseCutReasonProcess();
}

/*
* 功能描述： 更新是否可倒切原因
* 参数说明： void
* 返回值  ： 无
*/
void ReverseCutReasonProcess(void)
{
	UINT8 deviceSum = 0u;/*通信设备总数*/
	UINT8* pDeviceIdBuf = NULL;/*通信设备ID数组*/
	UINT16 ii = 0U;
	UINT8 chCommState = 0U;
	UINT16 wTrainSum = 0U;
	UINT16 wTrainId = 0U;
	UINT8 chLocalCiId = 0U;
	UINT8 chCanntCutReason = 0U;
	UINT8 chTiocSystemMode = 0U;
	chLocalCiId = GetSystemParaLocalCiId();

	/*清除当前不可倒切原因*/
	SetTiocCanntCutReason(0U);
	chTiocSystemMode = GetTiocSystemMode();
	if (REVERSE_MODE_MAIN != chTiocSystemMode)
	{
		deviceSum = GetCiTransmitSpecifySysDevSum(CI_SYSTEM_TYPE_OC);     /*获取通信OC设备总数*/
		pDeviceIdBuf = GetCiTransmitSpecifySysDevBuf(CI_SYSTEM_TYPE_OC); /*获取通信OC设备ID数组*/

		if (pDeviceIdBuf != NULL)
		{
			if (TRANSMIT_OBJECT_DEVICE_SUM_MAX > deviceSum)
			{
				/*参数有效性判断*/
				for (ii = 0u; ii < deviceSum; ii++)
				{/*遍历与本CI通信的OC系统*/
				 /*更新与CI通信状态*/
					(void)UpdateCiTransmitState(chLocalCiId, CI_SYSTEM_TYPE_OC, pDeviceIdBuf[ii]);
					chCommState = GetCiTransmitState(CI_SYSTEM_TYPE_OC, pDeviceIdBuf[ii]);

					if (TRANSMIT_STATE_GOOD != chCommState)
					{
						SetTiocCanntCutReason(REVERSE_REASON_OC_COMM_ERR);
						break;
					}
				}
			}
		}
		else
		{
			SetTiocCanntCutReason(REVERSE_REASON_OC_COMM_ERR);
		}

		deviceSum = GetCiTransmitSpecifySysDevSum(CI_SYSTEM_TYPE_AXIS);     /*获取通信OC设备总数*/
		pDeviceIdBuf = GetCiTransmitSpecifySysDevBuf(CI_SYSTEM_TYPE_AXIS); /*获取通信OC设备ID数组*/

		if (pDeviceIdBuf != NULL)
		{
			if (TRANSMIT_OBJECT_DEVICE_SUM_MAX > deviceSum)
			{
				/*参数有效性判断*/
				for (ii = 0u; ii < deviceSum; ii++)
				{/*遍历与本CI通信的OC系统*/
				 /*更新与CI通信状态*/
					(void)UpdateCiTransmitState(chLocalCiId, CI_SYSTEM_TYPE_AXIS, pDeviceIdBuf[ii]);
					chCommState = GetCiTransmitState(CI_SYSTEM_TYPE_AXIS, pDeviceIdBuf[ii]);

					if (TRANSMIT_STATE_GOOD != chCommState)
					{
						SetTiocCanntCutReason(REVERSE_REASON_AXLE_COMM_ERR);
						break;
					}
				}
			}
		}
		else
		{
			/*存在没有计轴系统的情况，此处不做处理*/
		}

		wTrainSum = GetTrainSum();

		for (ii = 0U; ii < wTrainSum; ii++)
		{
			wTrainId = GetTrainId(ii);
			/** 获取列车通信状态*/
			chCommState = GetTrainTransitmitStat(wTrainId);

			/** 判断通信状态是否良好*/
			if ((TRAIN_COMM_STATE_GOOD == chCommState)
				|| (TRAIN_COMM_STATE_UNKNOWN == chCommState))
			{
				; /*不做处理*/
			}
			else
			{
				SetTiocCanntCutReason(REVERSE_REASON_IVOC_COMM_ERR);
			}
		}

		chCanntCutReason = GetTiocCanntCutReason();

		if (0U != chCanntCutReason)
		{
			SetTiocSystemCutState(REVERSE_CUT_STATE_EXCEPTION);
		}
		else
		{
			SetTiocSystemCutState(REVERSE_CUT_STATE_NORMAL);
		}
	}
	else
	{
		SetTiocSystemCutState(REVERSE_CUT_STATE_DEFAULT);
	}
}

/*
* 功能描述： TIOC影子模式设备输出处理
* 参数说明： void
* 返回值  ： void
*/
void TiocSysShadowDeviceOutputProc(void)
{
	UINT16 wSwitchCurSum = 0u;	 /*道岔总数目*/
	UINT16 wSignalCurSum = 0U;   /*信号机总数目*/
	UINT16 wPsdCurSum = 0U;		 /*屏蔽门总数目*/

	UINT8 chLocalCiId = 0u;         /*本地联锁ID*/

	UINT16 wDeviceId = 0u;	     /*道岔ID*/
	UINT8 chBelongCiId = 0u;        /*道岔所属联锁ID*/
	UINT16 ii = 0u;               /*循环索引*/

	chLocalCiId = GetSystemParaLocalCiId();


	wSwitchCurSum = GetSwitchCurSum();
	wSignalCurSum = GetSignalCurSum();
	wPsdCurSum = GetPsdSum();
	for (ii = 0u; ii < wSwitchCurSum; ii++)
	{
		wDeviceId = GetSwitchId(ii); 					 /*获取道岔ID*/

		if ((0u < wDeviceId) && (SWITCH_SUM_MAX > wDeviceId))
		{
			chBelongCiId = GetSwitchBelongCiId(wDeviceId); 	 /*获取道岔所属联锁ID*/
			if ((chBelongCiId == chLocalCiId) && (0u != chLocalCiId))
			{
				(void)SetSwitchExpDrvPosition(wDeviceId, SWITCH_DRIVE_POS_INVALID);
				(void)SetSwitchDrivePostion(wDeviceId, SWITCH_DRIVE_POS_INVALID);
				(void)SetSwitchDanCaoPosition(wDeviceId, SWITCH_DRIVE_POS_INVALID);
			}
			else
			{
				;
			}
		}
		else
		{
			;
		}
	}

	for (ii = 0u; ii < wSignalCurSum; ii++)
	{
		wDeviceId = GetSignalId(ii); 					 /*获取信号机ID*/

		if ((0u < wDeviceId) && (SIGNAL_SUM_MAX > wDeviceId))
		{
			chBelongCiId = GetSignalBelongCiId(wDeviceId); 	 /*获取信号机所属联锁ID*/
			if ((chBelongCiId == chLocalCiId) && (0u != chLocalCiId))
			{
				SetSignalCurDriveColor(wDeviceId, SIGNAL_DRIVECOLOUR_NULL);
			}
			else
			{
				;
			}
		}
		else
		{
			;
		}
	}

	for (ii = 0u; ii < wPsdCurSum; ii++)
	{
		wDeviceId = GetPsdId(ii); 					 /*获取屏蔽门ID*/

		if ((0u < wDeviceId) && (PSD_SUM_MAX > wDeviceId))
		{
			/*获取屏蔽门所属联锁ID*/
			chBelongCiId = GetPsdBelongCiId(wDeviceId);
			if ((chBelongCiId == chLocalCiId) && (0u != chLocalCiId))
			{
				SetPsdDriveState(wDeviceId, PSD_DRIVE_STATE_INVALID);
				SetStartDetectionState(wDeviceId, JXTC_START_DETECTION_NO);
				SetStopDetectionState(wDeviceId, JXTC_STOP_DETECTION_NO);
			}
			else
			{
				;
			}
		}
		else
		{
			;
		}
	}

}


/*
* 功能描述： 提前驱动道岔时岔区的物理区段占用落计轴
* 参数说明： UINT16 ACID 计轴区段ID
* 返回值  ： AXIS_SECTION_OCCUPY_YES 计轴占用
		   AXIS_SECTION_OCCUPY_NO 计轴空闲
		   0x00u  需要根据道岔拓扑关系落计轴
*/
static UINT8 ProcessACStatusSpecial(UINT16 ACID)
{
	UINT8 ret = AXIS_SECTION_OCCUPY_YES;
	UINT8 funRtn = UINT8_MAX;
	UINT8 cycle = 0u;
	UINT8 chLogSecCnt = 0u;
	UINT8 TrainLockCnt = 0u;
	UINT8 LogSecLockCnt = 0u;
	UINT8 sameAdjoinStatus = LOGICSECTION_OCCUPY_UT;
	UINT8 convertAdjoinStatus = LOGICSECTION_OCCUPY_UT;
	UINT16* pLogSecCntBuff = NULL;
	const EnvelopeStruct* pELMInfo = NULL;
	UINT8 envelopeCnt = CI_ERROR;
	UINT16 envelopeIDs[SECTION_REL_ENVELOPE_SUM_MAX] = {0u};

	chLogSecCnt = GetAxisSecLogSectionSum(ACID);
	pLogSecCntBuff = GetAxisSecLogSectionIdBuf(ACID);

	if ((0u == chLogSecCnt) || (NULL == pLogSecCntBuff))
	{
		/** 注：不要删除if判断条件 */
		ret = AXIS_SECTION_OCCUPY_YES;
	}
	else
	{
		/** 获取计轴区段包含的包络，如果存在UKT包络，需要等物理区段空闲后才可变空闲 */
		envelopeCnt = elm_GetEnvelopeIDsInAC(ACID,envelopeIDs);
		for (cycle = 0u; cycle < envelopeCnt; cycle++)
		{
			pELMInfo = elm_GetEnvelopeInfoPtr(envelopeIDs[cycle]);

			if ((NULL == pELMInfo) || (TYPE_UKT_ENVELOPE == pELMInfo->envelopeType))
			{
				break;
			}
			else
			{
				/** 继续遍历*/
			}
		}

		if (cycle != envelopeCnt)
		{
			/** 说明上周期存在UKT包络，处理成占用 */
			ret = AXIS_SECTION_OCCUPY_YES;
		}
		else
		{			
			for (cycle = 0u;cycle < chLogSecCnt; cycle++)
			{
				/** 获取逻辑区段被车锁闭的数量 */
				TrainLockCnt = GetLogSecTrainInfoSum(pLogSecCntBuff[cycle]);

				if (0U < TrainLockCnt)
				{
					LogSecLockCnt++;
				}
			}

			if ((0u != LogSecLockCnt) && (LogSecLockCnt != chLogSecCnt))
			{
				/** 计轴区段资源部分释放，如果有包络则设置占用，否则不设置占用 */
				if (0u == envelopeCnt)
				{
					/** 正向查询计轴相邻逻辑区段占用状态 */
					sameAdjoinStatus = GetACAdjoinLogSecStatus(EMAP_SAME_DIR,ACID);
					convertAdjoinStatus = GetACAdjoinLogSecStatus(EMAP_CONVER_DIR,ACID);

					if ((LOGICSECTION_OCCUPY_UT == sameAdjoinStatus) || (LOGICSECTION_OCCUPY_UT == convertAdjoinStatus))
					{
						ret = AXIS_SECTION_OCCUPY_YES;
					}
					else
					{
						/* 极端场景，岔区制造延迟解锁故障且车延迟释放资源故障，道岔持续定位。定位计轴因为无车包络无法落占用，反位因为无UT接近无法落占用
						   岔区占用无计轴占用防护，会设置岔区计轴都占用，定位因为好车通过进入ARB，反位因为无好车通过进入UT,后续因为反位计轴添加UKT包络导致定位无法落上占用 */
						ret = 0x00u;
					}					
				}
				else
				{
					ret = AXIS_SECTION_OCCUPY_YES;
				}
			}
			else
			{
				/** 计轴区段资源全未释放或者未分配 */
				if (0u != envelopeCnt)
				{
					ret = AXIS_SECTION_OCCUPY_YES;
				}
				else
				{
					/** 正向查询计轴相邻逻辑区段占用状态 */
					sameAdjoinStatus = GetACAdjoinLogSecStatus(EMAP_SAME_DIR,ACID);
					convertAdjoinStatus = GetACAdjoinLogSecStatus(EMAP_CONVER_DIR,ACID);

					if ((LOGICSECTION_OCCUPY_UT == sameAdjoinStatus) || (LOGICSECTION_OCCUPY_UT == convertAdjoinStatus))
					{
						ret = 0x00u;
					}
					else
					{
						/** 无坏车接近，判断岔区资源是否进行分配，未分配则根据道岔拓扑关系落占用，否则空闲*/
						funRtn = GetACRelSwLogSecLock(ACID);

						if (UINT8_MAX == funRtn)
						{
							ret = AXIS_SECTION_OCCUPY_YES;
						}
						else if (CI_SUCCESS == funRtn)
						{
							ret = AXIS_SECTION_OCCUPY_NO;
						}
						else
						{
							ret = 0x00u;
						}
					}
				}
			}
		}
	}
	return ret;
}


/*
* 功能描述： 处理物理区段上的占用落到计轴区段
* 参数说明： void
* 返回值  ： void
*/
void ProcessPhyOCcStateToAxisSection(void)
{
	UINT16 cycle = 0u;
	UINT16 acCnt = 0u;
	UINT16* pACBuff = NULL;
	UINT8 chSwitch = FUNC_SWITCH_OFF;
	UINT8 setFlag = FLAG_UNSET;
	UINT8 chFunRtn = CI_ERROR;
	UINT16 wPhyId = 0u;
	UINT8 chOccState = SECTION_OCCUPY_YES;
	AxisSwitchStruct* pSwitchInfo = NULL;
	UINT8 chSwitchNum = 0u;
	UINT8 chLogSecCnt = 0u;
	UINT8 chSpecialHandle = AXIS_SECTION_OCCUPY_YES;
	UINT8 chIndex = 0u;
	UINT8 chSwitchPos = 0u;
	UINT8 chHitTimes = 0u;
	UINT16 wACindex = 0U;

	/** 获取计轴信息*/
	acCnt = GetLocalCiAxisSectionIdBuf(&pACBuff);

	for (cycle = 0u; cycle < acCnt; cycle++)
	{
		/** 重置变量 */
		setFlag = FLAG_UNSET;
		chHitTimes = 0u;

		/** 判断无直轨功能开关是否打开 */
		chSwitch = GetCiFunctionSwitchConfig(FUNC_TOA_SWITCH);

		if (FUNC_SWITCH_ON == chSwitch)
		{
			chFunRtn = IsAcFree(pACBuff[cycle]);
			if (CI_ERROR == chFunRtn)
			{
				setFlag = FLAG_SET;
			}
		}
		else
		{
			/** 继续处理 */
		}

		if (FLAG_SET == setFlag)
		{
			SetAxisOccupyState(pACBuff[cycle], AXIS_SECTION_OCCUPY_YES);
		}
		else
		{
			/* 获取物理区段信息 */
			wPhyId = GetAxisSecRelativePhySecId(pACBuff[cycle]);
			chOccState = GetPhySecCurOccupyState(wPhyId);

			if (SECTION_OCCUPY_NO == chOccState)
			{
				/* 物理区段空闲，直接返回计轴区段空闲 */
				SetAxisOccupyState(pACBuff[cycle], AXIS_SECTION_OCCUPY_NO);
			}
			else
			{
				/* 获取计轴关联的道岔信息 */
				chSwitchNum = GetAxisSwitchSum(pACBuff[cycle]);
				pSwitchInfo = GetAxisSwitchIdStru(pACBuff[cycle]);

				if ((0u == chSwitchNum) || (AXIS_INCLUDE_SWITCH_SUM_MAX < chSwitchNum) || (NULL == pSwitchInfo))
				{
					/** 物理区段占用，计轴区段上道岔数量不合法，计轴区段占用 */
					/* 物理区段占用，且该计轴区段不包含道岔，计轴区段占用 */
					SetAxisOccupyState(pACBuff[cycle], AXIS_SECTION_OCCUPY_YES);
				}
				else
				{
					/** 获取计轴区段包含的逻辑区段，如果包含的逻辑区段为大于1，则为多段式 */
					chLogSecCnt = GetAxisSecLogSectionSum(pACBuff[cycle]);
					chSwitch = GetCiFunctionSwitchConfig(FUNC_ROUTE_DRV_SWITCH_EARLY);

					if ((chLogSecCnt > 1u) && (FUNC_SWITCH_ON == chSwitch))
					{
						/** 进路可提前驱动道岔，特殊处理 */
						chSpecialHandle = ProcessACStatusSpecial(pACBuff[cycle]);
					}
					else
					{
						chSpecialHandle = 0x00u;
					}

					if (0x00U == chSpecialHandle)
					{
						/** 需要根据道岔拓扑关系落计轴 */
						for (chIndex = 0u; chIndex < chSwitchNum; chIndex++)
						{
							chSwitchPos = GetSwitchCurPosition(pSwitchInfo[chIndex].SwitchId);
							if ((SWITCH_POSITION_DINGWEI != chSwitchPos) && (SWITCH_POSITION_FANWEI != chSwitchPos))
							{/* 物理区段占用，道岔四开，继续检查 */
								chHitTimes++;
							}
							else
							{
								if (chSwitchPos == pSwitchInfo[chIndex].SwitchPosition)
								{
									chHitTimes++;
								}
								else
								{
									;
								}
							}
						}
						if (chIndex < chSwitchNum)
						{
							SetAxisOccupyState(pACBuff[cycle], AXIS_SECTION_OCCUPY_YES);
						}
						else
						{
							if (chHitTimes == chSwitchNum)
							{
								/* 物理区段占用，无四开道岔，计轴区段所有道岔在期望位置占用 */
								SetAxisOccupyState(pACBuff[cycle], AXIS_SECTION_OCCUPY_YES);
							}
							else
							{
								SetAxisOccupyState(pACBuff[cycle], AXIS_SECTION_OCCUPY_NO);
							}
						}
					}
					else if (AXIS_SECTION_OCCUPY_NO == chSpecialHandle)
					{
						SetAxisOccupyState(pACBuff[cycle], AXIS_SECTION_OCCUPY_NO);
					}
					else
					{
						SetAxisOccupyState(pACBuff[cycle], AXIS_SECTION_OCCUPY_YES);
					}
				}
			}
		}
	}

	/* 检查所有占用物理区段是否均有占用计轴区段 */
	IsOccPhyHasOccAc();

	/*更新计轴区段冗余结束可判ARB标志置*/
	for (cycle = 0u; cycle < acCnt; cycle++)
	{
		wACindex = aam_PrepareACIndex(pACBuff[cycle]);
		/*计轴区段无占用 设置冗余结束可判ARB标志置为0x55*/
		chOccState = GetAxisOccupyState(pACBuff[cycle]);
		if (AXIS_SECTION_OCCUPY_NO == chOccState)
		{
			aam_SetAxisRedunCanArbFlag(wACindex, REDUN_OVER_ARB_YES);
		}
		else
		{
			; /*有占用时标志在计轴故障诊断处理中设置*/
		}
	}
}

/**
* @brief 判断所有占用物理区段是否均有占用计轴区段
* @param 无
* @return 无
*/
static void IsOccPhyHasOccAc(void)
{
	UINT16 wPhyNum = 0u;
	UINT8 chAcNum = 0u;
	UINT8 chAcIndex = 0u;
	UINT16 * pAcId = NULL;
	UINT16 wPhyId = 0u;
	UINT16 wPhyIndex = 0u;
	UINT8 chPhyOccState = SECTION_OCCUPY_YES;
	UINT8 chAcOccState = AXIS_SECTION_OCCUPY_YES;

	/* 获取物理区段数量 */
	wPhyNum = GetTotalPhySecCurNum();
	for (wPhyIndex = 0u; wPhyIndex < wPhyNum; wPhyIndex++)
	{
		wPhyId = GetPhySecId(wPhyIndex);
		chPhyOccState = GetPhySecCurOccupyState(wPhyId);

		if (SECTION_OCCUPY_NO != chPhyOccState)
		{
			/* 获取物理区段包含计轴区段 */
			chAcNum = GetPAxisSectionSum(wPhyId);
			pAcId = GetPAxisSectionIdBuf(wPhyId);

			if ((0u == chAcNum) || (NULL == pAcId))
			{
				/* 数据查询出错，不处理，初始化防护 */
			}
			else
			{
				/* 物理区段占用 */
				for (chAcIndex = 0u; chAcIndex < chAcNum; chAcIndex++)
				{
					chAcOccState = GetAxisOccupyState(pAcId[chAcIndex]);
					if (AXIS_SECTION_OCCUPY_YES == chAcOccState)
					{
						/* 计轴区段占用，跳出循环 */
						break;
					}
					else
					{
						; /* 计轴区段空闲继续遍历 */
					}
				}

				if (chAcIndex == chAcNum)
				{
					debug_infor_printf((const)"phy%d of ac lose occ.\n",wPhyId);
					for (chAcIndex = 0u; chAcIndex < chAcNum; chAcIndex++)
					{
						/* 占用物理区段无计轴区段占用，返回失败 */
						SetAxisOccupyState(pAcId[chAcIndex],AXIS_SECTION_OCCUPY_YES);
					}					
				}
				else
				{
					;
				}
			}
		}
		else
		{
			/** 空闲无需处理 */
		}
	}
}

/*
* 功能描述： 获取ESB当前需要设置的状态
* 参数说明：UINT16 esbId ESB ID
*
* 返回值  ： ESB_STATE_VALID_YES：设置状态为有效
*            ESB_STATE_VALID_NO：设置状态为无效
*			 CI_ERROR: 获取失败
* cgh-合并CID-2349-3：
*/
UINT8 GetEsbCurNeedSetState(UINT16 esbId)
{
	UINT16 esbRelayId = 0u;  /*esb继电器ID*/
	UINT16 ESSRelayId = 0u;  /*紧急停车开关继电器ID*/
	UINT16 esbRelayState = 0u; /*esb继电器采集状态*/
	UINT16 ESSRelayState = 0u; /*紧急停车开关继电器采集状态*/
	UINT8 resultVal = CI_ERROR;/*函数返回值*/
	UINT8 curEsbDriveState = 0u;  /*当前esb相关继电器驱动状态机*/
	UINT16 bufIndex = 0U;  /*数组下标*/
	UINT8 cFuncRet = 0U;

	bufIndex = GetEsbConfigBufIndex(esbId);  /*获取数组下标*/
	if (bufIndex < ESB_SUM_MAX)
	{		
		esbRelayId = GetEsbRelayId(esbId);
		esbRelayState = GetRelayCollState(esbRelayId);
		ESSRelayId = GetESSRelayId(esbId);
		/*当紧急停车开关继电器存在时esb的状态需根据esb采集继电器与紧急停车开关采集继电器状态共同决定*/
		if ((0u < ESSRelayId) && (ESSRelayId < UINT16_MAX))
		{
			ESSRelayState = GetRelayCollState(ESSRelayId);
			if ((RELAY_STATE_DOWN == esbRelayState) || (RELAY_STATE_DOWN == ESSRelayState))
			{
				resultVal = ESB_STATE_VALID_YES;  /*当esb采集继电器或紧急停车开关采集继电器有一个落下则esb有效*/
			}
			else if ((RELAY_STATE_UP == esbRelayState) && (RELAY_STATE_UP == ESSRelayState))
			{
				curEsbDriveState = GetEsbRelateRelayDriveProState(esbId);   /*获取esb相关继电器当前驱动状态机*/
				if ((ESB_PEPDOWN_ESSUP_TWO_STATE == curEsbDriveState) || (ESB_FAULT_SIX_STATE == curEsbDriveState))
				{/*当由状态机2直接恢复PEP，则esb仍然有效,或者一直在状态机6但是还采到ESS和PEP都吸起则认为esb还是有效的*/
					resultVal = ESB_STATE_VALID_YES;
				}
				else
				{
					resultVal = ESB_STATE_VALID_NO;   /*当esb采集继电器和紧急停车开关采集继电器都吸起且当前状态机不是状态机2则esb无效*/
				}
			}
			else
			{
				resultVal = CI_ERROR;             /*不存在的值返回失败不设置esb状态*/
			}
		}
		else
		{
			/*紧急停车开关继电器不存在时esb的状态只由esb采集继电器状态决定*/
			cFuncRet = GetEsbCollTolerateRet(esbId);  /*获取ESB采集容忍结果*/
			if (CI_SUCCESS == cFuncRet)
			{
				resultVal = ESB_STATE_VALID_NO;  /*esb采集继电器落下未超过容忍时间，返回紧急无效*/
			}
			else
			{
				resultVal = ESB_STATE_VALID_YES;  /*当esb采集继电器落下且超过容忍时间后，返回紧急有效*/
			}
		}
	}
	else
	{
		resultVal = CI_ERROR;                   /*esb ID不合法返回失败不设置esb状态*/
	}

	return resultVal;
}

/*
* 功能描述： OC ESS和PEP操作下的闪灯、稳灯和蜂鸣器继电器驱动输出处理
* 参数说明： void
* 返回值  ： void
* cgh-合并CID-2349-3、cgh-合并CID-3037-1：
*/
void EsbRelateDelayDriveOutputProc(void)
{
	/*变量初始化*/
	UINT16 esbCurSum = 0u;
	UINT8  localCiId = 0u;          /*本地联锁ID*/
	UINT16 esbId = 0u;              /*esb ID*/
	UINT8  devBlongCiId = 0u;       /*设备所属联锁ID*/
	UINT16 esbBuzzRelayId = 0u;     /*esb蜂鸣继电器ID*/
	UINT16 esbCutoffBuzzRelayId = 0U;     /*esb切除蜂鸣继电器ID*/
	UINT8 esbCutState = 0u;
	UINT8 esbState = 0u;
	UINT8 esbBuzzDriveState = 0u;   /*esb蜂鸣继电器驱动状态*/
	UINT8 esbCutoffBuzzDriveState = 0u;   /*esb切除蜂鸣继电器驱动状态*/
	UINT16 i = 0u;                  /*循环索引*/
	UINT16 ESSRelayId = 0u;         /*ESS ID*/

	UINT8 funcswitchZfsBtn = 0U;    /*自复式按钮开关*/

	esbCurSum = GetEsbSum();        /*获取esb数量*/
	localCiId = GetSystemParaLocalCiId();   /*获取本地联锁ID*/

	funcswitchZfsBtn = GetCiFunctionSwitchConfig(FUNC_ZIFUSHI_BUTTON);

	if (0U < esbCurSum)
	{
		/*获取ESB状态信息*/
		for (i = 0u; i < esbCurSum; i++)
		{
			esbId = GetEsbId(i);
			devBlongCiId = GetEsbBelongCiId(esbId); /*获取设备所属联锁ID*/
			/*ESB是本联锁*/
			if (localCiId == devBlongCiId)
			{
				if (FUNC_SWITCH_ON == funcswitchZfsBtn)
				{
					/***** 自复式/宁象市域铁路ESB蜂鸣继电器驱动处理 *****/
					/*1.设置自复式ESB蜂鸣继电器驱动状态*/
					esbBuzzRelayId = GetEsbBuzzRelayId(esbId);
					if ((0u < esbBuzzRelayId) && (UINT16_MAX > esbBuzzRelayId))
					{
						esbState = GetEsbState(esbId);
						if (ESB_STATE_VALID_YES == esbState)
						{
							/*驱动蜂鸣器吸起*/
							(void)SetRelayDriveState(esbBuzzRelayId, RELAY_DRIVE_STATE_UP);
						}
						else
						{
							esbBuzzDriveState = GetRelayDriveState(esbBuzzRelayId);
							if (RELAY_DRIVE_STATE_NULL == esbBuzzDriveState)
							{
								/*未驱动过，驱动蜂鸣器落下*/
								(void)SetRelayDriveState(esbBuzzRelayId, RELAY_DRIVE_STATE_DOWN);
							}
						}
					}

					/*2.设置自复式ESB切除蜂鸣继电器驱动状态*/
					esbCutoffBuzzRelayId = GetEsbCutoffBuzzRelayId(esbId);
					if ((0U < esbCutoffBuzzRelayId) && (UINT16_MAX > esbCutoffBuzzRelayId))
					{
						esbState = GetEsbState(esbId);
						if (ESB_STATE_VALID_YES == esbState)
						{
							/*驱动切除蜂鸣器落下*/
							(void)SetRelayDriveState(esbCutoffBuzzRelayId, RELAY_DRIVE_STATE_DOWN);
						}
						else
						{
							esbCutoffBuzzDriveState = GetRelayDriveState(esbCutoffBuzzRelayId);
							if (RELAY_DRIVE_STATE_NULL == esbCutoffBuzzDriveState)
							{
								/*未驱动过，驱动切除蜂鸣器吸起*/
								(void)SetRelayDriveState(esbCutoffBuzzRelayId, RELAY_DRIVE_STATE_UP);
							}
						}
					}
				}
				else   /*非自复式ESB或宁象ESB蜂鸣继电器驱动处理*/
				{
					/*获取旁路按钮状态、ESB状态*/
					esbCutState = GetEsbCutState(esbId);
					esbState = GetEsbState(esbId);
					esbBuzzRelayId = GetEsbBuzzRelayId(esbId); /*根据esb ID获取esb蜂鸣器ID*/
					ESSRelayId = GetESSRelayId(esbId);  /*根据esb ID获取ESS继电器ID*/
					/*ESS继电器存在时按照状态机流转来处理相关继电器的驱动状态*/
					if ((0U < ESSRelayId) && (ESSRelayId < UINT16_MAX))
					{
						EsbRelateDelayDriveStateManage(esbId);
					}
					else
					{
						/*ESS继电器不存在时按照esb的状态来处理蜂鸣器的驱动状态*/
						if (0u < esbBuzzRelayId)
						{
							/*蜂鸣器驱动状态*/
							esbBuzzDriveState = GetRelayDriveState(esbBuzzRelayId);
							/*紧急未旁路、且紧急按下*/
							if ((ESB_CUT_NO == esbCutState) && (ESB_STATE_VALID_YES == esbState))
							{
								/*驱动蜂鸣器吸起*/
								(void)SetRelayDriveState(esbBuzzRelayId, RELAY_DRIVE_STATE_UP);
							}
							else
							{
								/*没有驱动*/
								if (RELAY_DRIVE_STATE_NULL == esbBuzzDriveState)
								{
									/*驱动蜂鸣器落下*/
									(void)SetRelayDriveState(esbBuzzRelayId, RELAY_DRIVE_STATE_DOWN);
								}
							}
						}

						/*设置非自复式ESB切除蜂鸣继电器驱动状态——太原1号线项目需求*/
						esbCutoffBuzzRelayId = GetEsbCutoffBuzzRelayId(esbId);
						if ((0U < esbCutoffBuzzRelayId) && (UINT16_MAX > esbCutoffBuzzRelayId))
						{							
							/*紧急未旁路*/
							if ((ESB_CUT_NO == esbCutState) && (ESB_STATE_VALID_YES == esbState))
							{
								/*驱动切除蜂鸣器落下*/
								(void)SetRelayDriveState(esbCutoffBuzzRelayId, RELAY_DRIVE_STATE_DOWN);
							}
							else
							{
								esbCutoffBuzzDriveState = GetRelayDriveState(esbCutoffBuzzRelayId);
								if (RELAY_DRIVE_STATE_NULL == esbCutoffBuzzDriveState)
								{
									/*未驱动过，驱动切除蜂鸣器吸起*/
									(void)SetRelayDriveState(esbCutoffBuzzRelayId, RELAY_DRIVE_STATE_UP);
								}
							}
						}
						else
						{
							/*未配置蜂鸣器切除报警继电器，不处理*/
						}
					}
				}
			}
		}
	}
}


/*
* 功能描述： OC ESS和PEP操作下的闪灯、稳灯和蜂鸣器继电器驱动输出状态机管理函数
* 参数说明： UINT16 esbId ESB ID
* 返回值  ： void
* cgh-合并CID-2349-3：
*/
void EsbRelateDelayDriveStateManage(UINT16 esbId)
{
	/*变量初始化*/
	UINT16 esbRelayId = 0u;             /*esb采集继电器 ID*/
	UINT8 esbCutState = 0u;             /*esb旁路状态*/
	UINT8 esbRelayState = 0u;           /*esb采集继电器状态*/
	UINT16 ESSRelayId = 0u;             /*ESS ID*/
	UINT8 ESSRelayState = 0u;           /*ESS 继电器状态*/
	UINT8 esbRelateDelayDriveState = 0u; /*esb相关继电器驱动状态机*/
	UINT16 esbSteadyIndicatRelayId = 0u; /*esb稳灯继电器ID*/
	UINT16 esbFlashIndicatRelayId = 0u;  /*esb闪灯继电器ID*/
	UINT16 esbBuzzRelayId = 0u;          /*esb蜂鸣器继电器ID*/
	UINT16 bufIndex = 0u;  /*数组下标*/
	UINT8 esbBuzzDriveState = 0u;        /*esb蜂鸣器是否驱动过*/

	bufIndex = GetEsbConfigBufIndex(esbId);  /*获取数组下标*/

	if (bufIndex < ESB_SUM_MAX)
	{
		esbRelayId = GetEsbRelayId(esbId);   /*获取esb采集继电器ID*/
		esbRelayState = GetRelayCollState(esbRelayId); /*获取esb继电器采集状态*/
		esbCutState = GetEsbCutState(esbId);  /*获取esb旁路状态*/
		ESSRelayId = GetESSRelayId(esbId);    /*获取ESS继电器ID*/
		ESSRelayState = GetRelayCollState(ESSRelayId); /*获取ESS继电器采集状态*/
		esbSteadyIndicatRelayId = GetESSSteadyIndicatRelayId(esbId); /*获取ESS稳灯继电器ID*/
		esbFlashIndicatRelayId = GetESSFlashIndicatRelayId(esbId);   /*获取ESS闪灯继电器ID*/
		esbBuzzRelayId = GetEsbBuzzRelayId(esbId);     /*获取esb蜂鸣器ID*/
		esbRelateDelayDriveState = GetEsbRelateRelayDriveProState(esbId); /*获取esb相关继电器驱动状态机*/
		esbBuzzDriveState = GetRelayDriveState(esbBuzzRelayId);

		switch (esbRelateDelayDriveState)
		{
		case ESB_PEPUP_ESSUP_INITION_STA:
			/*初始状态，稳灯、闪灯和蜂鸣器都不驱动*/
			(void)SetRelayDriveState(esbSteadyIndicatRelayId, RELAY_DRIVE_STATE_DOWN);
			(void)SetRelayDriveState(esbFlashIndicatRelayId, RELAY_DRIVE_STATE_DOWN);
			if (RELAY_DRIVE_STATE_NULL == esbBuzzDriveState)
			{
				/*由于一个站共用一个ESB蜂鸣器，所以只有当其他站台侧没有驱动蜂鸣器吸起的情况下才可以驱落下*/
				(void)SetRelayDriveState(esbBuzzRelayId, RELAY_DRIVE_STATE_DOWN);
			}
			if ((RELAY_STATE_DOWN == esbRelayState) && (RELAY_STATE_UP == ESSRelayState))
			{
				/*PEP按下后，状态流转到状态机2*/
				SetEsbRelateRelayDriveProState(esbId, ESB_PEPDOWN_ESSUP_TWO_STATE);
			}
			else if ((RELAY_STATE_UP == esbRelayState) && (RELAY_STATE_DOWN == ESSRelayState))
			{
				/*ESS按下后，状态流转到状态机5*/
				SetEsbRelateRelayDriveProState(esbId, ESB_TWOPEPUP_ESSDOWN_FIVE_STATE);
			}
			else if ((RELAY_STATE_DOWN == esbRelayState) && (RELAY_STATE_DOWN == ESSRelayState))
			{
				/*当联锁启动还未与OC建立通信时，或者与OC通信中断后，跳转到状态机3*/
				SetEsbRelateRelayDriveProState(esbId, ESB_PEPDOWN_ESSDOWN_THREE_STATE);
			}
			else
			{
				/*在初始状态下按下PEP或者ESS在停位进行状态流转其他情况不做处理*/
			}
			break;
		case ESB_PEPDOWN_ESSUP_TWO_STATE:
			if (ESB_CUT_NO == esbCutState)
			{
				/*状态机2时，蜂鸣器报警，指示灯闪灯*/
				(void)SetRelayDriveState(esbSteadyIndicatRelayId, RELAY_DRIVE_STATE_DOWN);
				(void)SetRelayDriveState(esbFlashIndicatRelayId, RELAY_DRIVE_STATE_UP);
				(void)SetRelayDriveState(esbBuzzRelayId, RELAY_DRIVE_STATE_UP);
			}
			else
			{
				/*旁路之后不再驱动任何报警继电器*/
				(void)SetRelayDriveState(esbSteadyIndicatRelayId, RELAY_DRIVE_STATE_DOWN);
				(void)SetRelayDriveState(esbFlashIndicatRelayId, RELAY_DRIVE_STATE_DOWN);
				if (RELAY_DRIVE_STATE_NULL == esbBuzzDriveState)
				{
					(void)SetRelayDriveState(esbBuzzRelayId, RELAY_DRIVE_STATE_DOWN);
				}
			}
			if ((RELAY_STATE_DOWN == esbRelayState) && (RELAY_STATE_DOWN == ESSRelayState))
			{
				/*此时在使ESS在停位，则状态流转道状态机3*/
				SetEsbRelateRelayDriveProState(esbId, ESB_PEPDOWN_ESSDOWN_THREE_STATE);
			}
			else if ((RELAY_STATE_UP == esbRelayState) && (RELAY_STATE_UP == ESSRelayState))
			{
				/*此时直接复位PEP，是非正常操作，流程流转到状态机6*/
				SetEsbRelateRelayDriveProState(esbId, ESB_FAULT_SIX_STATE);
			}
			else
			{
				/*在状态机2时只能是以上两种流转情况其他情况不做处理*/
			}
			break;
		case ESB_PEPDOWN_ESSDOWN_THREE_STATE:
			if (ESB_CUT_NO == esbCutState)
			{
				/*在状态3时，蜂鸣器不报警，指示灯稳灯*/
				(void)SetRelayDriveState(esbSteadyIndicatRelayId, RELAY_DRIVE_STATE_UP);
				(void)SetRelayDriveState(esbFlashIndicatRelayId, RELAY_DRIVE_STATE_DOWN);
				if (RELAY_DRIVE_STATE_NULL == esbBuzzDriveState)
				{
					/*由于一个站共用一个ESB蜂鸣器，所以只有当其他站台侧没有驱动蜂鸣器吸起的情况下才可以驱落下*/
					(void)SetRelayDriveState(esbBuzzRelayId, RELAY_DRIVE_STATE_DOWN);
				}
			}
			else
			{
				/*旁路之后不再驱动任何报警继电器*/
				(void)SetRelayDriveState(esbSteadyIndicatRelayId, RELAY_DRIVE_STATE_DOWN);
				(void)SetRelayDriveState(esbFlashIndicatRelayId, RELAY_DRIVE_STATE_DOWN);
				if (RELAY_DRIVE_STATE_NULL == esbBuzzDriveState)
				{
					(void)SetRelayDriveState(esbBuzzRelayId, RELAY_DRIVE_STATE_DOWN);
				}
			}
			if ((RELAY_STATE_DOWN == esbRelayState) && (RELAY_STATE_UP == ESSRelayState))
			{
				/*此时使ESS在去位，则回到状态机2*/
				SetEsbRelateRelayDriveProState(esbId, ESB_PEPDOWN_ESSUP_TWO_STATE);
			}
			else if ((RELAY_STATE_UP == esbRelayState) && (RELAY_STATE_DOWN == ESSRelayState))
			{
				/*此时使PEP恢复，则回到状态机4*/
				SetEsbRelateRelayDriveProState(esbId, ESB_ONEPEPUP_ESSDOWN_FOUR_STATE);
			}
			else if ((RELAY_STATE_UP == esbRelayState) && (RELAY_STATE_UP == ESSRelayState))
			{
				/*ESS和PEP都落下又同时吸起，则转会初始状态*/
				SetEsbRelateRelayDriveProState(esbId, ESB_PEPUP_ESSUP_INITION_STA);
			}
			else
			{
				/*在状态机3时只能是以上两种流转情况其他情况不做处理*/
			}
			break;
		case ESB_ONEPEPUP_ESSDOWN_FOUR_STATE:
			if (ESB_CUT_NO == esbCutState)
			{
				/*当PEP先按下之后操作ESS到停位，再恢复PEP，这个时候蜂鸣器报警，指示灯闪烁为状态机4*/
				(void)SetRelayDriveState(esbSteadyIndicatRelayId, RELAY_DRIVE_STATE_DOWN);
				(void)SetRelayDriveState(esbFlashIndicatRelayId, RELAY_DRIVE_STATE_UP);
				(void)SetRelayDriveState(esbBuzzRelayId, RELAY_DRIVE_STATE_UP);
			}
			else
			{
				/*旁路之后不再驱动任何报警继电器*/
				(void)SetRelayDriveState(esbSteadyIndicatRelayId, RELAY_DRIVE_STATE_DOWN);
				(void)SetRelayDriveState(esbFlashIndicatRelayId, RELAY_DRIVE_STATE_DOWN);
				if (RELAY_DRIVE_STATE_NULL == esbBuzzDriveState)
				{
					(void)SetRelayDriveState(esbBuzzRelayId, RELAY_DRIVE_STATE_DOWN);
				}
			}
			if ((RELAY_STATE_UP == esbRelayState) && (RELAY_STATE_UP == ESSRelayState))
			{
				/*此时再使ESS在去位，则恢复到初始状态*/
				SetEsbRelateRelayDriveProState(esbId, ESB_PEPUP_ESSUP_INITION_STA);
			}
			else if ((RELAY_STATE_DOWN == esbRelayState) && (RELAY_STATE_DOWN == ESSRelayState))
			{
				/*此时再使PEP落下，则又转到状态机3*/
				SetEsbRelateRelayDriveProState(esbId, ESB_PEPDOWN_ESSDOWN_THREE_STATE);
			}
			else
			{
				/*在状态机4时只能是以上两种流转情况其他情况不做处理*/
			}
			break;
		case ESB_TWOPEPUP_ESSDOWN_FIVE_STATE:
			if (ESB_CUT_NO == esbCutState)
			{
				/*先使ESS在停位，PEP吸起时蜂鸣器不报警，指示灯稳灯为状态机5，这个时候与状态机4的PEP和ESS继电器状态一致但是报警不一致
				可以直接使ESS在去位恢复到初始状态*/
				(void)SetRelayDriveState(esbSteadyIndicatRelayId, RELAY_DRIVE_STATE_UP);
				(void)SetRelayDriveState(esbFlashIndicatRelayId, RELAY_DRIVE_STATE_DOWN);
				if (RELAY_DRIVE_STATE_NULL == esbBuzzDriveState)
				{
					/*由于一个站共用一个ESB蜂鸣器，所以只有当其他站台侧没有驱动蜂鸣器吸起的情况下才可以驱落下*/
					(void)SetRelayDriveState(esbBuzzRelayId, RELAY_DRIVE_STATE_DOWN);
				}
			}
			else
			{
				/*旁路之后不再驱动任何报警继电器*/
				(void)SetRelayDriveState(esbSteadyIndicatRelayId, RELAY_DRIVE_STATE_DOWN);
				(void)SetRelayDriveState(esbFlashIndicatRelayId, RELAY_DRIVE_STATE_DOWN);
				if (RELAY_DRIVE_STATE_NULL == esbBuzzDriveState)
				{
					(void)SetRelayDriveState(esbBuzzRelayId, RELAY_DRIVE_STATE_DOWN);
				}
			}
			if ((RELAY_STATE_UP == esbRelayState) && (RELAY_STATE_UP == ESSRelayState))
			{
				/*直接操作ESS位去位，恢复到初始状态*/
				SetEsbRelateRelayDriveProState(esbId, ESB_PEPUP_ESSUP_INITION_STA);
			}
			else if ((RELAY_STATE_DOWN == esbRelayState) && (RELAY_STATE_DOWN == ESSRelayState))
			{
				/*再操作PEP使之落下，则流转至状态机3*/
				SetEsbRelateRelayDriveProState(esbId, ESB_PEPDOWN_ESSDOWN_THREE_STATE);
			}
			else
			{
				/*在状态机5时只能是以上两种流转情况其他情况不做处理*/
			}
			break;
		case ESB_FAULT_SIX_STATE:
			if (ESB_CUT_NO == esbCutState)
			{
				/*只有在按下PEP后直接恢复PEP才会流转到这个状态机，此时虽然ESS和PEP都是吸起的，但是ESB有效
				且需要蜂鸣器报警和指示灯闪灯*/
				(void)SetRelayDriveState(esbSteadyIndicatRelayId, RELAY_DRIVE_STATE_DOWN);
				(void)SetRelayDriveState(esbFlashIndicatRelayId, RELAY_DRIVE_STATE_UP);
				(void)SetRelayDriveState(esbBuzzRelayId, RELAY_DRIVE_STATE_UP);
			}
			else
			{
				/*旁路之后不再驱动任何报警继电器*/
				(void)SetRelayDriveState(esbSteadyIndicatRelayId, RELAY_DRIVE_STATE_DOWN);
				(void)SetRelayDriveState(esbFlashIndicatRelayId, RELAY_DRIVE_STATE_DOWN);
				if (RELAY_DRIVE_STATE_NULL == esbBuzzDriveState)
				{
					(void)SetRelayDriveState(esbBuzzRelayId, RELAY_DRIVE_STATE_DOWN);
				}
			}
			if ((RELAY_STATE_DOWN == esbRelayState) && (RELAY_STATE_UP == ESSRelayState))
			{
				/*再按下PEP，回到状态机2按正常流程进行操作，流转到状态机2*/
				SetEsbRelateRelayDriveProState(esbId, ESB_PEPDOWN_ESSUP_TWO_STATE);
			}
			else if ((RELAY_STATE_UP == esbRelayState) && (RELAY_STATE_DOWN == ESSRelayState))
			{
				/*再按下ESS，则认为是先ESS按下的，按照此操作流程进行操作，即流转到状态机4*/
				SetEsbRelateRelayDriveProState(esbId, ESB_ONEPEPUP_ESSDOWN_FOUR_STATE);
			}
			else
			{
				/*在状态机6时只能是以上两种流转情况其他情况不做处理*/
			}
			break;
		default:
			/*其他不存在的状态机不做处理*/
			break;
		}
	}
}

/*
* 功能描述： 检查是否驱动超时
* 参数说明： const UINT16 relayId 继电器ID
*
* 返回值  ： 1：不是驱动超时状态
*            0：驱动超时
* cgh-合并CID-2349-4：
*/
UINT8 CheckRelayDriveOutTimeState(const UINT16 relayId)
{
	/*初始化*/
	UINT8 relayColleState = 0u;
	UINT8 relayDriveState = 0u;
	UINT8 retValue = CI_ERROR;
	UINT32 curCycNum = 0u;
	UINT8 checkRelayRes = 0u;
	UINT32 relayCycNum = 0u;

	curCycNum = Get2oo2CurCycleNum();


	retValue = CI_SUCCESS;
	/*获取继电器状态*/
	relayColleState = GetRelayCollState(relayId); /*采集状态*/
	relayDriveState = GetRelayDriveState(relayId); /*驱动状态*/

	/*驱动是吸起*/
	if (RELAY_DRIVE_STATE_UP == relayDriveState)
	{
		/*采集落下*/
		if (RELAY_STATE_DOWN == relayColleState)
		{
			relayCycNum = GetRelayDriveStartCycNum(relayId);
			checkRelayRes = SystemOverTimeCheck(relayCycNum, RELAY_DRIVE_MAX_NUM);
			/*未计时*/
			if (CI_TIME_NO == checkRelayRes)
			{
				SetRelayDriveStartCycNum(relayId, curCycNum);/*设置继电器有效周期*/
			}
			/*超时*/
			else if (CI_TIME_OUT == checkRelayRes)
			{
				retValue = CI_ERROR;
			}
			else
			{
				/*计时中，返回成功*/
			}
		}
		else
		{
			SetRelayDriveStartCycNum(relayId, 0u);/*设置继电器有效周期*/
		}
	}
	else if ((RELAY_DRIVE_STATE_DOWN == relayDriveState) || (RELAY_DRIVE_STATE_NULL == relayDriveState))
	{
		/*采集吸起*/
		if (RELAY_STATE_UP == relayColleState)
		{
			relayCycNum = GetRelayDriveStartCycNum(relayId);
			checkRelayRes = SystemOverTimeCheck(relayCycNum, RELAY_DRIVE_MAX_NUM);
			/*未计时*/
			if (CI_TIME_NO == checkRelayRes)
			{
				SetRelayDriveStartCycNum(relayId, curCycNum);/*设置继电器有效周期*/
			}
			/*超时*/
			else if (CI_TIME_OUT == checkRelayRes)
			{
				retValue = CI_ERROR;
			}
			else
			{
				/*计时中，返回成功*/
			}
		}
		else
		{
			SetRelayDriveStartCycNum(relayId, 0u);/*设置继电器有效周期*/
		}
	}
	else
	{
		SetRelayDriveStartCycNum(relayId, 0u);/*设置继电器有效周期*/
	}

	return retValue;
}


/*
* 功能描述： 检查是否驱动超时
* 参数说明： const UINT16 psdId 屏蔽门ID
*            const UINT8 psdDriveState psd驱动状态
* 返回值  ： 0xff：不是驱动超时状态
*            0x55 驱动开门未开门
*            0xaa 驱动关门未关门
* cgh-合并CID-2349-4：
*/
UINT8 CheckPsdDriveOutTimeState(const UINT16 psdId)
{
	/*初始化*/
	UINT8 retValue = UINT8_MAX;
	UINT32 curCycNum = 0u;
	UINT8 psdState = 0u;
	UINT32 driveStartCycNum = 0u;
	UINT8 OverTimeCheck = 0u;
	UINT8 psdDriveState = 0u;
	UINT32 psdDrivOpenMaxCount = 0u;
	UINT32 psdDrivCloseMaxCount = 0u;

	curCycNum = Get2oo2CurCycleNum();
	if (0u < psdId)
	{
		psdState = GetPsdState(psdId);
		psdDriveState = GetPsdDriveState(psdId);
		/*根据当前驱动状态，设置驱动开始时间*/
		if (PSD_DRIVE_STATE_OPEN == psdDriveState)
		{/*驱动开门*/
			SetPsdDriveCloseStartCycNum(psdId, 0u);/*清0开始周期*/
			if (PSD_STATE_OPEN != psdState)
			{
				driveStartCycNum = GetPsdDriveOpenStartCycNum(psdId);
				psdDrivOpenMaxCount = GetPsdDrivOpenMaxCount();
				OverTimeCheck = SystemOverTimeCheck(driveStartCycNum, psdDrivOpenMaxCount);

				/*未计时*/
				if (CI_TIME_NO == OverTimeCheck)
				{
					SetPsdDriveOpenStartCycNum(psdId, curCycNum);/*设置继电器有效周期*/
				}
			}
			else
			{
				SetPsdDriveOpenStartCycNum(psdId, 0u);/*清0开始周期*/
			}
		}
		else if (PSD_DRIVE_STATE_CLOSE == psdDriveState)
		{/*驱动关门*/
			SetPsdDriveOpenStartCycNum(psdId, 0u);/*清0开始周期*/
			if (PSD_STATE_CLOSE != psdState)
			{
				driveStartCycNum = GetPsdDriveCloseStartCycNum(psdId);
				psdDrivCloseMaxCount = GetPsdDrivCloseMaxCount();
				OverTimeCheck = SystemOverTimeCheck(driveStartCycNum, psdDrivCloseMaxCount);

				/*未计时*/
				if (CI_TIME_NO == OverTimeCheck)
				{
					SetPsdDriveCloseStartCycNum(psdId, curCycNum);/*清0开始周期*/
				}
			}
			else
			{
				SetPsdDriveCloseStartCycNum(psdId, 0u);/*清0开始周期*/
			}
		}
		else
		{/*非驱动状态，清空两种驱动周期*/
			SetPsdDriveOpenStartCycNum(psdId, 0u);/*清0驱动开门开始周期*/
			SetPsdDriveCloseStartCycNum(psdId, 0u);/*清0驱动关门开始周期*/
		}
		/*计算是否超时*/
		driveStartCycNum = GetPsdDriveOpenStartCycNum(psdId);
		if (0u < driveStartCycNum)
		{/*有驱动过*/
			psdDrivOpenMaxCount = GetPsdDrivOpenMaxCount();
			OverTimeCheck = SystemOverTimeCheck(driveStartCycNum, psdDrivOpenMaxCount);

			if (CI_TIME_OUT == OverTimeCheck)
			{
				retValue = PSD_OPEN_OUT_TIME;/*返回开门超时*/
				SetPsdDriveOpenStartCycNum(psdId, 0u);/*清0开始周期，仅报警一次*/
			}
			else
			{
				/*计时中，返回成功*/
			}
		}
		else
		{
			driveStartCycNum = GetPsdDriveCloseStartCycNum(psdId);
			if (0u < driveStartCycNum)
			{
				/*有驱动过*/
				psdDrivCloseMaxCount = GetPsdDrivCloseMaxCount();
				OverTimeCheck = SystemOverTimeCheck(driveStartCycNum, psdDrivCloseMaxCount);

				/*超时*/
				if (CI_TIME_OUT == OverTimeCheck)
				{
					retValue = PSD_CLOSE_OUT_TIME;/*返回关闭超时*/
					SetPsdDriveCloseStartCycNum(psdId, 0u);/*清0开始周期，仅报警一次*/
				}
				else
				{
					/*计时中，返回成功*/
				}

			}
		}
	}
	return(retValue);
}

/*
* 功能描述：获取继电器是否驱动采集不一致
* 参数说明： const UINT16 relayId, 继电器ID
			 const UINT8 foreNodeColl 前采状态
			 const UINT8 backNodeColl 后采状态
* 返回值  ： 0: 驱动采集不一致
*			>0: 一致
*cgh-合并CID-2349-4：
*/
UINT8 CheckRelayDriAndCollDiffSeat(const UINT16 relayId, const UINT8 foreNodeColl, const UINT8 backNodeColl)
{

	UINT8 colMode = 0;	/*采集类型*/
	UINT8 returnValue = CI_ERROR;/*返回值*/
	UINT8 relayDriveState = 0u;

	returnValue = CheckRelayDriveOutTimeState(relayId);

	if (CI_ERROR == returnValue)/*驱动超时*/
	{
		returnValue = CI_SUCCESS;
		relayDriveState = GetRelayDriveState(relayId);
		colMode = GetRelayCollectMode(relayId);
		if (RELAY_DRIVE_STATE_UP == relayDriveState)
		{/*驱动吸起*/
			switch (colMode)
			{
			case RELAY_COLL_MODE_FORE:
				/*前节点采集情况*/
				if (RELAY_STATE_UP == foreNodeColl)
				{
				}
				else
				{
					returnValue = CI_ERROR;
				}
				break;

			case RELAY_COLL_MODE_BACK:
				/*后节点采集情况*/
				if (RELAY_STATE_DOWN == backNodeColl)/*后采落下代表继电器此时吸起*/
				{
				}
				else
				{
					returnValue = CI_ERROR;
				}
				break;
			case RELAY_COLL_MODE_DOUBLE:
				/*双节点采集情况*/
				if ((RELAY_STATE_UP == foreNodeColl) && (RELAY_STATE_DOWN == backNodeColl))
				{/*前采集吸起,后采落下*/
				}
				else
				{
					returnValue = CI_ERROR;
				}
				break;
			default:
				/*不可达分支*/
				break;
			}
		}
		else if ((RELAY_DRIVE_STATE_DOWN == relayDriveState) || (RELAY_DRIVE_STATE_NULL == relayDriveState))
		{/*驱动落下*/
			switch (colMode)
			{
			case RELAY_COLL_MODE_FORE:
				/*前节点采集情况*/
				if (RELAY_STATE_DOWN == foreNodeColl)
				{
				}
				else
				{
					returnValue = CI_ERROR;
				}
				break;

			case RELAY_COLL_MODE_BACK:
				/*后节点采集情况*/
				if (RELAY_STATE_UP == backNodeColl)/*后采吸起代表继电器此时落下*/
				{
				}
				else
				{
					returnValue = CI_ERROR;
				}
				break;
			case RELAY_COLL_MODE_DOUBLE:
				/*双节点采集情况*/
				if ((RELAY_STATE_DOWN == foreNodeColl) && (RELAY_STATE_UP == backNodeColl))
				{/*前采集落下,后采吸起，继电器落下*/
				}
				else
				{
					returnValue = CI_ERROR;
				}
				break;
			default:
				/*不可达分支*/
				break;

			}
		}
		else
		{/*不处理*/

		}
	}
	return returnValue;
}

/*
* 功能描述：获取PSD是否驱动采集不一致
* 参数说明： const UINT16 psdId, PSD ID
* 返回值  ：  0xff: 无报警
*			  0x55: 开门驱动采集不一致
*             0xaa: 关门驱动采集不一致
*cgh-合并CID-2349-4：
*/
UINT8 CheckPsdDriAndCollDiff(const UINT16 psdId)
{
	UINT8 returnValue = UINT8_MAX;/*返回值*/
	UINT8 psdDriveState = 0u;
	UINT16 kmj8Id = 0u;/*8KMJ*/
	UINT16 kmj6Id = 0u;/*6KMJ*/
	UINT16 kmj4Id = 0u;/*4KMJ*/
	UINT16 gmjId = 0u;/*GMJ*/
	UINT8 checkVal = 0u;

	psdDriveState = GetPsdDriveState(psdId);
	kmj4Id = GetFourGroupPsdOpenDrvRelayId(psdId);
	kmj6Id = GetSixGroupPsdOpenDrvRelayId(psdId);
	kmj8Id = GetEightGroupPsdOpenDrvRelayId(psdId);
	gmjId = GetPsdCloseDriveRelayId(psdId);

	if (PSD_DRIVE_STATE_OPEN == psdDriveState)
	{
		checkVal = 1u;
		checkVal *= CheckRelayDriveOutTimeState(kmj4Id);
		checkVal *= CheckRelayDriveOutTimeState(kmj6Id);
		checkVal *= CheckRelayDriveOutTimeState(kmj8Id);
		checkVal *= CheckRelayDriveOutTimeState(gmjId);

		if (0u == checkVal)
		{
			returnValue = PSD_OPEN_DRVANDCOLL_DIFF;/*开门驱动采集不一致*/
		}

	}
	else if (PSD_DRIVE_STATE_CLOSE == psdDriveState)
	{
		checkVal = 1u;
		checkVal *= CheckRelayDriveOutTimeState(kmj4Id);
		checkVal *= CheckRelayDriveOutTimeState(kmj6Id);
		checkVal *= CheckRelayDriveOutTimeState(kmj8Id);
		checkVal *= CheckRelayDriveOutTimeState(gmjId);

		if (0u == checkVal)
		{
			returnValue = PSD_CLOSE_DRVANDCOLL_DIFF;/*关门驱动采集不一致*/
		}
	}
	else
	{
		/*返回默认值*/
	}
	return returnValue;
}

/*
* 功能描述： 总Spks按钮指示灯处理
* 参数说明： UINT16 spksId ID
*
* 返回值  ： void
*/
void TotalSpksOutsideDisPlayProc(UINT16 spksId)
{
	UINT8 reVal = CI_ERROR;
	UINT8 spksIncludeSpksNum = 0u;
	UINT16* pSpksIncludeSpksIdBuf = NULL;
	UINT16 ii = 0u;
	UINT16 contrlspksId = 0u;/*被控SPKS id*/
	UINT32 spksflockStartNum = 0u;
	UINT8 spksSate = 0u;
	UINT8 spksCutState = 0u;
	UINT32 spksIndicDelayCount = 0u;
	UINT16 outsideRelayId = 0u;
	UINT8  checkCycOut = 0u;
	UINT8 totalSpksDriveFlag = TOTALSPKSDRIVE_INVALID;
	if (0u < spksId)
	{
		reVal = CI_SUCCESS;
	}

	if (CI_SUCCESS == reVal)
	{
		spksIncludeSpksNum = GetSpksIncludeSpksNum(spksId);
		pSpksIncludeSpksIdBuf = GetSpksIncludeSpksIdBuf(spksId);

		if ((0u < spksIncludeSpksNum) && (NULL != pSpksIncludeSpksIdBuf))
		{
		}
		else
		{
			reVal = CI_ERROR;
		}
	}

	if (CI_SUCCESS == reVal)
	{
		for (ii = 0; ii < spksIncludeSpksNum; ii++)/*遍历总spks管辖的spks*/
		{
			contrlspksId = pSpksIncludeSpksIdBuf[ii];/*受控spks id*/
			totalSpksDriveFlag = GetDriveOutDisFlag(contrlspksId);
			if (0u < contrlspksId)
			{
				/*总SPKS按钮按下,且未旁路*/
				spksSate = GetSpksState(spksId);
				spksCutState = GetSpksCutState(spksId);
				spksflockStartNum = GetSpksflockStartNum(spksId);/*获取总SPKS激活起始周期*/
				if ((SPKS_STATUS_YES == spksSate) && (SPKS_CUT_NO == spksCutState))
				{
					/*因总spks按下，驱动其管辖的spks 室外指示灯点亮*/
					outsideRelayId = GetSpksOutsideRelayId(contrlspksId);/*户外指示灯*/
					if ((0u < outsideRelayId) && (UINT16_MAX != outsideRelayId))
					{
						spksIndicDelayCount = GetSpksIndicDelayCount();/*获取延时周期数*/
						checkCycOut = SystemOverTimeCheck(spksflockStartNum, spksIndicDelayCount);
						if (CI_TIME_OUT == checkCycOut)
						{
							(void)SetRelayDriveState(outsideRelayId, RELAY_STATE_UP); /*户外指示灯亮灯*/
							SetDriveOutDisFlag(contrlspksId, TOTALSPKSDRIVE_YES);/*总SPKS有效，则设置总SPKS驱动分SPKS室外灯标志*/
						}
						else
						{
							/*户外指示灯保持之前状态。若存在1个总spks按下，则保持该总spks点亮室外指示灯状态*/
						}
					}
				}
				else
				{
					if (TOTALSPKSDRIVE_YES != totalSpksDriveFlag)
					{
						SetDriveOutDisFlag(contrlspksId, TOTALSPKSDRIVE_NO);/*标志本周期没有被设置yes，则可以设置为NO*/
					}
				}
			}
		}
	}
}

/*
* 功能描述： 室外SPKS指示灯驱动
* 参数说明： UINT16 contrlspksId SPKS ID
*            UINT32 spksflockStartNum  spks作用起始周期
* 返回值  ： void
*/

void SpksOutsideDisPlayDriv(UINT16 contrlspksId, UINT32 spksflockStartNum)
{
	UINT8 reVal = CI_ERROR;
	UINT8 spksSate = 0u;
	UINT16 outsideRelayId = 0u;
	UINT32 spksIndicDelayCount = 0u;
	UINT8 checkCycOut = 0u;
	UINT8 spksCutState = 0u;
	UINT8 totalSpksDriveFlag = 0u;

	if (0u < contrlspksId)
	{
		reVal = CI_SUCCESS;
	}

	if (CI_SUCCESS == reVal)
	{
		outsideRelayId = GetSpksOutsideRelayId(contrlspksId);/*户外指示灯*/
		if ((0u < outsideRelayId) && (UINT16_MAX != outsideRelayId))
		{
			/*户外指示灯存在，继续*/
		}
		else
		{
			reVal = CI_ERROR;
		}

	}

	if (CI_SUCCESS == reVal)
	{
		spksSate = GetSpksState(contrlspksId);/*spks激活状态*/
		spksCutState = GetSpksCutState(contrlspksId);/*旁路状态*/
		totalSpksDriveFlag = GetDriveOutDisFlag(contrlspksId);
		if ((SPKS_STATUS_YES == spksSate) && (SPKS_CUT_NO == spksCutState) && (TOTALSPKSDRIVE_YES != totalSpksDriveFlag))
		{/*spks室外指示灯仅在spks激活且未旁路且总SPKS未驱动状态下点亮*/
			spksIndicDelayCount = GetSpksIndicDelayCount();/*获取延时周期数*/
			checkCycOut = SystemOverTimeCheck(spksflockStartNum, spksIndicDelayCount);
			if (CI_TIME_OUT == checkCycOut)
			{
				(void)SetRelayDriveState(outsideRelayId, RELAY_STATE_UP); /*户外指示灯亮灯*/
			}
			else
			{
				(void)SetRelayDriveState(outsideRelayId, RELAY_STATE_DOWN); /*户外指示灯灭灯*/
			}
		}
		else
		{
			if (TOTALSPKSDRIVE_YES != totalSpksDriveFlag)
			{
				(void)SetRelayDriveState(outsideRelayId, RELAY_STATE_DOWN); /*户外指示灯灭灯*/
			}
			else
			{
				/*总SPKS驱动分SPKS室外指示灯亮，不处理*/
			}
		}

	}
}

/*
* 功能描述： 判断硬件扣车是否执行
* 参数说明： const UINT16 detainCutRelayId     旁路继电
			 const UINT16 signalDetainRelayId  扣车继电器

* 返回值  ： CI_ERROR:   不执行
*            CI_SUCCESS: 执行
*
*/
UINT8 CheakDeatainState(UINT16 detainCutRelayId, UINT16 signalDetainRelayId)
{
	UINT8 relayDetainValidFlag = 0u;
	UINT8 tmpRelayColState = 0u;
	UINT16 detainCutState = 0u;  /*扣车旁路状态*/
	UINT8 detainCutBelongCi = 0u;
	UINT8 localCiId = 0u;
	UINT8 ret = CI_SUCCESS;				/*返回结果*/
	localCiId = GetSystemParaLocalCiId();       /*获取本机联锁ID*/
	relayDetainValidFlag = GetCiFunctionSwitchConfig(FUNC_RELAY_DETAIN_VALID_FLAG);/*获取硬线扣车有效标志*/
	tmpRelayColState = GetRelayCollState(signalDetainRelayId);/*获取扣车继电器采集状态*/

	if (((UP_VALID == relayDetainValidFlag) && (RELAY_DRIVE_STATE_UP == tmpRelayColState))
		|| ((DOWN_VALID == relayDetainValidFlag) && (RELAY_DRIVE_STATE_DOWN == tmpRelayColState))) /*继电器吸起,扣车*/
	{
		if ((0u != detainCutRelayId) && (UINT16_MAX != detainCutRelayId)) /*有旁路继电器*/
		{
			detainCutState = GetRelayCollState(detainCutRelayId);/*获取扣车旁路继电器采集状态*/
			detainCutBelongCi = GetRelayBelongCiId(detainCutRelayId);
			/*扣车旁路继电器属于本联锁*/
			if (detainCutBelongCi == localCiId)
			{

				if (RELAY_DRIVE_STATE_DOWN == detainCutState) /*旁路无效,扣车*/
				{
					ret = CI_SUCCESS;
				}
				else if (RELAY_DRIVE_STATE_UP == detainCutState) /*旁路有效,未扣车*/
				{
					ret = CI_ERROR;
				}
				else /*旁路无效,扣车*/
				{
					ret = CI_SUCCESS;
				}
			}
		}
		else /*无旁路继电器,扣车*/
		{
			ret = CI_SUCCESS;
		}

	}
	else if (((UP_VALID == relayDetainValidFlag) && (RELAY_DRIVE_STATE_DOWN == tmpRelayColState))
		|| ((DOWN_VALID == relayDetainValidFlag) && (RELAY_DRIVE_STATE_UP == tmpRelayColState))) /*继电器落下,未扣车*/
	{
		ret = CI_ERROR;
	}
	else /*继电器状态无效：扣车*/
	{
		ret = CI_SUCCESS;
	}

	return ret;
}

/*
* 功能描述： 获取具备虚拟ESB当前需要设置的状态
* 参数说明：UINT16 esbId ESB ID
*
* 返回值  ： ESB_STATE_VALID_YES：设置状态为有效
*            ESB_STATE_VALID_NO：设置状态为无效
*			 CI_ERROR: 获取失败
* cgh-合并CID-3037-1：
*/
UINT8 GetVirEsbCurNeedSetState(UINT16 esbId)
{
	UINT8 esbRelayState = 0U; /*esb继电器采集状态*/
	UINT8 essRelayState = 0U; /*紧急停车开关继电器采集状态*/
	UINT8 resultVal = CI_ERROR;/*函数返回值*/
	UINT8 curEsbDriveState = 0U;  /*当前esb相关继电器驱动状态机*/
	UINT16 bufIndex = 0U;  /*数组下标*/

	bufIndex = GetEsbConfigBufIndex(esbId);  /*获取数组下标*/
	if (bufIndex < ESB_SUM_MAX)
	{
		esbRelayState = GetEsbAutualState(esbId);/*获取ESB按钮状态*/
		essRelayState = GetEssState(esbId);/*获取ESS按钮状态*/

		/*当紧急停车按钮存在时esb的状态需根据esb按钮实际状态与ESS状态共同决定*/
		if ((ESB_STATE_VALID_YES == esbRelayState) || (ESB_STATE_STOP_FLAG == essRelayState))
		{
			resultVal = ESB_STATE_VALID_YES;  /*当esb采集继电器或紧急停车开关采集继电器有一个落下则esb有效*/
		}
		else if ((ESB_STATE_VALID_NO == esbRelayState) && (ESB_STATE_GO_FLAG == essRelayState))
		{
			curEsbDriveState = GetEsbRelateRelayDriveProState(esbId);   /*获取esb相关继电器当前驱动状态机*/
			if (ESB_FAULT_SIX_STATE == curEsbDriveState)
			{/*当一直在状态机6但是还采到ESS和PEP都吸起则认为esb还是有效的*/
				resultVal = ESB_STATE_VALID_YES;
			}
			else
			{
				resultVal = ESB_STATE_VALID_NO;
			}
		}
		else
		{
			resultVal = CI_ERROR;             /*不存在的值返回失败不设置esb状态*/
		}

	}
	else
	{
		resultVal = CI_ERROR;                   /*esb ID不合法返回失败不设置esb状态*/
	}

	return resultVal;
}
/*
* 功能描述： 虚拟ESB逻辑处理函数
* 参数说明： 无
* 返回值  ： void
* cgh-合并CID-3037-1：
*/
void VirtualEsbLogicProcess(void)
{
	/*变量初始化*/
	UINT16 esbCurSum = 0U;
	UINT8  localCiId = 0U;          /*本地联锁ID*/
	UINT16 esbId = 0U;             /*esb ID*/
	UINT8  devBlongCiId = 0U;       /*设备所属联锁ID*/
	UINT16 i = 0U;                 /*循环索引*/
	UINT8 localCiType = 0U;			/*本连锁类型*/
	UINT16 EssSteadyMaskIdFlag = ESS_MASK_NO; /*Ess稳灯码位配置标志*/
	UINT16 EssFlashMaskIdFlag = ESS_MASK_NO;	/*Ess稳灯码位配置标志*/
	UINT8 esbSetState = 0U;
	UINT8 chEsbbVirtualAttribute = 0U;

	esbCurSum = GetEsbSum();     /*获取esb数量*/
	localCiId = GetSystemParaLocalCiId(); /*获取本地联锁ID*/
	localCiType = GetLocalCiType();/*获取联锁类型*/
	if (0U < esbCurSum)
	{
		/*获取ESB状态信息*/
		for (i = 0U; i < esbCurSum; i++)
		{
			esbId = GetEsbId(i);
			devBlongCiId = GetEsbBelongCiId(esbId); /*获取设备所属联锁ID*/
			/*获取当前ESB虚拟属性*/
			chEsbbVirtualAttribute = GetEsbVirtualAttribute(esbId);

			if ((localCiId == devBlongCiId) && (CI_TYPE_SCX == localCiType)
				&& (ESB_VIRTUAL_ATTR_YES == chEsbbVirtualAttribute))
			{
				/*获取指定ESB对应的ESS稳灯码位ID*/
				EssSteadyMaskIdFlag = GetEssSteadyCiToAtsMaskFlag(esbId);
				/*获取指定ESB对应的ESS闪灯码位ID*/
				EssFlashMaskIdFlag = GetEssFlashCiToAtsMaskFlag(esbId);
				if ((ESS_MASK_YES == EssSteadyMaskIdFlag) && (ESS_MASK_YES == EssFlashMaskIdFlag))
				{
					/*虚拟ESB下相关处理*/
					VirEsbRelateDelayDriStaManage(esbId);
					/*进行ESB与ESS状态融合*/
					esbSetState = GetVirEsbCurNeedSetState(esbId);

				}
				else
				{
					/*获取ESB按钮状态*/
					esbSetState = GetEsbAutualState(esbId);

				}
				/*进行虚拟ESB状态更新*/
				(void)SetEsbState(esbId, esbSetState);

			}
			else
			{
				; /*非本连锁不处理，非试车线不处理*/
			}

		}
	}
}
/*
* 功能描述： OC ESS和PEP操作下的闪灯、稳灯和蜂鸣器继电器驱动输出状态机管理函数
* 参数说明： UINT16 esbId ESB ID
* 返回值  ： void
* 备注：cgh-合并CID-3037-1：。
*/
void VirEsbRelateDelayDriStaManage(UINT16 esbId)
{
	/*变量初始化*/
	UINT8 esbRelateDelayDriveState = 0U; /*esb相关继电器驱动状态机*/
	UINT16 bufIndex = 0U;  /*数组下标*/
	UINT8 EsbRelayState = 0U;
	UINT8 ESSRelayState = 0U;
	bufIndex = GetEsbConfigBufIndex(esbId);  /*获取数组下标*/

	if (bufIndex < ESB_SUM_MAX)
	{
		esbRelateDelayDriveState = GetEsbRelateRelayDriveProState(esbId); /*获取esb相关继电器驱动状态机*/
		EsbRelayState = GetEsbAutualState(esbId);/*获取ESB按钮状态*/
		ESSRelayState = GetEssState(esbId);/*获取ESS按钮状态*/

		switch (esbRelateDelayDriveState)
		{
		case ESB_PEPUP_ESSUP_INITION_STA:
			/*初始状态，稳灯、闪灯都不驱动*/
			SetEsbRelateEssSteadyState(esbId, ESB_STATE_LIGHT_STATE_N);
			SetEsbRelateEssFlashState(esbId, ESB_STATE_LIGHT_STATE_N);

			if ((ESB_STATE_VALID_YES == EsbRelayState) && (ESB_STATE_GO_FLAG == ESSRelayState))
			{
				/*PEP按下、ESS去位后，状态流转到状态机2*/
				SetEsbRelateRelayDriveProState(esbId, ESB_PEPDOWN_ESSUP_TWO_STATE);
			}
			else if ((ESB_STATE_VALID_NO == EsbRelayState) && (ESB_STATE_STOP_FLAG == ESSRelayState))
			{
				/*ESS停位按下后，状态流转到状态机5*/
				SetEsbRelateRelayDriveProState(esbId, ESB_TWOPEPUP_ESSDOWN_FIVE_STATE);
			}
			else
			{
				/*在初始状态下按下PEP或者ESS在停位进行状态流转其他情况不做处理*/
			}
			break;
		case ESB_PEPDOWN_ESSUP_TWO_STATE:

			/*状态机2时，指示灯闪灯*/
			SetEsbRelateEssSteadyState(esbId, ESB_STATE_LIGHT_STATE_N);
			SetEsbRelateEssFlashState(esbId, ESB_STATE_LIGHT_STATE_Y);

			if ((ESB_STATE_VALID_YES == EsbRelayState) && (ESB_STATE_STOP_FLAG == ESSRelayState))
			{
				/*此时在使ESS在停位，则状态流转道状态机3*/
				SetEsbRelateRelayDriveProState(esbId, ESB_PEPDOWN_ESSDOWN_THREE_STATE);
			}
			else if ((ESB_STATE_VALID_NO == EsbRelayState) && (ESB_STATE_GO_FLAG == ESSRelayState))
			{
				/*此时直接复位PEP，是非正常操作，流程流转到状态机6*/
				SetEsbRelateRelayDriveProState(esbId, ESB_FAULT_SIX_STATE);
			}
			else
			{
				/*在状态机2时只能是以上两种流转情况其他情况不做处理*/
			}
			break;
		case ESB_PEPDOWN_ESSDOWN_THREE_STATE:

			/*在状态3时，指示灯稳灯*/
			SetEsbRelateEssSteadyState(esbId, ESB_STATE_LIGHT_STATE_Y);
			SetEsbRelateEssFlashState(esbId, ESB_STATE_LIGHT_STATE_N);

			if ((ESB_STATE_VALID_YES == EsbRelayState) && (ESB_STATE_GO_FLAG == ESSRelayState))
			{
				/*此时使ESS在去位，则回到状态机2*/
				SetEsbRelateRelayDriveProState(esbId, ESB_PEPDOWN_ESSUP_TWO_STATE);
			}
			else if ((ESB_STATE_VALID_NO == EsbRelayState) && (ESB_STATE_STOP_FLAG == ESSRelayState))
			{
				/*此时使PEP恢复，则回到状态机4*/
				SetEsbRelateRelayDriveProState(esbId, ESB_ONEPEPUP_ESSDOWN_FOUR_STATE);
			}
			else
			{
				/*在状态机3时只能是以上两种流转情况其他情况不做处理*/
			}
			break;
		case ESB_ONEPEPUP_ESSDOWN_FOUR_STATE:

			/*当PEP先按下之后操作ESS到停位，再恢复PEP，指示灯闪烁为状态机4*/
			SetEsbRelateEssSteadyState(esbId, ESB_STATE_LIGHT_STATE_N);
			SetEsbRelateEssFlashState(esbId, ESB_STATE_LIGHT_STATE_Y);

			if ((ESB_STATE_VALID_NO == EsbRelayState) && (ESB_STATE_GO_FLAG == ESSRelayState))
			{
				/*此时再使ESS在去位，则恢复到初始状态*/
				SetEsbRelateRelayDriveProState(esbId, ESB_PEPUP_ESSUP_INITION_STA);
			}
			else if ((ESB_STATE_VALID_YES == EsbRelayState) && (ESB_STATE_STOP_FLAG == ESSRelayState))
			{
				/*此时再使PEP落下，则又转到状态机3*/
				SetEsbRelateRelayDriveProState(esbId, ESB_PEPDOWN_ESSDOWN_THREE_STATE);
			}
			else
			{
				/*在状态机4时只能是以上两种流转情况其他情况不做处理*/
			}
			break;
		case ESB_TWOPEPUP_ESSDOWN_FIVE_STATE:

			/*先使ESS在停位，PEP吸起时指示灯稳灯为状态机5，这个时候与状态机4的PEP和ESS继电器状态一致但是报警不一致
			可以直接使ESS在去位恢复到初始状态*/
			SetEsbRelateEssSteadyState(esbId, ESB_STATE_LIGHT_STATE_Y);
			SetEsbRelateEssFlashState(esbId, ESB_STATE_LIGHT_STATE_N);
			if ((ESB_STATE_VALID_NO == EsbRelayState) && (ESB_STATE_GO_FLAG == ESSRelayState))
			{
				/*直接操作ESS位去位，恢复到初始状态*/
				SetEsbRelateRelayDriveProState(esbId, ESB_PEPUP_ESSUP_INITION_STA);
			}
			else if ((ESB_STATE_VALID_YES == EsbRelayState) && (ESB_STATE_STOP_FLAG == ESSRelayState))
			{
				/*再操作PEP使之落下，则流转至状态机3*/
				SetEsbRelateRelayDriveProState(esbId, ESB_PEPDOWN_ESSDOWN_THREE_STATE);
			}
			else
			{
				/*在状态机5时只能是以上两种流转情况其他情况不做处理*/
			}
			break;
		case ESB_FAULT_SIX_STATE:

			/*只有在按下PEP后直接恢复PEP才会流转到这个状态机，此时虽然ESS和PEP都是吸起的，但是ESB有效指示灯闪灯*/
			SetEsbRelateEssSteadyState(esbId, ESB_STATE_LIGHT_STATE_N);
			SetEsbRelateEssFlashState(esbId, ESB_STATE_LIGHT_STATE_Y);

			if ((ESB_STATE_VALID_YES == EsbRelayState) && (ESB_STATE_GO_FLAG == ESSRelayState))
			{
				/*再按下PEP，回到状态机2按正常流程进行操作，流转到状态机2*/
				SetEsbRelateRelayDriveProState(esbId, ESB_PEPDOWN_ESSUP_TWO_STATE);
			}
			else if ((ESB_STATE_VALID_NO == EsbRelayState) && (ESB_STATE_STOP_FLAG == ESSRelayState))
			{
				/*再按下ESS，则认为是先ESS按下的，按照此操作流程进行操作，即流转到状态机4*/
				SetEsbRelateRelayDriveProState(esbId, ESB_ONEPEPUP_ESSDOWN_FOUR_STATE);
			}
			else
			{
				/*在状态机6时只能是以上两种流转情况其他情况不做处理*/
			}
			break;
		default:
			/*其他不存在的状态机不做处理*/
			break;
		}
	}
}
/*
* 功能描述： 获取复示信号机驱动颜色
* 参数说明： const UINT8 signalColor, 主体信号机颜色
* 返回值  ： 0x01 :驱红灭，0x02:驱黄，0x04:驱绿
*cgh-合并CID-3037-3：
*/
UINT8 GetFushiSignalDriveColor(const UINT8 signalColor)
{
	UINT8 reVal = CI_ERROR;

	/*黄灯*/
	if (SIGNAL_SHOWCOLOUR_YELLOW == signalColor)
	{
		reVal = SIGNAL_DRIVECOLOUR_YELLOW;
	}
	else if (SIGNAL_SHOWCOLOUR_GREEN == signalColor)
	{
		reVal = SIGNAL_DRIVECOLOUR_GREEN;
	}
	else
	{
		reVal = SIGNAL_SHOWCOLOUR_REDCLOSE;
	}
	return reVal;
}
/*
* 功能描述： 站台清客确认按钮闪灯稳灯继电器驱动处理
* 参数说明： const UINT16 psdId, 屏蔽门ID
* 返回值  ： 无
*cgh-合并CID-3037-7：
*/
void StationCearPassenagerProcess(const UINT16 psdId)
{
	UINT8 clearPassenagerFlag = 0U; /*清客标志*/
	UINT16 QKSteadyLightRelayId = 0U;  /*清客确认按钮稳灯继电器ID*/
	UINT8 QKButtonRelayState = 0U;             /*清客确认按钮继电器状态*/
	UINT16 QKFlashLightRelayId = 0U;  /*清客确认按钮闪灯继电器ID*/
	UINT16 QKButtonRelayId = 0U;      /*清客确认按钮继电器ID*/
	UINT16 psdRelativePhySecId = 0U;      /*屏蔽门关联的物理区段ID*/
	UINT8 secState = 0U;      /*区段状态*/
	UINT8 psdState = 0U;     /*屏蔽门状态*/
	UINT8 steadyLightFlag = 0U;  /*清客按钮稳灯标志*/

	clearPassenagerFlag = GetClearPassenagerFlag(psdId);  /*获取清客标志*/
	QKSteadyLightRelayId = GetQKASteadyLightRelayId(psdId);/*获取清客按钮确认稳灯继电器ID*/
	QKFlashLightRelayId = GetQKAFlashLightRelayId(psdId); /*获取清客按钮确认闪灯继电器ID*/
	if (ATS_TO_CI_PLATFORM_QK_YES == clearPassenagerFlag)
	{
		psdRelativePhySecId = GetPsdRelatedPhySecId(psdId);  /*获取屏蔽门关联的物理区段ID*/
		secState = GetPhySecCurOccupyState(psdRelativePhySecId); /*获取物理区段当前占用状态*/
		if (SECTION_OCCUPY_NO == secState)
		{
			/*站台轨出清之后，驱动稳灯闪灯继电器落下*/
			if ((0U != QKSteadyLightRelayId) && (UINT16_MAX != QKSteadyLightRelayId))
			{
				(void)SetRelayDriveState(QKSteadyLightRelayId, RELAY_DRIVE_STATE_DOWN);
			}

			if ((0U != QKFlashLightRelayId) && (UINT16_MAX != QKFlashLightRelayId))
			{
				(void)SetRelayDriveState(QKFlashLightRelayId, RELAY_DRIVE_STATE_DOWN);
			}
			/*车出清站台轨之后清客标志无效*/
			SetClearPassenagerFlag(psdId, ATS_TO_CI_PLATFORM_QK_NO);
			SetSteadyLightFlag(psdId, QK_BUTTON_STEADY_LIGHT_NO);  /*清除清客按钮已驱动过稳灯标志*/
		}
		else
		{
			/*站台轨有车占用*/
			psdState = GetPsdState(psdId);         /*获取屏蔽门状态*/
			if (PSD_STATE_OPEN == psdState)
			{
				/*收到了VOBC的开门命令或者站台/IBP盘上操作了屏蔽门门车门打开命令且屏蔽门状态为打开，则根据清客按钮确认继电器状态设置稳灯和闪灯继电器驱动状态*/
				QKButtonRelayId = GetQKButtonRelayId(psdId);          /*获取请客确认按钮继电器ID*/
				QKButtonRelayState = GetRelayCollState(QKButtonRelayId); /*获取清客确认按钮继电器状态*/
				steadyLightFlag = GetSteadyLightFlag(psdId);
				/*清客确认按钮是自负式的，按下之后继电器吸起3s就落下，因此在驱动过清客按钮稳灯后持续驱稳灯*/
				if ((RELAY_DRIVE_STATE_UP == QKButtonRelayState) || (QK_BUTTON_STEADY_LIGHT_YES == steadyLightFlag))
				{
					/*站台清客确认按钮继电器吸起，清客确认按钮稳灯继电器驱动*/
					if ((0U != QKSteadyLightRelayId) && (UINT16_MAX != QKSteadyLightRelayId))
					{
						(void)SetRelayDriveState(QKSteadyLightRelayId, RELAY_DRIVE_STATE_UP);
					}

					if ((0U != QKFlashLightRelayId) && (UINT16_MAX != QKFlashLightRelayId))
					{
						(void)SetRelayDriveState(QKFlashLightRelayId, RELAY_DRIVE_STATE_DOWN);
					}
					SetSteadyLightFlag(psdId, QK_BUTTON_STEADY_LIGHT_YES);  /*设置清客按钮已驱动过稳灯标志*/
				}
				else if (RELAY_DRIVE_STATE_DOWN == QKButtonRelayState)
				{
					/*站台清客确认按钮继电器落下，清客确认按钮闪灯继电器驱动*/
					if ((0U != QKSteadyLightRelayId) && (UINT16_MAX != QKSteadyLightRelayId))
					{
						(void)SetRelayDriveState(QKSteadyLightRelayId, RELAY_DRIVE_STATE_DOWN);
					}

					if ((0U != QKFlashLightRelayId) && (UINT16_MAX != QKFlashLightRelayId))
					{
						(void)SetRelayDriveState(QKFlashLightRelayId, RELAY_DRIVE_STATE_UP);
					}
				}
				else
				{
					/*不做处理*/
				}
			}
			else
			{
				/*当驱过稳灯之后，车关门，还未出清站台轨之前，一直驱稳灯*/
				steadyLightFlag = GetSteadyLightFlag(psdId);
				if (QK_BUTTON_STEADY_LIGHT_YES == steadyLightFlag)
				{
					/*站台清客确认按钮继电器吸起，清客确认按钮稳灯继电器驱动*/
					if ((0U != QKSteadyLightRelayId) && (UINT16_MAX != QKSteadyLightRelayId))
					{
						(void)SetRelayDriveState(QKSteadyLightRelayId, RELAY_DRIVE_STATE_UP);
					}

					if ((0U != QKFlashLightRelayId) && (UINT16_MAX != QKFlashLightRelayId))
					{
						(void)SetRelayDriveState(QKFlashLightRelayId, RELAY_DRIVE_STATE_DOWN);
					}
				}
			}
		}
	}
	else
	{
		/*站台没有清客标志时，如果闪灯稳灯继电器有效则驱动继电器落下*/
		if ((0U != QKSteadyLightRelayId) && (UINT16_MAX != QKSteadyLightRelayId))
		{
			(void)SetRelayDriveState(QKSteadyLightRelayId, RELAY_DRIVE_STATE_DOWN);
		}

		if ((0U != QKFlashLightRelayId) && (UINT16_MAX != QKFlashLightRelayId))
		{
			(void)SetRelayDriveState(QKFlashLightRelayId, RELAY_DRIVE_STATE_DOWN);
		}
	}
}

/*
* 功能描述： 更新屏蔽门对应清客确认箱关门按钮及记忆状态（用于后续驱动PDB表示灯黄闪）
* 参数说明： const UINT16 wPsdId 屏蔽门ID
* 返回值  ： 0u: 更新失败
*			 1: 更新成功
* cgh修改成都四线清客需求
*/
UINT8 PsdCleFarePCBRelToDevStaProc(const UINT16 wPsdId)
{
	UINT8 reVal = CI_ERROR;
	UINT32 dwCycNum = 0U;                 /*清客确认箱PCB按钮按下周期*/
	UINT16 wCleFarePCBButRelayId = 0U;    /*清客确认箱关门按钮继电器ID*/
	UINT8 chCleFarePCBButRelaySta = 0U;  /*清客确认箱关门按钮继电器状态*/
	UINT8 chCheckTimeState = 0U;         /*清客确认箱关门按钮采集有效标志*/
	UINT32 dwSelfCollSnCount = 0U;         /*自复式按钮对应继电器采集有效周期数*/

	if ((0u == wPsdId) || (PSD_SUM_MAX <= wPsdId))
	{
		reVal = CI_ERROR;
	}
	else
	{/*清客确认箱关门按钮状态更新*//*by cgh 20230526*/
		reVal = CI_SUCCESS;
		wCleFarePCBButRelayId = GetCleFarePCBButRelayId(wPsdId);
		if ((0u != wCleFarePCBButRelayId) && (UINT16_MAX != wCleFarePCBButRelayId))
		{/*清客确认箱PCB按钮继电器ID有效*/
			chCleFarePCBButRelaySta = GetRelayCollState(wCleFarePCBButRelayId);
			dwCycNum = GetCleFarePCBPressCycNum(wPsdId);
			/*清客确认箱PCB按钮为自复式按钮，对应继电器需采集3个周期才认为可信---防抖*/
			if (RELAY_STATE_UP == chCleFarePCBButRelaySta)
			{
				if (0u == dwCycNum)
				{/*若未计时或者中间抖动，则重新设置起始周期*/
					reVal = SetCleFarePCBPressCycNum(wPsdId, Get2oo2CurCycleNum());
				}
			}
			else if (RELAY_STATE_DOWN == chCleFarePCBButRelaySta)
			{/*清除清客确认箱PCB按下起始周期号*/
				reVal = SetCleFarePCBPressCycNum(wPsdId, 0u);
			}
			else
			{/*采集状态无效*/
				reVal = CI_ERROR;
			}

			if (CI_SUCCESS == reVal)
			{
				/*因为前面根据继电器状态改变过清客确认箱PCB按钮按下周期，所以在这里再次获取一次*/
				dwCycNum = GetCleFarePCBPressCycNum(wPsdId);
				/*自复式按钮对应继电器采集有效周期数*/
				dwSelfCollSnCount = GetSelfButCollCount();
				/*延时计时*/
				chCheckTimeState = SystemOverTimeCheck(dwCycNum, dwSelfCollSnCount);
				/*解锁计时超时*/
				if (CI_TIME_OUT == chCheckTimeState)
				{/*清客确认箱PCB按钮按下周期数达到配置要求(防抖)，设置清客确认箱PCB按钮状态及按钮记忆状态按下*/
					reVal = SetCleFarePCBButtonState(wPsdId, QK_PSD_BUTTON_STATE_DOWN);
					reVal &= SetCleFarePCBButKeepState(wPsdId, QK_PSD_BUTTON_STATE_DOWN);
				}
				else
				{/*清客确认箱PCB按钮按下周期数达不到配置要求(防抖)或者PCB按钮已抬起，设置清客确认箱PCB按钮状态未按下*/
					reVal = SetCleFarePCBButtonState(wPsdId, QK_PSD_BUTTON_STATE_UP);
				}
			}
			else
			{/*采集无效,设置清客确认箱PCB按钮及记忆状态未按下*/
				reVal = SetCleFarePCBPressCycNum(wPsdId, 0u);
				reVal &= SetCleFarePCBButtonState(wPsdId, QK_PSD_BUTTON_STATE_UP);
				reVal &= SetCleFarePCBButKeepState(wPsdId, QK_PSD_BUTTON_STATE_UP);
			}
		}
		else
		{
			reVal = CI_SUCCESS; /*有些线路PSD不配置清客确认箱PCB按钮，即清客确认箱PCB按钮继电器ID无效，continue，继续执行*/
		}
	}
	return reVal;
}

/*
* 功能描述： 更新屏蔽门对应清客确认箱发车按钮及指示灯逻辑状态
* 参数说明： const UINT16 wPsdId 屏蔽门ID
* 返回值  ： 0u: 更新失败
*			 1: 更新成功
* cgh修改成都四线清客需求
*/
UINT8 PsdCleFarePDBRelToDevStaProc(const UINT16 wPsdId)
{
	UINT8 reVal = CI_ERROR;
	UINT32 dwCycNum = 0U;                 /*PDB按钮按下周期*/
	UINT16 wPDBButRelayId = 0U;    /*PDB按钮继电器ID*/
	UINT8 chPDBButRelaySta = 0U;  /*PDB按钮继电器状态*/
	UINT8 chCheckTimeState = 0U;         /*PDB按钮采集有效标志*/
	UINT32 dwSelfCollSnCount = 0U;         /*自复式按钮对应继电器采集有效周期数*/

	if ((0u == wPsdId) || (PSD_SUM_MAX <= wPsdId))
	{
		reVal = CI_ERROR;
	}
	else
	{/*发车按钮状态更新*//*by cgh 20230529*/
		reVal = CI_SUCCESS;
		wPDBButRelayId = GetPsdDeparConfmRelayId(wPsdId);
		if ((0u != wPDBButRelayId) && (UINT16_MAX != wPDBButRelayId))
		{/*清客确认箱PDB按钮继电器ID有效*/
			chPDBButRelaySta = GetRelayCollState(wPDBButRelayId);
			dwCycNum = GetPSBPressCycNum(wPsdId);
			/*PDB按钮为自复式按钮，对应继电器需采集3个周期才认为可信---防抖*/
			if (RELAY_STATE_UP == chPDBButRelaySta)
			{
				if (0u == dwCycNum)
				{/*若未计时或者中间抖动，则重新设置起始周期*/
					reVal = SetPSBPressCycNum(wPsdId, Get2oo2CurCycleNum());
				}
			}
			else if (RELAY_STATE_DOWN == chPDBButRelaySta)
			{/*PDB按下起始周期号*/
				reVal = SetPSBPressCycNum(wPsdId, 0u);
			}
			else
			{/*采集状态无效*/
				reVal = CI_ERROR;
			}

			if (CI_SUCCESS == reVal)
			{
				/*因为前面根据继电器状态改变过PDB按钮按下周期，所以在这里再次获取一次*/
				dwCycNum = GetPSBPressCycNum(wPsdId);
				/*自复式按钮对应继电器采集有效周期数*/
				dwSelfCollSnCount = GetSelfButCollCount();
				/*延时计时*/
				chCheckTimeState = SystemOverTimeCheck(dwCycNum, dwSelfCollSnCount);
				/*解锁计时超时*/
				if (CI_TIME_OUT == chCheckTimeState)
				{/*PDB按钮按下周期数达到配置要求(防抖)，设置PDB按钮状态有效，同时清除清客确认箱PCB按钮按下记忆状态*/
					reVal = SetPsdDepartButtonState(wPsdId, PLATFORM_DEPAR_BUTTON_STATE_VALID);
					reVal &= SetCleFarePCBButKeepState(wPsdId, QK_PSD_BUTTON_STATE_UP);
				}
				else
				{/*PDB按钮按下周期数达不到配置要求(防抖)或者PDB按钮已抬起，设置PDB按钮状态无效*/
					reVal = SetPsdDepartButtonState(wPsdId, PLATFORM_DEPAR_BUTTON_STATE_INVALID);
				}
			}
			else
			{/*采集无效,设置PDB按钮无效*/
				reVal = SetPSBPressCycNum(wPsdId, 0u);
				reVal &= SetPsdDepartButtonState(wPsdId, PLATFORM_DEPAR_BUTTON_STATE_INVALID);
			}
		}
		else
		{
			reVal = CI_SUCCESS; /*有些线路PSD不配置PDB按钮，即PDB按钮继电器ID无效，continue，继续执行*/
		}
	}
	return reVal;
}

/*
* 功能描述： 清客确认箱发车按钮指示灯闪灯处理
* 参数说明： const UINT16 psdId, 屏蔽门ID
* 返回值  ： 无
*cgh修改成都四线清客需求
*/
void PsdCleFarePDBFlashProcess(const UINT16 psdId)
{
	UINT8 chCleFarePCBButKeepState = 0U;/*清客确认箱关门按钮记忆状态*/
	UINT16 wCleFareFlaLigRelayId = 0U;  /*清客确认箱按钮指示灯闪灯继电器ID*/
	UINT16 wPsdRelativePhySecId = 0U;      /*屏蔽门关联的物理区段ID*/
	UINT8 chSecState = 0U;      /*区段状态*/
	UINT8 chPsdState = 0U;     /*屏蔽门状态*/
	UINT8 chMutualLockState = 0U;/*屏蔽门互锁解除状态*/

	chCleFarePCBButKeepState = GetCleFarePCBButKeepState(psdId);
	wCleFareFlaLigRelayId = GetCleFarePDBFlaLigRelayId(psdId); /*清客确认箱按钮指示灯闪灯继电器ID*/
	if ((0U != wCleFareFlaLigRelayId) && (UINT16_MAX != wCleFareFlaLigRelayId))
	{/*清客确认箱按钮指示灯闪灯继电器ID有效时进行处理*/
		if (QK_PSD_BUTTON_STATE_DOWN == chCleFarePCBButKeepState)
		{/*清客确认箱关门按钮记忆状态需为按下才有后续检查*/
			wPsdRelativePhySecId = GetPsdRelatedPhySecId(psdId);  /*获取屏蔽门关联的物理区段ID*/
			chSecState = GetPhySecCurOccupyState(wPsdRelativePhySecId); /*获取物理区段当前占用状态*/
			if (SECTION_OCCUPY_NO == chSecState)
			{/*站台轨无占用，则驱动清客确认箱PDB按钮指示灯闪灯继电器落下，设置清客确认箱PDB按钮指示灯不驱动闪灯标志*/
				(void)SetRelayDriveState(wCleFareFlaLigRelayId, RELAY_DRIVE_STATE_DOWN);
				(void)SetCleFarePDBFlaLigFlag(psdId, QK_BUTTON_FLASH_LIGHT_NO);
			}
			else
			{
				/*站台轨有车占用*/
				chPsdState = GetPsdState(psdId);         /*获取屏蔽门状态*/
				chMutualLockState = GetPsdMutualLockRemoveState(psdId);/*获取屏蔽门互锁解除状态*/

				if ((PSD_STATE_CLOSE == chPsdState) || (PSD_MUTUALLOCK_REMOVE_YES == chMutualLockState))
				{
					/*站台轨有车占用，屏蔽门关闭或者有互锁解除，则驱动清客确认箱PDB按钮指示灯闪灯继电器吸起，设置清客确认箱PDB按钮指示灯驱动闪灯标志*/
					(void)SetRelayDriveState(wCleFareFlaLigRelayId, RELAY_DRIVE_STATE_UP);
					(void)SetCleFarePDBFlaLigFlag(psdId, QK_BUTTON_FLASH_LIGHT_YES);
				}
				else
				{
					/*站台轨有车占用，但屏蔽门打开且没有互锁解除，则驱动清客确认箱PDB按钮指示灯闪灯继电器落下，设置清客确认箱PDB按钮指示灯不驱动闪灯标志*/
					(void)SetRelayDriveState(wCleFareFlaLigRelayId, RELAY_DRIVE_STATE_DOWN);
					(void)SetCleFarePDBFlaLigFlag(psdId, QK_BUTTON_FLASH_LIGHT_NO);

				}
			}
		}
		else
		{/*清客确认箱PCB关门按钮记忆状态不为按下，则驱动清客确认箱PDB按钮指示灯闪灯继电器落下，设置清客确认箱PDB按钮指示灯不驱动闪灯标志*/

			(void)SetRelayDriveState(wCleFareFlaLigRelayId, RELAY_DRIVE_STATE_DOWN);
			(void)SetCleFarePDBFlaLigFlag(psdId, QK_BUTTON_FLASH_LIGHT_NO);
		}
	}	
}

/*
* 功能描述：自复式紧急停车按钮处理
* 参数说明：UINT16 esbId ESB ID
* 返回值  ：无
*/
void EsbZfsBtnProc(UINT16 esbId)
{
	UINT16 esbRelayId = 0u;    /*esb继电器ID*/
	UINT8 localCiId = 0U;              /*本地联锁ID*/
	UINT8 esbRelayBelongCiId = 0U;     /*esb采集继电器1所属CI*/
	UINT8 esbRelayCollState = 0U;      /*esb按钮采集继电器1状态*/
	UINT32 cycnow = 0U;        /*当前周期*/
	UINT32 zfsBtnRelayCollCycNum = 0U;      /*自复式按钮继电器判断采集有效周期数*/
	UINT32 zfsBtnRelayFaultCycNum = 0U;     /*自复式按钮继电器判断故障周期数*/
	UINT32 esbPressCycNum = 0U;    /*紧急关闭按钮按下周期*/
	UINT8 btnPressValidTime = CI_TIME_NO;   /*按钮按下时间是否达到有效时间*/
	UINT8 btnPressFaultTime = CI_TIME_NO;   /*按钮按下时间是否达到故障时间*/
	UINT8 esbErrorFlag = ESB_ERROR_FLAG_NO;  /*ESB故障标志*/
	UINT16 bufIndex = 0U;    /*数组下标*/

	bufIndex = GetEsbConfigBufIndex(esbId);

	if (bufIndex < ESB_SUM_MAX)
	{
		/***** 自复式紧急停车按钮处理 *****/
		esbRelayId = GetEsbRelayId(esbId);
		esbRelayBelongCiId = GetRelayBelongCiId(esbRelayId);
		localCiId = GetSystemParaLocalCiId();
		if ((0U != esbRelayId) && (UINT16_MAX != esbRelayId) && (esbRelayBelongCiId == localCiId))
		{
			esbRelayCollState = GetRelayCollState(esbRelayId);  /*获取ESB继电器采集状态*/
			if (RELAY_STATE_DOWN == esbRelayCollState)
			{
				esbPressCycNum = GetEsbPressCycNum(esbId);
				if (0U == esbPressCycNum)
				{
					cycnow = Get2oo2CurCycleNum();
					SetEsbPressCycNum(esbId, cycnow);
				}
				else
				{
					/*已记录按钮按下周期，此处不记录*/
				}
			}
			else
			{
				SetEsbPressCycNum(esbId, 0U);
			}
			
			esbPressCycNum = GetEsbPressCycNum(esbId);
			zfsBtnRelayCollCycNum = GetSelfButCollCount();
			btnPressValidTime = SystemOverOrEqualTimeCheck(esbPressCycNum, zfsBtnRelayCollCycNum);
			esbErrorFlag = GetEsbErrFlag(esbId);
			if ((CI_TIME_OUT == btnPressValidTime) && (ESB_ERROR_FLAG_YES != esbErrorFlag))
			{
				/*按钮按下时间达到判断采集有效时间且未故障，设置紧急关闭有效*/
				(void)SetEsbState(esbId, ESB_STATE_VALID_YES);
			}
			else
			{
				/*不处理*/
			}

			zfsBtnRelayFaultCycNum = GetSelfButErrCount();
			btnPressFaultTime = SystemOverTimeCheck(esbPressCycNum, zfsBtnRelayFaultCycNum);
			if (CI_TIME_OUT == btnPressFaultTime)
			{
				SetEsbErrFlag(esbId, ESB_ERROR_FLAG_YES);
			}
			else
			{
				SetEsbErrFlag(esbId, ESB_ERROR_FLAG_NO);
			}
		}
		else
		{
			/*继电器ID错误/非本联锁，不处理*/
		}
	}
	else
	{
		/*索引错误，不处理*/
	}
}

/*
* 功能描述：自复式取消紧急停车按钮处理
* 参数说明：UINT16 esbId ESB ID
* 返回值  ：无
*/
void EsbZfsCancelBtnProc(UINT16 esbId)
{
	UINT16 wEsbIdIndex = 0U;    /*ESB数组下标*/
	UINT16 wRelayIdIndex = 0U;  /*继电器数组下标*/
	UINT16 cancelEsbRelayId = 0u;         /*取消esb继电器ID*/
	UINT8 localCiId = 0U;                 /*本地联锁ID*/
	UINT8 cancelEsbRelayBelongCiId = 0U;  /*取消esb采集继电器1所属CI*/
	UINT32 zfsBtnRelayCollCycNum = 0U;     /*自复式按钮继电器判断采集有效周期数*/
	UINT32 zfsBtnRelayFaultCycNum = 0U;    /*自复式按钮继电器判断故障周期数*/
	UINT32 zfsBtnRelayErrTriggerCycNum = 0U;    /*自复式按钮继电器判断误触发周期数*/
	UINT32 cancelEsbPressCycNum = 0U;      /*取消紧急关闭按钮按下周期*/
	UINT32 cancelEsbErrTriggerPressCycNum = 0U;      /*取消紧急关闭按钮误触发按下周期*/
	UINT8 cancelEsbValidFlag = ESB_CANCEL_VALID_NO;   /*取消紧急关闭按钮有效标志*/
	UINT8 btnPressValidTime = CI_TIME_NO;   /*按钮按下时间是否达到有效时间*/
	UINT8 btnPressFaultTime = CI_TIME_NO;   /*按钮按下时间是否达到故障时间*/
	UINT8 btnPressErrTriggerTime = CI_TIME_NO;   /*按钮按下时间是否达到误触发时间*/
	UINT8 esbErrorFlag = ESB_ERROR_FLAG_NO;

	wEsbIdIndex = GetEsbConfigBufIndex(esbId);

	if (wEsbIdIndex < ESB_SUM_MAX)
	{
		/***** 自复式取消紧急停车按钮处理 *****/
		cancelEsbRelayId = GetCancelEsbRelayId(esbId);
		wRelayIdIndex = GetRelayConfigBufIndex(cancelEsbRelayId);
		cancelEsbRelayBelongCiId = GetRelayBelongCiId(cancelEsbRelayId);
		localCiId = GetSystemParaLocalCiId();

		if ((wRelayIdIndex < RELAY_SUM_MAX) && (localCiId == cancelEsbRelayBelongCiId) && (0U != localCiId))
		{
			/***** 1.处理取消紧急关闭按钮正常/误触发按下周期和采集继电器落下状态 *****/
			EsbZfsCancelBtnPressStateProc(esbId, cancelEsbRelayId);

			/***** 2.处理取消紧急关闭按钮有效标志 *****/
			EsbZfsCancelBtnValidFlagProc(esbId, cancelEsbRelayId);			

			/***** 3.处理紧急状态及取消紧急关闭按钮有效标志 *****/
			cancelEsbValidFlag = GetCancelEsbValidFlag(esbId);
			cancelEsbPressCycNum = GetCancelEsbPressCycNum(esbId);
			zfsBtnRelayCollCycNum = GetSelfButCollCount();
			btnPressValidTime = SystemOverTimeCheck(cancelEsbPressCycNum, zfsBtnRelayCollCycNum);
			zfsBtnRelayFaultCycNum = GetSelfCancelButErrCount();
			btnPressFaultTime = SystemOverTimeCheck(cancelEsbPressCycNum, zfsBtnRelayFaultCycNum);
			esbErrorFlag = GetEsbErrFlag(esbId);

			if ((ESB_CANCEL_VALID_YES == cancelEsbValidFlag) && (CI_TIME_OUT == btnPressValidTime) && (CI_TIME_OUT != btnPressFaultTime))
			{
				/*取消紧急关闭按钮有效且按钮按下时间达到判断采集有效时间且未达到故障判断时间，设置紧急关闭无效，设置取消紧急关闭按钮无效*/
				(void)SetEsbState(esbId, ESB_STATE_VALID_NO);
				SetCancelEsbValidFlag(esbId, ESB_CANCEL_VALID_NO);
			}
			else if ((ESB_ERROR_FLAG_NO != esbErrorFlag) && ((CI_TIME_OUT != btnPressValidTime) || (CI_TIME_OUT == btnPressFaultTime)))
			{
				/*紧急关闭按钮故障且（取消紧急关闭按钮按下时间未生效或按钮正常按下故障），设置紧急关闭有效*/
				(void)SetEsbState(esbId, ESB_STATE_VALID_YES);
			}
			else
			{
				/*不处理*/
			}

			/***** 4.处理取消紧急关闭按钮故障标志 *****/
			cancelEsbErrTriggerPressCycNum = GetCancelEsbErrTrigPressCycNum(esbId);  /*获取取消按钮误触发按下周期*/
			zfsBtnRelayErrTriggerCycNum = GetSelfCancelButErrTriggerCount();  /*获取自复式取消按钮误触发判断时间*/
			btnPressErrTriggerTime = SystemOverTimeCheck(cancelEsbErrTriggerPressCycNum, zfsBtnRelayErrTriggerCycNum);

			if ((CI_TIME_OUT == btnPressFaultTime) || (CI_TIME_OUT == btnPressErrTriggerTime))
			{
				/*取消按钮正常按下时间达到故障判断时间或误触发按下时间达到误触发判断时间，设置取消紧急停车按钮故障标志*/
				SetCancelEsbErrFlag(esbId, ESB_ERROR_FLAG_YES);
			}
			else
			{
				SetCancelEsbErrFlag(esbId, ESB_ERROR_FLAG_NO);
			}
		}
		else
		{
			/*继电器ID错误/非本联锁，不处理*/
		}
	}
	else
	{
		/*索引错误，不处理*/
	}
}

/*
* 功能描述：自复式紧急停车按钮取消按钮按下状态处理
* 参数说明：const UINT16 wEsbId ESB ID
*           const UINT16 wCancelEsbRelayId  ESB取消按钮采集继电器ID
* 返回值  ：无
* Created By LQ 2024.05.09
*/
void EsbZfsCancelBtnPressStateProc(const UINT16 wEsbId, const UINT16 wCancelEsbRelayId)
{
	UINT16 wEsbIdIndex = 0U;  /*ESB数组下标*/
	UINT16 wRelayIdIndex = 0U;  /*继电器数组下标*/
	UINT8 cCancelRelayCollState = 0U;  /*取消esb按钮采集继电器状态*/
	UINT8 cEsbState = ESB_STATE_VALID_NO;  /*紧急关闭状态*/
	UINT8 cCancelEsbRelayDownState = ESB_RELAY_ERROR_DOWN_YES;  /*取消紧急关闭按钮继电器落下状态*/
	UINT32 dwCancelBtnPressCycNum = 0U;  /*取消紧急关闭按钮按下周期*/
	UINT32 dwCancelBtnErrTrigPressCycNum = 0U;  /*取消紧急关闭按钮误触发按下周期*/
	UINT32 dwCurCycNum = 0U;  /*当前周期*/
	UINT16 wRelayBelongOcId = 0U;  /*继电器所属OC*/
	UINT8 cOcCommState = TRANSMIT_STATE_BAD;  /*与OC通信状态*/
	UINT8 cABoardState = RELAY_BOARD_FAULT_YES;  /*A系板卡状态*/
	UINT8 cBBoardState = RELAY_BOARD_FAULT_YES;  /*B系板卡状态*/

	wEsbIdIndex = GetEsbConfigBufIndex(wEsbId);
	wRelayIdIndex = GetRelayConfigBufIndex(wCancelEsbRelayId);

	if ((wEsbIdIndex < ESB_SUM_MAX) && (wRelayIdIndex < RELAY_SUM_MAX))
	{		
		cCancelRelayCollState = GetRelayCollState(wCancelEsbRelayId);  /*获取取消扣车按钮继电器采集状态*/

		if (RELAY_STATE_UP == cCancelRelayCollState)
		{
			/** 继电器吸起，更新取消紧急关闭按钮正常/误触发按下周期 **/
			cEsbState = GetEsbState(wEsbId);  /*获取ESB状态*/
			cCancelEsbRelayDownState = GetCancelEsbRelayDownState(wEsbId);  /*获取取消按钮采集继电器落下状态*/
			dwCancelBtnPressCycNum = GetCancelEsbPressCycNum(wEsbId);  /*获取取消按钮正常按下周期*/
			dwCancelBtnErrTrigPressCycNum = GetCancelEsbErrTrigPressCycNum(wEsbId);  /*获取取消按钮误触发按下周期*/
			dwCurCycNum = Get2oo2CurCycleNum();

			if ((ESB_STATE_VALID_YES == cEsbState) && (ESB_RELAY_ERROR_DOWN_NO == cCancelEsbRelayDownState))
			{
				/*紧急有效且之前取消紧急关闭按钮采集继电器处于正常落下状态（与OC通信正常且板卡状态正常），更新取消紧急关闭按钮正常按下周期*/
				if ((0U == dwCancelBtnPressCycNum) && (0U == dwCancelBtnErrTrigPressCycNum))
				{
					SetCancelEsbPressCycNum(wEsbId, dwCurCycNum);  /*正常按下和误触发按下不同时存在*/
				}
				else
				{
					/*不处理*/
				}
			}
			else
			{
				/*紧急无效或之前取消紧急关闭按钮采集继电器未处于正常落下状态（与OC通信中断或双系板卡状态异常），更新取消紧急关闭按钮误触发按下周期*/
				if ((0U == dwCancelBtnPressCycNum) && (0U == dwCancelBtnErrTrigPressCycNum))
				{
					SetCancelEsbErrTrigPressCycNum(wEsbId, dwCurCycNum);  /*正常按下和误触发按下不同时存在*/
				}
				else
				{
					/*不处理*/
				}
			}
		}
		else
		{
			/** 继电器落下，更新取消紧急关闭按钮采集继电器落下状态 **/
			wRelayBelongOcId = GetRelayBelongOCId(wCancelEsbRelayId);
			cOcCommState = GetCiTransmitState(CI_SYSTEM_TYPE_OC, (UINT8)wRelayBelongOcId);  /*获取与OC通信状态*/
			cABoardState = GetRelayACollBoardState(wCancelEsbRelayId);  /*获取A系板卡状态*/
			cBBoardState = GetRelayBCollBoardState(wCancelEsbRelayId);  /*获取B系板卡状态*/

			if ((TRANSMIT_STATE_GOOD == cOcCommState) && ((RELAY_BOARD_FAULT_NO == cABoardState) || (RELAY_BOARD_FAULT_NO == cBBoardState)))
			{
				/*OC通信正常且有一系板卡状态正常，设置继电器正常落下*/
				SetCancelEsbRelayDownState(wEsbId, ESB_RELAY_ERROR_DOWN_NO);
			}
			else
			{
				/*OC通信异常或两系板卡状态均故障，设置继电器通信异常落下*/
				SetCancelEsbRelayDownState(wEsbId, ESB_RELAY_ERROR_DOWN_YES);
			}

			/** 继电器落下，清除取消紧急关闭按钮正常按下周期和误触发按下周期 **/
			SetCancelEsbPressCycNum(wEsbId, 0U);
			SetCancelEsbErrTrigPressCycNum(wEsbId, 0U);
		}
	}
	else
	{
		/*入参非法，不处理*/
	}
}

/*
* 功能描述：自复式紧急停车按钮取消按钮有效标志处理
* 参数说明：const UINT16 wEsbId ESB ID
*           const UINT16 wCancelEsbRelayId  ESB取消按钮采集继电器ID
* 返回值  ：无
* Created By LQ 2024.05.09
*/
void EsbZfsCancelBtnValidFlagProc(const UINT16 wEsbId, const UINT16 wCancelEsbRelayId)
{
	UINT16 wEsbIdIndex = 0U;  /*ESB数组下标*/
	UINT16 wRelayIdIndex = 0U;  /*继电器数组下标*/
	UINT8 cEsbState = ESB_STATE_VALID_NO;  /*紧急关闭状态*/
	UINT16 wEsbRelayId = 0U;  /*ESB采集继电器ID*/
	UINT8 cEsbRelayCollState = 0U;  /*ESB采集继电器状态*/
	UINT8 cEsbErrorFlag = ESB_ERROR_FLAG_NO;  /*ESB故障标志*/
	UINT8 cCancelEsbRelayCollState = 0U;  /*ESB取消按钮采集继电器状态*/
	UINT8 cCancelEsbRelayDownState = ESB_RELAY_ERROR_DOWN_YES;  /*ESB取消按钮继电器落下状态*/

	wEsbIdIndex = GetEsbConfigBufIndex(wEsbId);
	wRelayIdIndex = GetRelayConfigBufIndex(wCancelEsbRelayId);

	if ((wEsbIdIndex < ESB_SUM_MAX) && (wRelayIdIndex < RELAY_SUM_MAX))
	{
		cEsbState = GetEsbState(wEsbId);  /*获取ESB状态*/
		wEsbRelayId = GetEsbRelayId(wEsbId);
		cEsbRelayCollState = GetRelayCollState(wEsbRelayId);  /*获取ESB继电器采集状态*/
		cEsbErrorFlag = GetEsbErrFlag(wEsbId);  /*获取ESB按钮故障标志*/
		cCancelEsbRelayCollState = GetRelayCollState(wCancelEsbRelayId);  /*获取ESB取消按钮继电器采集状态*/
		cCancelEsbRelayDownState = GetCancelEsbRelayDownState(wEsbId);  /*获取ESB取消按钮采集继电器落下状态*/

		if ((ESB_STATE_VALID_YES == cEsbState) && ((RELAY_STATE_UP == cEsbRelayCollState) || (ESB_ERROR_FLAG_YES == cEsbErrorFlag))
			&& (RELAY_STATE_DOWN == cCancelEsbRelayCollState) && (ESB_RELAY_ERROR_DOWN_NO == cCancelEsbRelayDownState))
		{
			/*紧急关闭有效且(紧急关闭按钮采集继电器吸起或按钮故障)且取消紧急关闭按钮采集继电器落下且为正常落下，设置取消紧急关闭按钮有效*/
			SetCancelEsbValidFlag(wEsbId, ESB_CANCEL_VALID_YES);
		}
		else if (((RELAY_STATE_UP != cEsbRelayCollState) && (ESB_ERROR_FLAG_YES != cEsbErrorFlag)) || (ESB_RELAY_ERROR_DOWN_NO != cCancelEsbRelayDownState))
		{
			/*（紧急关闭按钮采集继电器未吸起且未故障）或取消按钮采集继电器落下状态非正常落下，设置取消紧急关闭按钮无效*/
			SetCancelEsbValidFlag(wEsbId, ESB_CANCEL_VALID_NO);
		}
		else
		{
			/*不处理*/
		}
	}
	else
	{
		/*入参非法，不处理*/
	}
}

/*
* 功能描述： 根据SPKS状态更新逻辑区段SPKS封锁状态
* 参数说明： 无
* 返回值  ： 无
* by cgh 20230919 逻辑区段封锁状态仅用于给ATS显示
*/
void SpksRelayToLogSecFlockStatus(void)
{
	UINT16 ii = 0U;
	UINT8 jj = 0U;
	UINT16 wLogSecCurSum = 0U;	 /* 逻辑区段总数目*/
	UINT16 wLogSecId = 0U;	 /* 逻辑区段ID*/
	UINT8 chLogSecSpksSum = 0U;/*逻辑区段关联SPKS数目*/
	UINT16 wLogSecSpksId = 0U;/*逻辑区段关联的SPKS ID*/
	UINT8 chSpksState = 0U;/*逻辑区段关联的SPKS状态*/
	UINT8 chSpksCutState = 0U;/*逻辑区段关联的SPKS旁路状态*/

	wLogSecCurSum = GetLogicSecCurSum();		/*获取逻辑区段总数*/

	/*处理逻辑区段*/
	for (ii = 0U; ii < wLogSecCurSum; ii++)
	{
		wLogSecId = 0U;	      /*逻辑区段ID*/
		wLogSecId = GetLogicSecId(ii);                      /*获取逻辑区段ID*/

		if ((0U != wLogSecId) && (wLogSecId < LOGIC_SECTION_SUM_MAX))
		{
			chLogSecSpksSum = GetLogSecSpksSum(wLogSecId);           /*获取所有逻辑区段关联的SPKS数目*/
			for (jj = 0U; jj < chLogSecSpksSum; jj++)
			{
				wLogSecSpksId = GetLogSecSpksIdBySpksIdx(wLogSecId, jj);
				if (0U < wLogSecSpksId)
				{
					chSpksState = GetSpksState(wLogSecSpksId);
					chSpksCutState = GetSpksCutState(wLogSecSpksId);
					if ((SPKS_STATUS_NO != chSpksState) && (SPKS_CUT_YES != chSpksCutState))
					{
						SetLogSecSpksFLockState(wLogSecId, LOGIC_SECTION_SPKS_FLOCK_YES);
						break;
					}
				}
			}

			/*此处即可判断处区段没有封锁 */
			if ((jj == chLogSecSpksSum) && (0u < jj))
			{
				SetLogSecSpksFLockState(wLogSecId, LOGIC_SECTION_SPKS_FLOCK_NO);
			}
			else
			{
				/*无操作*/
			}
		}
	}
}

/*
* 功能描述： 屏蔽门再开/关门按钮指示灯处理
* 参数说明： const UINT16 psdId, 屏蔽门ID
* 返回值  ： 无
* 成都13、27、30新需求——2023.09.21
*/
void PsdOpenAndCloseBsdProc(const UINT16 psdId)
{
	UINT16 wPcbBsdRelayId = 0U;  /*PCB按钮表示灯继电器*/
	UINT16 wPobBsdRelayId = 0U;  /*POB按钮表示灯继电器*/
	UINT32 dwBtnPressInvalidCycNum = 0U;  /*按钮按下超限失效周期数*/
	UINT32 dwPcbPressStartCycNum = 0U;  /*PCB按下起始周期*/
	UINT32 dwPobPressStartCycNum = 0U;  /*POB按下起始周期*/
	UINT8 cPcbstate = 0U;  /*PCB状态*/
	UINT8 cPobstate = 0U;  /*POB状态*/
	UINT8 cBtnPressTimeCheck = 0U;

	if ((0U != psdId) && (PSD_SUM_MAX != psdId))
	{
		dwBtnPressInvalidCycNum = GetPsdButtonPressCount();  /*获取PSD按钮按下超限失效周期数*/

		/*处理再关门按钮指示灯*/
		wPcbBsdRelayId = GetPsdPcbRelayId(psdId);
		if ((0U != wPcbBsdRelayId) && (RELAY_SUM_MAX != wPcbBsdRelayId))
		{
			dwPcbPressStartCycNum = GetPCBPressCycNum(psdId);
			cBtnPressTimeCheck = SystemOverTimeCheck(dwPcbPressStartCycNum, dwBtnPressInvalidCycNum);
			cPcbstate = GetPsdButtonState(psdId);

			if (CI_TIME_OUT == cBtnPressTimeCheck)
			{
				(void)SetRelayDriveState(wPcbBsdRelayId, RELAY_DRIVE_STATE_DOWN);  /*按下超时，驱动指示灯灭灯*/
			}
			else
			{
				if (PSD_BUTTON_STATE_UP == cPcbstate)
				{
					(void)SetRelayDriveState(wPcbBsdRelayId, RELAY_DRIVE_STATE_DOWN);  /*未按下未超时，驱动指示灯灭灯*/
				}
				else if (PSD_BUTTON_STATE_DOWN == cPcbstate)
				{
					(void)SetRelayDriveState(wPcbBsdRelayId, RELAY_DRIVE_STATE_UP);  /*按下未超时，驱动指示灯亮灯*/
				}
				else
				{
					/*不处理*/
				}
			}

		}
		else
		{
			/*未配置表示灯继电器，不处理*/
		}
		
		/*处理再开门按钮指示灯*/
		wPobBsdRelayId = GetPsdPobBsdRelayId(psdId);
		if ((0U != wPobBsdRelayId) && (RELAY_SUM_MAX != wPobBsdRelayId))
		{
			dwPobPressStartCycNum = GetPOBPressCycNum(psdId);			
			cBtnPressTimeCheck = SystemOverTimeCheck(dwPobPressStartCycNum, dwBtnPressInvalidCycNum);
			cPobstate = GetPsdOpenButtonState(psdId);

			if (CI_TIME_OUT == cBtnPressTimeCheck)
			{
				(void)SetRelayDriveState(wPobBsdRelayId, RELAY_DRIVE_STATE_DOWN);  /*按下超时，驱动指示灯灭灯*/
			}
			else
			{
				if (PSD_OPEN_BUTTON_STATE_INVALID == cPobstate)
				{
					(void)SetRelayDriveState(wPobBsdRelayId, RELAY_DRIVE_STATE_DOWN);  /*未按下未超时，驱动指示灯灭灯*/
				}
				else if (PSD_OPEN_BUTTON_STATE_VALID == cPobstate)
				{
					(void)SetRelayDriveState(wPobBsdRelayId, RELAY_DRIVE_STATE_UP);  /*按下未超时，驱动指示灯亮灯*/
				}
				else
				{
					/*不处理*/
				}
			}
		}
		else
		{
			/*未配置表示灯继电器，不处理*/
		}	
	}
	else
	{
		/*入参非法，不处理*/
	}
}

/*
* 功能描述： 检查继电器是否驱动超时-带超时时间参数
* 参数说明： const UINT16 relayId 继电器ID
*					const UINT32 dwTimeOutCycCount   最大时间 
* 返回值  ： 1：不是驱动超时状态
*            0：驱动超时
* by cgh 20230923
*/
UINT8 CheckRelayDriveOutTime(const UINT16 wRelayId, const UINT32 dwTimeOutCycCount)
{
	UINT8 chRelayColleState = 0U;/*继电器采集状态*/
	UINT8 chrelayDriveState = 0U;/*继电器驱动状态*/
	UINT8 chRetValue = CI_ERROR;
	UINT32 dwCurCycNum = 0U;/*系统当前周期数*/
	UINT8 checkRelayRes = 0U;/*继电器超时检查结果*/
	UINT32 dwRelayCycNum = 0U;/*继电器驱动起始周期数*/

	if ((0U != wRelayId) && (RELAY_SUM_MAX != wRelayId))
	{
		chRetValue = CI_SUCCESS;
		dwCurCycNum = Get2oo2CurCycleNum();
		/*获取继电器状态*/
		chRelayColleState = GetRelayCollState(wRelayId); /*采集状态*/
		chrelayDriveState = GetRelayDriveState(wRelayId); /*驱动状态*/

		/*驱动是吸起*/
		if (RELAY_DRIVE_STATE_UP == chrelayDriveState)
		{
			/*采集落下*/
			if (RELAY_STATE_DOWN == chRelayColleState)
			{
				dwRelayCycNum = GetRelayDriveStartCycNum(wRelayId);
				checkRelayRes = SystemOverTimeCheck(dwRelayCycNum, dwTimeOutCycCount);
				/*未计时*/
				if (CI_TIME_NO == checkRelayRes)
				{
					SetRelayDriveStartCycNum(wRelayId, dwCurCycNum);/*设置继电器有效周期*/
				}
				/*超时*/
				else if (CI_TIME_OUT == checkRelayRes)
				{
					chRetValue = CI_ERROR;
				}
				else
				{
					/*计时中，返回成功*/
				}
			}
			else
			{
				SetRelayDriveStartCycNum(wRelayId, 0U);/*设置继电器有效周期*/
			}
		}
		else if ((RELAY_DRIVE_STATE_DOWN == chrelayDriveState) || (RELAY_DRIVE_STATE_NULL == chrelayDriveState))
		{
			/*采集吸起*/
			if (RELAY_STATE_UP == chRelayColleState)
			{
				dwRelayCycNum = GetRelayDriveStartCycNum(wRelayId);
				checkRelayRes = SystemOverTimeCheck(dwRelayCycNum, dwTimeOutCycCount);
				/*未计时*/
				if (CI_TIME_NO == checkRelayRes)
				{
					SetRelayDriveStartCycNum(wRelayId, dwCurCycNum);/*设置继电器有效周期*/
				}
				/*超时*/
				else if (CI_TIME_OUT == checkRelayRes)
				{
					chRetValue = CI_ERROR;
				}
				else
				{
					/*计时中，返回成功*/
				}
			}
			else
			{
				SetRelayDriveStartCycNum(wRelayId, 0U);/*设置继电器有效周期*/
			}
		}
		else
		{
			SetRelayDriveStartCycNum(wRelayId, 0U);/*设置继电器有效周期*/
		}
	}
	else
	{
		; /*继电器ID不合法*/
	}


	return chRetValue;
}

/******************************声光报警器输出处理****************************/
/*
* 功能描述： 声光报警器输出处理
* 参数说明： void
* 返回值  ： void
* 成都三线新需求：声光报警器——2023.09.23 by LQ
*/
void SGBJDriveOutputProc(void)
{
	UINT16 ii = 0U;
	UINT16 jj = 0U;
	UINT16 wSGBJCurSum = 0U;  /*声光报警器总数*/
	UINT16 wSGBJId = 0U;  /*声光报警器ID*/
	UINT16 wSGBJRelRelayId = 0U;  /*声光报警器关联继电器ID1*/
	UINT16 wSGBJRelRelayId_2 = 0U;  /*声光报警器关联继电器ID2*/
	UINT16 wSGBJRelRouteNum = 0U;  /*声光报警器关联进路数量*/
	UINT16 wSGBJRelRouteId = 0U;  /*声光报警器关联进路ID*/
	UINT16* pSGBJRelRouteIdBuf = NULL;  /*声光报警器关联进路结构体*/
	UINT8 cRouteState = 0U;  /*声光报警器关联进路状态*/
	UINT8 cLocalCiId = 0U;  /*本地联锁ID*/
	UINT8 cSGBJBlongCiId = 0U;  /*声光报警器所属联锁ID*/
	UINT8 cRouteDrvSGBJFlag = ROUTE_DRIVE_SGBJ_INVALID;  /*进路需驱动声光报警标志*/
	UINT8 cSGBJNeedDriveFlag = FLAG_UNSET;  /*声光报警器需被驱动标志*/

	wSGBJCurSum = GetSGBJCurSum();     /*获取spks数量，默认为每个spks都有对应的指示灯*/
	cLocalCiId = GetSystemParaLocalCiId(); /*获取本地联锁ID*/

	for (ii = 0U; ii < wSGBJCurSum; ii++)
	{
		cSGBJNeedDriveFlag = FLAG_UNSET;  /*每进一次清一次标志*/
		wSGBJId = GetSGBJIdByIndex(ii);
		cSGBJBlongCiId = GetSGBJBelongCiId(wSGBJId);
		wSGBJRelRelayId = GetSGBJRelayId(wSGBJId);
		wSGBJRelRelayId_2 = GetSGBJRelayId_2(wSGBJId);

		if ((0U != cLocalCiId) && (cLocalCiId == cSGBJBlongCiId)
			&& (0U != wSGBJRelRelayId) && (RELAY_SUM_MAX != wSGBJRelRelayId)
			&& (0U != wSGBJRelRelayId_2) && (RELAY_SUM_MAX != wSGBJRelRelayId_2))
		{
			/*处理本控区内的声光报警器*/
			wSGBJRelRouteNum = GetSGBJRelRouteNum(wSGBJId);
			pSGBJRelRouteIdBuf = GetSGBJRelRouteIdBuf(wSGBJId);

			/*遍历所有关联进路，确定是否存在进路需驱动声光报警器*/
			for (jj = 0U; jj < wSGBJRelRouteNum; jj++)
			{
				wSGBJRelRouteId = pSGBJRelRouteIdBuf[jj];
				cRouteState = GetRouteState(wSGBJRelRouteId);

				if ((ROUTE_STATE_FIRST_LOCK == cRouteState) || (ROUTE_STATE_FIRST_LOCKERR == cRouteState)
					|| (ROUTE_STATE_YUXIAN_LOCK == cRouteState) || (ROUTE_STATE_YUXIAN_OPEN == cRouteState)
					|| (ROUTE_STATE_NEAR_LOCK == cRouteState) || (ROUTE_STATE_NEAR_LOCKERR == cRouteState) || (ROUTE_STATE_NEAR_OPEN == cRouteState)
					 || (ROUTE_STATE_LEAD_LOCK == cRouteState) || (ROUTE_STATE_LEAD_LOCKERR == cRouteState) || (ROUTE_STATE_LEAD_OPEN == cRouteState)
					|| (ROUTE_STATE_AUTO_UNLOCK == cRouteState) || (ROUTE_STATE_AUTO_UNLOCKERR == cRouteState) || (ROUTE_STATE_DELAY_UNLOCK == cRouteState))
				{
					/*进路处于锁闭过程中且未解锁，校验进路是否需要驱动声光报警器*/
					RouteNeedDriveSGBJCheck(wSGBJRelRouteId);  /*校验进路是否需要驱动声光报警器*/
					cRouteDrvSGBJFlag = GetRouteDriveSGBJFlag(wSGBJRelRouteId);
					
					if (ROUTE_DRIVE_SGBJ_VALID == cRouteDrvSGBJFlag)
					{
						cSGBJNeedDriveFlag = FLAG_SET;  /*存在进路需驱动声光报警器，停止遍历*/
						break;
					}
					else
					{
						/*继续遍历*/
					}
				}
				else 
				{
					cSGBJNeedDriveFlag = FLAG_UNSET;  /*进路未锁闭或在解锁中，不再驱动声光报警器*/
				}
			}

			if (FLAG_SET == cSGBJNeedDriveFlag)
			{
				(void)SetRelayDriveState(wSGBJRelRelayId, RELAY_DRIVE_STATE_UP);
				(void)SetRelayDriveState(wSGBJRelRelayId_2, RELAY_DRIVE_STATE_UP);
			}
			else
			{
				(void)SetRelayDriveState(wSGBJRelRelayId, RELAY_DRIVE_STATE_DOWN);
				(void)SetRelayDriveState(wSGBJRelRelayId_2, RELAY_DRIVE_STATE_DOWN);
			}
		}
		else
		{
			/*非本控区或无声光报警器继电器，不处理*/
		}
	}
}


/*
* 功能描述： 设置继电器驱动起始周期
* 参数说明： const UINT16 relayId 继电器ID
* 返回值  ： 无
* by cgh 20230930
*/
void SetRelayDriveStartCyc(const UINT16 wRelayId)
{
	UINT8 chRelayColleState = 0U;/*继电器采集状态*/
	UINT8 chrelayDriveState = 0U;/*继电器驱动状态*/
	UINT32 dwCurCycNum = 0U;/*系统当前周期数*/
	UINT32 dwRelayCycNum = 0U;/*继电器驱动起始周期数*/

	if ((0U != wRelayId) && (RELAY_SUM_MAX != wRelayId))
	{
		dwCurCycNum = Get2oo2CurCycleNum();
		/*获取继电器状态*/
		chRelayColleState = GetRelayCollState(wRelayId); /*采集状态*/
		chrelayDriveState = GetRelayDriveState(wRelayId); /*驱动状态*/

		/*驱动是吸起*/
		if (RELAY_DRIVE_STATE_UP == chrelayDriveState)
		{
			/*采集落下*/
			if (RELAY_STATE_DOWN == chRelayColleState)
			{
				dwRelayCycNum = GetRelayDriveStartCycNum(wRelayId);
				if (0U == dwRelayCycNum)
				{
					SetRelayDriveStartCycNum(wRelayId, dwCurCycNum);/*设置继电器有效周期*/
				}
				else
				{
					;/*周期数有效，不改变*/
				}
			}
			else
			{
				SetRelayDriveStartCycNum(wRelayId, 0U);/*设置继电器有效周期*/
			}
		}
		else if ((RELAY_DRIVE_STATE_DOWN == chrelayDriveState) || (RELAY_DRIVE_STATE_NULL == chrelayDriveState))
		{
			/*采集吸起*/
			if (RELAY_STATE_UP == chRelayColleState)
			{
				dwRelayCycNum = GetRelayDriveStartCycNum(wRelayId);
				if (0U == dwRelayCycNum)
				{
					SetRelayDriveStartCycNum(wRelayId, dwCurCycNum);/*设置继电器有效周期*/
				}
				else
				{
					;/*周期数有效，不改变*/
				}
				
			}
			else
			{
				SetRelayDriveStartCycNum(wRelayId, 0U);/*设置继电器有效周期*/
			}
		}
		else
		{
			SetRelayDriveStartCycNum(wRelayId, 0U);/*设置继电器有效周期*/
		}
	}
	else
	{
		; /*继电器ID不合法*/
	}
}

/*
* 功能描述： 设置所有道岔单独位置
* 参数说明： UINT16 switchCurSum 道岔总数
* 返回值  ： 无
*/
void SetAllSingleSwitchCurPosition(UINT16 switchCurSum)
{
	UINT8 localCiId = 0U;         /*本地联锁ID*/
	UINT16 switchId = 0U;	     /*道岔ID*/
	UINT8 belongCiId = 0U;        /*道岔所属联锁ID*/
	UINT16 ii = 0U;               /*循环索引*/
	UINT8 chSwitchColPos = SWITCH_POSITION_INVALID;		/*道岔当前位置*/
	UINT8 chSwitchTolPos = SWITCH_POSITION_INVALID;		/*道岔容忍后位置*/
	localCiId = GetSystemParaLocalCiId();       		/*获取本机联锁ID*/
	for (ii = 0U; ii < switchCurSum; ii++)
	{
		switchId = 0U;	      /*道岔ID*/
		belongCiId = 0U;       /*道岔所属联锁ID*/

		switchId = GetSwitchId(ii);                      /*获取道岔ID*/

		if ((0U != switchId) && (SWITCH_SUM_MAX > switchId))
		{
			belongCiId = GetSwitchBelongCiId(switchId); 	 /*获取道岔所属联锁ID*/

			if ((belongCiId == localCiId) && (0U != localCiId))
			{
				chSwitchColPos = GetOcSwitchState(switchId);
				SetSwitchCollPos(switchId, chSwitchColPos);
				chSwitchTolPos = GetSwitchCollToleratePos(switchId);
				SetSingleSwitchCurPosition(switchId, chSwitchTolPos);/*设置道岔单独位置*/
			}
		}
	}
}

/*
* 功能描述： 设置道岔当前逻辑位置
* 参数说明： UINT16 switchCurSum 道岔总数
* 返回值  ： 无
*/
void UpdataSwitchCurPostion(UINT16 switchCurSum)
{
	UINT8 localCiId = 0U;         /*本地联锁ID*/
	UINT16 switchId = 0U;	     /*道岔ID*/
	UINT8 singleSwitchPos = 0U;		/*道岔单独位置*/
	UINT8 belongCiId = 0U;        /*道岔所属联锁ID*/
	UINT16 ii = 0U;               /*循环索引*/
	UINT16 switch2ndId = 0U;
	UINT8 singleSwitch2ndPos = 0U;	/*双动道岔单独位置*/

	localCiId = GetSystemParaLocalCiId();       		/*获取本机联锁ID*/
	for (ii = 0U; ii < switchCurSum; ii++)
	{
		switchId = GetSwitchId(ii);                      /*获取道岔ID*/
		if ((0U != switchId) && (SWITCH_SUM_MAX > switchId))
		{
			belongCiId = GetSwitchBelongCiId(switchId); 	 /*获取道岔所属联锁ID*/
			if ((belongCiId == localCiId) && (0U != localCiId))
			{
				switch2ndId = GetDSwitchOtherId(switchId);
				singleSwitchPos = GetSingleSwitchCurPosition(switchId);
				if (0U == switch2ndId)
				{/*单动道岔，单独位置就代表当前位置*/
					SetSwitchCurPosition(switchId, singleSwitchPos);
				}
				else
				{/*道岔是双动道岔，则需要两个道岔位置都满足，道岔才有正确位置，任意一个不满足则四开*/
					singleSwitch2ndPos = GetSingleSwitchCurPosition(switch2ndId);
					switch (singleSwitchPos)
					{
					case SWITCH_POSITION_DINGWEI:				/*道岔当前定位*/
						if (SWITCH_POSITION_DINGWEI == singleSwitch2ndPos)
						{/*另一双动道岔当前定位*/
							SetSwitchCurPosition(switchId, SWITCH_POSITION_DINGWEI);		/*都定位，设置道岔逻辑位置为定位*/
						}
						else if (SWITCH_POSITION_MOVE == singleSwitch2ndPos)
						{
							SetSwitchCurPosition(switchId, SWITCH_POSITION_MOVE);
						}
						else if (SWITCH_POSITION_JICHA == singleSwitch2ndPos)
						{
							SetSwitchCurPosition(switchId, SWITCH_POSITION_JICHA);
						}
						else
						{
							SetSwitchCurPosition(switchId, SWITCH_POSITION_SIKAI);
						}
						break;
					case SWITCH_POSITION_FANWEI:				/*道岔当前反位*/
						if (SWITCH_POSITION_FANWEI == singleSwitch2ndPos)
						{/*另一双动道岔当前反位*/
							SetSwitchCurPosition(switchId, SWITCH_POSITION_FANWEI);		/*都定位，设置道岔逻辑位置为反位*/
						}
						else if (SWITCH_POSITION_MOVE == singleSwitch2ndPos)
						{
							SetSwitchCurPosition(switchId, SWITCH_POSITION_MOVE);
						}
						else if (SWITCH_POSITION_JICHA == singleSwitch2ndPos)
						{
							SetSwitchCurPosition(switchId, SWITCH_POSITION_JICHA);
						}
						else
						{
							SetSwitchCurPosition(switchId, SWITCH_POSITION_SIKAI);
						}
						break;
					case SWITCH_POSITION_MOVE:					/*道岔当前移动中*/
						if ((SWITCH_POSITION_DINGWEI == singleSwitch2ndPos) || (SWITCH_POSITION_FANWEI == singleSwitch2ndPos) || (SWITCH_POSITION_MOVE == singleSwitch2ndPos))
						{
							SetSwitchCurPosition(switchId, SWITCH_POSITION_MOVE);
						}
						else if (SWITCH_POSITION_JICHA == singleSwitch2ndPos)
						{
							SetSwitchCurPosition(switchId, SWITCH_POSITION_JICHA);
						}
						else
						{
							SetSwitchCurPosition(switchId, SWITCH_POSITION_SIKAI);
						}
						break;
					case SWITCH_POSITION_SIKAI:					/*道岔当前四开*/
						if (SWITCH_POSITION_JICHA == singleSwitch2ndPos)
						{
							SetSwitchCurPosition(switchId, SWITCH_POSITION_JICHA);
						}
						else
						{
							SetSwitchCurPosition(switchId, SWITCH_POSITION_SIKAI);
						}
						break;
					case SWITCH_POSITION_JICHA:
						SetSwitchCurPosition(switchId, SWITCH_POSITION_JICHA);
						break;
					default:
						SetSwitchCurPosition(switchId, SWITCH_POSITION_SIKAI);
						break;
					}
				}
			}
		}
	}
}

/*
* 功能描述： 根据道岔当前逻辑位置选择清理相关内容
* 参数说明： UINT16 switchCurSum 道岔总数
* 返回值  ： 无
*/
void ClearSwitchMessageByCurPostion(UINT16 switchCurSum)
{
	UINT8 localCiId = 0U;         /*本地联锁ID*/
	UINT16 switchId = 0U;	     /*道岔ID*/
	UINT8 belongCiId = 0U;        /*道岔所属联锁ID*/
	UINT16 ii = 0U;               /*循环索引*/
	UINT8 curSwitchPos = SWITCH_POSITION_INVALID;		/*道岔当前位置*/
	UINT8 drvSwitchPos = SWITCH_DRIVE_POS_INVALID;	/*当前驱动道岔位置*/
	UINT8 SwitchDanCaoPos = SWITCH_POSITION_INVALID;	/*道岔单操位置*/

	UINT8 timeState = CI_TIME_NO;						/*驱动道岔超时状态*/
	localCiId = GetSystemParaLocalCiId();       		/*获取本机联锁ID*/
	for (ii = 0U; ii < switchCurSum; ii++)
	{
		switchId = 0U;	      /*道岔ID*/
		belongCiId = 0U;       /*道岔所属联锁ID*/

		switchId = GetSwitchId(ii);                      /*获取道岔ID*/
		if ((0U != switchId) && (SWITCH_SUM_MAX > switchId))
		{
			belongCiId = GetSwitchBelongCiId(switchId); 	 /*获取道岔所属联锁ID*/
			if ((belongCiId == localCiId) && (0U != localCiId))
			{
				/*检查驱动道岔时间是否已经超时*/
				timeState = SystemOverTimeCheck(GetSwitchDriveStartCycNum(switchId), GetSystemParaSwitchDriveCyc());

				if (CI_TIME_OUT == timeState)
				{/*驱动道岔时间超时*/

					/*获得当前道岔驱动位置*/
					drvSwitchPos = GetSwitchDrivePostion(switchId);

					/*获取道岔单操位置*/
					SwitchDanCaoPos = GetSwitchDanCaoPostition(switchId);

					if (((SWITCH_DRIVE_POS_DINGWEI == drvSwitchPos) && (SWITCH_POSITION_DINGWEI == SwitchDanCaoPos)) ||
						((SWITCH_DRIVE_POS_FANWEI == drvSwitchPos) && (SWITCH_POSITION_FANWEI == SwitchDanCaoPos)))
					{
						/*清除单操有效位置*/
						(void)SetSwitchDanCaoPosition(switchId, SWITCH_POSITION_INVALID);
					}

					/*设置道岔驱动超时位置*/
					SetSwitchDrivOvtmDrvPosition(switchId, drvSwitchPos);
					SetSwitchPreExpDrvPosition(switchId, SWITCH_DRIVE_POS_INVALID);/*清除道岔之前期望驱动位置*/
					SetSwitchDrivePostion(switchId, SWITCH_DRIVE_POS_INVALID);/*清除道岔实际驱动位置*/
				}

				/*以下一段代码是为了检查单操道岔是否已驱动到位*/

				/*再次获取道岔单操位置*/
				SwitchDanCaoPos = GetSwitchDanCaoPostition(switchId);

				/*获取道岔当前位置*/
				curSwitchPos = GetSwitchCurPosition(switchId);

				if ((SwitchDanCaoPos == curSwitchPos) && (SWITCH_POSITION_INVALID != SwitchDanCaoPos))
				{/*道岔驱动到位*/
					/*清除单操有效位置*/
					(void)SetSwitchDanCaoPosition(switchId, SWITCH_POSITION_INVALID);
				}
			}
		}
	}
}

/*
* 功能描述： 洗车机工作模式继电器状态处理
* 参数说明： const UINT16 washMachineId 洗车机ID
* 返回值  ： 0u: 更新失败
*			 1: 更新成功
* by cgh 20231108
*/
UINT8 WashMachineWorkModeRelayProc(const UINT16 washMachineId)
{
	UINT8 chReval = CI_ERROR;
	UINT8 chWashMachineWorkModeDrvState = WASHMACHINE_WORKMODE_INVALID_DRV;/*洗车机工作模式设置驱动状态*/
	UINT16 washWorkModeBackRelayId = 0U;/*洗车机工作模式反馈采集继电器*/
	UINT16 washWorkModeRelayId = 0U;/*洗车机工作模式驱动继电器*/
	UINT8 chwashModeRelayColl = 0U;/*洗车机工作模式继电器采集状态*/
	UINT32 dwRelayDriveStartCyc = 0U;/*继电器驱动起始周期*/
	UINT8 chRelayDriveOutTiomeCheck = 0U;/*继电器驱动超时检查*/

	if ((0U < washMachineId) && (WASHMACHINE_SUM_MAX > washMachineId))
	{
		/*先将洗车机工作模式反馈设置为默认*/
		SetWashWorkModeBackState(washMachineId, WASH_WORKMODE_BACK_DEFAULT);
		washWorkModeBackRelayId = GetWashModeBackRelayId(washMachineId);
		washWorkModeRelayId = GetWashModeRelayId(washMachineId);

		if ((0U != washWorkModeBackRelayId) && (0U != washWorkModeRelayId))
		{
			chWashMachineWorkModeDrvState = GetWashMachineWorkModeDrvState(washMachineId);
			chwashModeRelayColl = GetRelayCollState(washWorkModeBackRelayId);
			
			if (WASHMACHINE_WORKMODE_ALL_DRV == chWashMachineWorkModeDrvState)
			{
				/*全洗设置洗车模式继电器驱动吸起*/
				chReval = SetRelayDriveState(washWorkModeRelayId, RELAY_DRIVE_STATE_UP);
				if (RELAY_STATE_UP == chwashModeRelayColl)
				{
					/*当前采集和驱动的状态一致，反馈对应模式设置成功*/
					SetWashWorkModeBackState(washMachineId,WASH_WORKMODE_BACK_ALL_OK);
				}
				else
				{
					; /*不设置状态*/
				}
				/*如果驱动采集一致，在此函数设置的周期号为0，否则设置有效*/
				SetWorkModeRelayDriveStartCyc(washMachineId);
			}
			else if (WASHMACHINE_WORKMODE_SIDE_DRV == chWashMachineWorkModeDrvState)
			{
				/*侧洗设置洗车模式继电器驱动落下*/
				chReval = SetRelayDriveState(washWorkModeRelayId, RELAY_DRIVE_STATE_DOWN);
				if (RELAY_STATE_DOWN == chwashModeRelayColl)
				{
					/*当前采集和驱动的状态一致，反馈对应模式设置成功*/
					SetWashWorkModeBackState(washMachineId, WASH_WORKMODE_BACK_SIDE_OK);
				}
				else
				{
					; /*不设置状态*/
				}
				/*如果驱动采集一致，在此函数设置的周期号为0，否则设置有效*/
				SetWorkModeRelayDriveStartCyc(washMachineId);
			}
			else if (WASHMACHINE_WORKMODE_DEFAULT_DRV == chWashMachineWorkModeDrvState)
			{
				/*默认设置洗车模式继电器驱动为当前采集状态*/
				chReval = SetRelayDriveState(washWorkModeRelayId, chwashModeRelayColl);
				/*不需要进行超时判断，一旦出现周期号清0*/
				SetWashWorkModeRelayDrvCycle(washMachineId, 0U);
			}
			else
			{
				/*洗车请求无效，CI转回内部默认状态（低电平有效）*/
				chReval = SetRelayDriveState(washWorkModeRelayId, RELAY_DRIVE_STATE_DOWN);
				/*不需要进行超时判断，一旦出现周期号清0*/
				SetWashWorkModeRelayDrvCycle(washMachineId, 0U);
			}

			dwRelayDriveStartCyc = GetWashWorkModeRelayDrvCycle(washMachineId);
			/*检查洗车模式继电器是否驱动超时*/
			chRelayDriveOutTiomeCheck = SystemOverTimeCheck(dwRelayDriveStartCyc,RELAY_DRIVE_MAX_NUM);
			if ((CI_TIME_NO == chRelayDriveOutTiomeCheck) || (CI_TIME_IN == chRelayDriveOutTiomeCheck))
			{
				/*未计时，说明前面已经驱动采集一致，对应工作模式反馈已经设置过，这里不重复设置*/
				/*计时中，说明当前采集驱动还暂时一致，设置对应工作模式反馈为OXOO*/
			}
			else
			{
				/*超时，需要设置对应工作模式设置失败反馈*/
				if (WASHMACHINE_WORKMODE_ALL_DRV == chWashMachineWorkModeDrvState)
				{
					SetWashWorkModeBackState(washMachineId, WASH_WORKMODE_BACK_ALL_NO);
				}
				else if (WASHMACHINE_WORKMODE_SIDE_DRV == chWashMachineWorkModeDrvState)
				{
					SetWashWorkModeBackState(washMachineId, WASH_WORKMODE_BACK_SIDE_NO);
				}
				else
				{
					; /*其他模式不反馈设置失败*/
				}
			}
		}
		else
		{
			/*没有继电器继续执行，设置洗车机工作模式反馈为0X00*/
			chReval = CI_SUCCESS;
		}
	}
	else
	{
		; /*返回失败*/
	}

	return chReval;
}

/*
* 功能描述： 更新降级模式洗车继电器状态
* 参数说明： const UINT16 washMachineId 洗车机ID
* 返回值  ： CI_ERROR: 更新失败
*			 CI_SUCCESS: 更新成功
* by cgh 20231113
*/
UINT8 DownWashDevToRelayStaProc(const UINT16 washMachineId)
{
	UINT8 chReval = CI_ERROR;
	UINT16 wDownWashAllowLightRelayId = 0U;/*降级洗车同意指示灯继电器ID*/
	UINT8 chDownWashAllowState = 0U;/*降级洗车同意状态*/
	UINT16 wDownWashRelateRouteId = 0U;/*降级模式洗车线控制台表示灯关联进路ID*/
	UINT8 chDownWashRelRoute1CheckType = 0U;/*降级模式洗车线控制台表示灯关联进路状态检查类型*/
	UINT16 wDownWashControlLightRelayId = 0U;/*降级模式洗车线控制台表示灯继电器ID*/
	UINT8 chDownWashRelRouteCheckResult = 0U;/*降级模式关联进路状态检查结果*/

	if ((0U < washMachineId) && (WASHMACHINE_SUM_MAX > washMachineId))
	{
		chReval = CI_SUCCESS;

		wDownWashAllowLightRelayId = GetDownWashAllowLightRelayId(washMachineId);

		if (0U != wDownWashAllowLightRelayId)
		{
			chDownWashAllowState = GetDownWashAllowState(washMachineId);
			if (WASH_COL_STATE_ALLOW_YES == chDownWashAllowState)
			{
				/*降级模式洗车同意按钮按下，驱动降级洗车同意指示灯继电器吸起*/
				chReval = SetRelayDriveState(wDownWashAllowLightRelayId, RELAY_DRIVE_STATE_UP);
			}
			else
			{
				/*降级模式洗车同意按钮按下，驱动降级洗车同意指示灯继电器落下*/
				chReval = SetRelayDriveState(wDownWashAllowLightRelayId, RELAY_DRIVE_STATE_DOWN);
			}
		}
		else
		{
			; /*无继电器不处理*/
		}
		
		if (CI_SUCCESS == chReval)
		{
			/*驱动降级模式洗车线控制台表示灯1继电器*/
			wDownWashControlLightRelayId = GetDownWashRelRoute1LightRelay(washMachineId);

			if (0U != wDownWashControlLightRelayId)
			{
				wDownWashRelateRouteId = GetDownWashRelateRoute1Id(washMachineId);
				chDownWashRelRoute1CheckType = GetDownWashRelRoute1CheckType(washMachineId);
				chDownWashRelRouteCheckResult = DownWashRelRouteStateCheck(wDownWashRelateRouteId, chDownWashRelRoute1CheckType);
				
				if (CI_SUCCESS == chDownWashRelRouteCheckResult)
				{
					/*降级模式洗车线控制台表示灯1关联进路检查类型检查通过，驱动指示灯继电器吸起*/
					chReval = SetRelayDriveState(wDownWashControlLightRelayId, RELAY_DRIVE_STATE_UP);
				}
				else
				{
					chReval = SetRelayDriveState(wDownWashControlLightRelayId, RELAY_DRIVE_STATE_DOWN);
				}
			}
			else
			{
				; /*无继电器不处理*/
			}
		}
		else
		{
			; /*不处理*/
		}

		if (CI_SUCCESS == chReval)
		{
			/*驱动降级模式洗车线控制台表示灯2继电器*/
			wDownWashControlLightRelayId = GetDownWashRelRoute2LightRelay(washMachineId);

			if (0U != wDownWashControlLightRelayId)
			{
				wDownWashRelateRouteId = GetDownWashRelateRoute2Id(washMachineId);
				chDownWashRelRoute1CheckType = GetDownWashRelRoute2CheckType(washMachineId);
				chDownWashRelRouteCheckResult = DownWashRelRouteStateCheck(wDownWashRelateRouteId, chDownWashRelRoute1CheckType);
				
				if (CI_SUCCESS == chDownWashRelRouteCheckResult)
				{
					/*降级模式洗车线控制台表示灯1关联进路检查类型检查通过，驱动指示灯继电器吸起*/
					chReval = SetRelayDriveState(wDownWashControlLightRelayId, RELAY_DRIVE_STATE_UP);
				}
				else
				{
					chReval = SetRelayDriveState(wDownWashControlLightRelayId, RELAY_DRIVE_STATE_DOWN);
				}
			}
			else
			{
				; /*无继电器不处理*/
			}
		}
		else
		{
			; /*不处理*/
		}
	}
	else
	{
		; /*不处理*/
	}

	return chReval;
}

/*
* 功能描述： 降级模式洗车线关联进路状态检查
* 参数说明： const UINT16 wRouteId 进路ID
*			 const UINT8 chCheckType 进路检查类型
* 返回值  ： CI_ERROR: 更新失败
*			 CI_SUCCESS: 更新成功
* by cgh 20231113
*/
UINT8 DownWashRelRouteStateCheck(const UINT16 wRouteId,const UINT8 chCheckType)
{
	UINT8 chReval = CI_ERROR;
	UINT8 chRouteState = 0U;/*进路状态*/
	UINT8 chRouteType = 0U;/*进路类型*/

	if ((0U < wRouteId) && (ROUTE_SUM_MAX > wRouteId))
	{
		chRouteType = GetRouteType(wRouteId);
		if (ROUTE_TYPE_DIAOCHE == chRouteType)
		{
			chRouteState = GetRouteState(wRouteId);

			if ((WASH_REL_ROUTE_OPEN_STATE == chCheckType) &&
				((ROUTE_STATE_YUXIAN_OPEN == chRouteState) || (ROUTE_STATE_NEAR_OPEN == chRouteState)))
			{
				/*检查类型为进路开放状态且当前进路状态为预先开放、接近开放，检查通过*/
				chReval = CI_SUCCESS;
			}
			else if (WASH_REL_ROUTE_LOCK_STATE == chCheckType)
			{
				if ((ROUTE_STATE_IDLE == chRouteState) || (ROUTE_STATE_FIRST_XUANPAI == chRouteState)
					|| (ROUTE_STATE_XUANPAI == chRouteState))
				{
					/*进路状态为进路空闲 || 进路初选 || 进路选排 说明进路未锁闭，检查不通过*/

				}
				else
				{
					/*进路状态为锁闭，检查通过*/
					chReval = CI_SUCCESS;
				}
			}
			else
			{
				; /*进路检查类型非法返回失败*/
			}

		}
		else
		{
			;/*非调车进路返回失败*/
		}	
	}
	else
	{
		; /*接口校验不通过，返回失败*/
	}

	return chReval;
}

/*
* 功能描述： 处理驱采两个继电器ID是否混线状态
* 参数说明：const UINT16 drvRelayId	驱动继电器ID
*			const UINT16 collectRelayId		采集继电器ID
* 返回值  ： 1：不是混线状态
*            0：混线状态
*
*/
void ProcessCoupleRelayHunXianState(const UINT16 drvRelayId, const UINT16 collectRelayId)
{
	/*初始化*/
	UINT8 relayColleState = 0u;
	UINT8 relayDriveState = 0u;
	UINT8 retValue = CI_ERROR;
	UINT32 curCycNum = 0u;
	UINT8 checkRelayRes = 0u;
	UINT32 relayCycNum = 0u;

	curCycNum = Get2oo2CurCycleNum();

	if ((0U < drvRelayId)&&(0U< collectRelayId))
	{
		retValue = CI_SUCCESS;
		/*获取继电器状态*/
		relayColleState = GetRelayCollState(collectRelayId); /*采集状态*/
		relayDriveState = GetRelayDriveState(drvRelayId); /*驱动状态*/

		/*驱动是落下*/
		if ((RELAY_DRIVE_STATE_DOWN == relayDriveState) || (RELAY_DRIVE_STATE_NULL == relayDriveState))
		{
			/*吸起*/
			if (RELAY_STATE_UP == relayColleState)
			{
				relayCycNum = GetRelayHunXianStarCycNum(drvRelayId);
				checkRelayRes = SystemOverTimeCheck(relayCycNum, RELAY_HUNXIAN_NUM);
				/*未计时*/
				if (CI_TIME_NO == checkRelayRes)
				{
					SetRelayHunXianStarCycNum(drvRelayId, curCycNum);/*设置继电器有效周期*/
				}
				/*超时*/
				else if (CI_TIME_OUT == checkRelayRes)
				{
					retValue = CI_ERROR;
				}
				else
				{
					/*计时中，返回成功*/
				}
			}
			else
			{
				SetRelayHunXianStarCycNum(drvRelayId, 0u);/*设置继电器有效周期*/
			}
		}
		/*驱动吸起不做混线检查*/
		else
		{
			SetRelayHunXianStarCycNum(drvRelayId, 0u);/*设置继电器有效周期*/
		}

		if (CI_ERROR == retValue)
		{
			/*设置继电器混线状态*/
			SetRelayHunXianState(drvRelayId, RELAY_HUNXIAN_STATE_YES);
		}
		else
		{
			/*设置继电器未混线状态*/
			SetRelayHunXianState(drvRelayId, RELAY_HUNXIAN_STATE_NO);
		}
	}
}

/*
* 功能描述： 设置洗车模式继电器驱动起始周期
* 参数说明： const UINT16 washMachineId 洗车机ID
* 返回值  ： 无
* by cgh 20231208
*/
void SetWorkModeRelayDriveStartCyc(const UINT16 washMachineId)
{
	UINT8 chRelayColleState = 0U;/*继电器采集状态*/
	UINT8 chrelayDriveState = 0U;/*继电器驱动状态*/
	UINT32 dwCurCycNum = 0U;/*系统当前周期数*/
	UINT32 dwRelayCycNum = 0U;/*继电器驱动起始周期数*/
	UINT16 washWorkModeBackRelayId = 0U;/*洗车机工作模式反馈采集继电器*/
	UINT16 washWorkModeRelayId = 0U;/*洗车机工作模式驱动继电器*/

	if ((0U < washMachineId) && (WASHMACHINE_SUM_MAX > washMachineId))
	{
		washWorkModeBackRelayId = GetWashModeBackRelayId(washMachineId);
		washWorkModeRelayId = GetWashModeRelayId(washMachineId);

		if ((0U != washWorkModeBackRelayId) && (RELAY_SUM_MAX != washWorkModeBackRelayId) && (0U != washWorkModeRelayId) && (RELAY_SUM_MAX != washWorkModeRelayId))
		{
			dwCurCycNum = Get2oo2CurCycleNum();
			/*获取继电器状态*/
			chRelayColleState = GetRelayCollState(washWorkModeBackRelayId); /*采集状态*/
			chrelayDriveState = GetRelayDriveState(washWorkModeRelayId); /*驱动状态*/

			/*驱动是吸起*/
			if (RELAY_DRIVE_STATE_UP == chrelayDriveState)
			{
				/*采集落下*/
				if (RELAY_STATE_DOWN == chRelayColleState)
				{
					dwRelayCycNum = GetWashWorkModeRelayDrvCycle(washMachineId);
					if (0U == dwRelayCycNum)
					{
						SetWashWorkModeRelayDrvCycle(washMachineId, dwCurCycNum);/*设置继电器有效周期*/
					}
					else
					{
						;/*周期数有效，不改变*/
					}
				}
				else
				{
					SetWashWorkModeRelayDrvCycle(washMachineId, 0U);/*设置继电器有效周期*/
				}
			}
			else if ((RELAY_DRIVE_STATE_DOWN == chrelayDriveState) || (RELAY_DRIVE_STATE_NULL == chrelayDriveState))
			{
				/*采集吸起*/
				if (RELAY_STATE_UP == chRelayColleState)
				{
					dwRelayCycNum = GetWashWorkModeRelayDrvCycle(washMachineId);
					if (0U == dwRelayCycNum)
					{
						SetWashWorkModeRelayDrvCycle(washMachineId, dwCurCycNum);/*设置继电器有效周期*/
					}
					else
					{
						;/*周期数有效，不改变*/
					}

				}
				else
				{
					SetWashWorkModeRelayDrvCycle(washMachineId, 0U);/*设置继电器有效周期*/
				}
			}
			else
			{
				SetWashWorkModeRelayDrvCycle(washMachineId, 0U);/*设置继电器有效周期*/
			}
		}
		else
		{
			; /*继电器ID不合法*/
		}
	}
	else
	{
		; /*洗车机ID不合法*/
	}
}

/*
* 功能描述： 屏蔽门视频清客驱动状态处理
* 参数说明： const UINT16 wPsdId, 屏蔽门ID
* 返回值  ： 无
* by cgh 20231214
*/
void PsdVideoQkDriveStateProc(const UINT16 wPsdId)
{
	UINT8 chVideoQkDriveState = 0U;/*视频清客驱动状态*/
	UINT16 wPsdVideoQkLight1RelayId = 0U;/*清客按钮箱视频清客指示灯1（绿）继电器*/
	UINT16 wPsdVideoQkLight2RelayId = 0U;/*清客按钮箱视频清客指示灯2（红）继电器*/

	if ((0U < wPsdId) && (PSD_SUM_MAX > wPsdId))
	{
		chVideoQkDriveState = GePsdVideoQkDriveState(wPsdId);
		wPsdVideoQkLight1RelayId = GetPsdVideoQkLight1RelayId(wPsdId); /*清客按钮箱视频清客指示灯1（绿）继电器*/
		wPsdVideoQkLight2RelayId = GetPsdVideoQkLight2RelayId(wPsdId); /*清客按钮箱视频清客指示灯2（红）继电器*/

		if ((0U != wPsdVideoQkLight1RelayId) && (UINT16_MAX != wPsdVideoQkLight1RelayId)
			&& (0U != wPsdVideoQkLight2RelayId) && (UINT16_MAX != wPsdVideoQkLight2RelayId))
		{
			/*必须两个继电器均配置才驱动*/
			if (VIDEO_QK_DRIVE_STATE_NO == chVideoQkDriveState)
			{
				/*视频清客驱动状态为无人---绿色（绿吸起红落下）*/
				(void)SetRelayDriveState(wPsdVideoQkLight1RelayId, RELAY_DRIVE_STATE_UP);
				(void)SetRelayDriveState(wPsdVideoQkLight2RelayId, RELAY_DRIVE_STATE_DOWN);

			}
			else if (VIDEO_QK_DRIVE_STATE_HAVE == chVideoQkDriveState)
			{
				/*视频清客驱动状态为有人---红色（绿落下红吸起）*/
				(void)SetRelayDriveState(wPsdVideoQkLight1RelayId, RELAY_DRIVE_STATE_DOWN);
				(void)SetRelayDriveState(wPsdVideoQkLight2RelayId, RELAY_DRIVE_STATE_UP);

			}
			else if (VIDEO_QK_DRIVE_STATE_TESTING == chVideoQkDriveState)
			{
				/*视频清客驱动状态为检测中---橙色（绿吸起红吸起）*/
				(void)SetRelayDriveState(wPsdVideoQkLight1RelayId, RELAY_DRIVE_STATE_UP);
				(void)SetRelayDriveState(wPsdVideoQkLight2RelayId, RELAY_DRIVE_STATE_UP);
			}
			else
			{
				/*视频清客驱动状态为无效---不亮（绿落下红落下）*/
				(void)SetRelayDriveState(wPsdVideoQkLight1RelayId, RELAY_DRIVE_STATE_DOWN);
				(void)SetRelayDriveState(wPsdVideoQkLight2RelayId, RELAY_DRIVE_STATE_DOWN);
			}
		}
		else
		{
			; /*配置不合法不处理*/
		}
	}
	else
	{
		/*入参非法，不处理*/
	}
}

/*
* 功能描述：道岔采集容忍处理(对存在锁闭状态的道岔采集四开增加3周期的容忍)
* 参数说明： const UINT16 switchId 道岔ID
* 返回值  ：  道岔容忍后位置
* Create: fan 20250317
*/
UINT8 GetSwitchCollToleratePos(const UINT16 switchId)
{
	UINT8 chSwitchColPos = 0u;
	UINT8 chSwitch1CollTolerateState = CI_ERROR; /*本道岔可否容忍检查*/
	UINT8 chSwitch2CollTolerateState = CI_ERROR;/*双动道岔另一端可否容忍检查*/
	UINT32 curCycNum = 0u;
	UINT32 switchCollTolerateCycNum = 0u;
	UINT8 retPos = 0u;
	UINT8 timeState = 0U;
	UINT8 switchCurPosition = 0u;
	UINT8 faultFlag = GetSwitchFaultState(switchId); /*获取道岔是否板卡均故障*/
	UINT16 switch2ndId = GetDSwitchOtherId(switchId); /*双动道岔*/
	curCycNum = Get2oo2CurCycleNum();
	chSwitchColPos = GetSwitchCollPos(switchId);


	switchCurPosition = GetSingleSwitchCurPosition(switchId);
	if ((SWITCH_POSITION_DINGWEI == switchCurPosition) || (SWITCH_POSITION_FANWEI == switchCurPosition))/*道岔当前定位或反位*/
	{
		if (SWITCH_POSITION_SIKAI == chSwitchColPos)
		{
			if (SWITCH_FAULT_STATE_NO == faultFlag) /*板卡无故障*/
			{
				chSwitch1CollTolerateState = CheckSwitchCollTolerateState(switchId);
				chSwitch2CollTolerateState = CheckSwitchCollTolerateState(switch2ndId);
				if ((CI_SUCCESS == chSwitch1CollTolerateState) || (CI_SUCCESS == chSwitch2CollTolerateState))
				{ /*检查道岔区段正常锁闭||防护锁闭||延时锁闭||跳跃锁闭||道岔防护锁闭*/
					switchCollTolerateCycNum = GetSwitchCollTolerateCycNum(switchId);
					if (0u == switchCollTolerateCycNum)
					{
						SetSwitchCollTolerateCycNum(switchId, curCycNum);
					}
					else
					{
						/*无处理*/
					}
				}
				else
				{
					/*上述锁闭条件均不满足，则停止容忍*/
					SetSwitchCollTolerateCycNum(switchId, 0u);
				}
			}
			else
			{
				/*立即停止容忍*/
				SetSwitchCollTolerateCycNum(switchId, 0u);
			}
			switchCollTolerateCycNum = GetSwitchCollTolerateCycNum(switchId);
			debug_infor_printf((const)"\n SwitchCollTolerate  Sikai_Switch ID:%d,   TolerateCycNumNum%d \n.", switchId, switchCollTolerateCycNum);
		}
		else
		{
			/*采集到正常，立即清容忍*/
			SetSwitchCollTolerateCycNum(switchId, 0u);
		}
	}
	else
	{
		/*道岔上周期无位置，不触发容忍*/
		SetSwitchCollTolerateCycNum(switchId, 0u);
	}
	switchCollTolerateCycNum = GetSwitchCollTolerateCycNum(switchId);
	timeState = SystemOverTimeCheck(switchCollTolerateCycNum, COLLTOLERATE_CYCNUM);/*超过2即是容忍三周期*/
	if (CI_TIME_NO == timeState) /*未计时，无容忍*/
	{
		retPos = chSwitchColPos;
	}
	else if (CI_TIME_IN == timeState)/*容忍中*/
	{
		retPos = switchCurPosition;
	}
	else
	{
		retPos = chSwitchColPos;/*超时*/
		SetSwitchCollTolerateCycNum(switchId, 0u);
	}
	return retPos;
}

/*
* 功能描述：检查道岔是否满足容忍条件
* 参数说明： const UINT16 switchId 道岔ID
* 返回值  ：  CI_SUCCESS满足融合条件  CI_ERROR不满足容忍 需要立即四开
* Create: fan 20250317
*/
UINT8 CheckSwitchCollTolerateState(UINT16 switchId)
{
	UINT8 chRet = CI_ERROR;
	UINT16 switchPhySecId = 0u; /*道岔所属物理区段*/
	UINT8 phySecLockState = 0u; /*物理区段锁闭状态*/
	UINT8 switchLockStatus = 0u; /*道岔锁闭状态*/
	UINT8 phySecJumpLockState = 0u; /*区段跳跃锁闭状态*/
	UINT16 switchLogSum = 0U; /*关联逻辑区段数量*/
	UINT16* logSecBuf = NULL;
	UINT8 chLogSecState = 0U; /*关联逻辑区段状态*/
	UINT16 i = 0U;
	UINT8 chSwithLogRouteLockCheck = CI_ERROR; /*道岔逻辑区段是否存在逻辑进路锁闭*/
	if((0U != switchId) && (switchId < SWITCH_SUM_MAX))
	{
		switchPhySecId = GetSwitchPhySectionId(switchId);
		phySecLockState = GetPhySecLockState(switchPhySecId);
		phySecJumpLockState = GetPhySecJumpLockState(switchPhySecId);
		switchLockStatus = GetSwitchLockStatus(switchId);
		switchLogSum = GetSwitchLogSecSum(switchId);
		logSecBuf = GetSwitchLogSecBuf(switchId);
		/*检查逻辑区段锁闭状态*/
		if ((0U != switchLogSum)&&(NULL != logSecBuf))
		{
			for (i = 0u; i < switchLogSum; i++)
			{
				/*检查逻辑区段逻辑锁闭状态*/
				chLogSecState = GetLogSecLogLockState(logSecBuf[i]);
				if (LOG_SECTION_LOGLOCK_NORMAL == chLogSecState)
				{
					chSwithLogRouteLockCheck = CI_SUCCESS; /*存在逻辑区段为逻辑正常锁闭*/
					break;
				}
				else
				{
					; /*继续遍历*/
				}
			}
		}
		else
		{
			chSwithLogRouteLockCheck = CI_ERROR;
		}

		if ((PHYSICAL_SECTION_LOCK_NORMAL == phySecLockState)
			|| (PHYSICAL_SECTION_LOCK_PROTECT == phySecLockState)
			|| (PHYSICAL_SECTION_LOCK_DELAY == phySecLockState)
			|| (PHYSICAL_SECTION_JUMP_LOCK_YES == phySecJumpLockState)
			|| (SWITCH_LOCK_STATUS_PROTECT == switchLockStatus)
			|| (SWITCH_LOCK_STATUS_DAP == switchLockStatus)
			|| (CI_SUCCESS == chSwithLogRouteLockCheck))
		{ /*道岔区段正常锁闭||防护锁闭||延时锁闭||跳跃锁闭||道岔防护锁闭*/
			chRet = CI_SUCCESS;
		}
		else
		{
			chRet = CI_ERROR; /*不满足容忍*/
		}
	}
	else
	{
		chRet = CI_ERROR;
	}

	return chRet;
}

/*
* 功能描述：宁象市域铁路紧急停车按钮处理
* 参数说明：UINT16 esbId ESB ID
* 返 回 值：无
* Created By LQ 2025.03.28
*/
void EsbNXRailBtnProc(UINT16 esbId)
{	
	UINT8 localCiId = 0U;              /*本地联锁ID*/
	UINT16 esbRelayId = 0u;    /*esb继电器ID*/
	UINT8 esbRelayBelongCiId = 0U;     /*esb采集继电器所属CI*/
	UINT8 esbRelayCollState = 0U;      /*esb按钮采集继电器状态*/
	UINT16 bufIndex = 0U;    /*数组下标*/
	UINT16 wRelayBelongOcId = 0U;  /*继电器所属OC*/
	UINT8 cOcCommState = TRANSMIT_STATE_BAD;  /*与OC通信状态*/
	UINT8 cABoardState = RELAY_BOARD_FAULT_YES;  /*A系板卡状态*/
	UINT8 cBBoardState = RELAY_BOARD_FAULT_YES;  /*B系板卡状态*/

	bufIndex = GetEsbConfigBufIndex(esbId);

	if (bufIndex < ESB_SUM_MAX)
	{
		localCiId = GetSystemParaLocalCiId();
		esbRelayId = GetEsbRelayId(esbId);
		esbRelayBelongCiId = GetRelayBelongCiId(esbRelayId);
		if ((0U != localCiId) && (esbRelayBelongCiId == localCiId))
		{
			esbRelayCollState = GetRelayCollState(esbRelayId);  /*获取ESB继电器采集状态*/
			if (RELAY_STATE_UP == esbRelayCollState)
			{
				/*ESB未按下、采集继电器吸起，维持当前紧急状态*/
			}
			else
			{
				(void)SetEsbState(esbId, ESB_STATE_VALID_YES);  /*ESB采集继电器落下（包括按钮正常按下或板卡故障或OC通信中断导致的落下），紧急有效*/

				/** 继电器落下，更新紧急关闭按钮采集继电器落下状态 **/
				wRelayBelongOcId = GetRelayBelongOCId(esbRelayId);
				cOcCommState = GetCiTransmitState(CI_SYSTEM_TYPE_OC, (UINT8)wRelayBelongOcId);  /*获取与OC通信状态*/
				cABoardState = GetRelayACollBoardState(esbRelayId);  /*获取A系板卡状态*/
				cBBoardState = GetRelayBCollBoardState(esbRelayId);  /*获取B系板卡状态*/

				if ((TRANSMIT_STATE_GOOD == cOcCommState) && ((RELAY_BOARD_FAULT_NO == cABoardState) || (RELAY_BOARD_FAULT_NO == cBBoardState)))
				{
					/*OC通信正常且有一系板卡状态正常，设置继电器正常落下*/
					SetEsbRelayDownState(esbId, ESB_RELAY_ERROR_DOWN_NO);
				}
				else
				{
					/*OC通信异常或两系板卡状态均故障，设置继电器通信异常落下*/
					SetEsbRelayDownState(esbId, ESB_RELAY_ERROR_DOWN_YES);
				}
			}
		}
		else
		{
			/*继电器ID错误/非本联锁，不处理*/
		}
	}
	else
	{
		/*索引错误，不处理*/
	}
}

/*
* 功能描述：宁象市域铁路紧急停车取消按钮处理
* 参数说明：UINT16 esbId ESB ID
* 返 回 值：无
* Created By LQ 2025.03.28
*/
void EsbNXRailCancelBtnProc(UINT16 esbId)
{
	UINT16 wEsbIdIndex = 0U;    /*ESB数组下标*/
	UINT16 cancelEsbRelayId = 0u;         /*取消esb继电器ID*/
	UINT8 localCiId = 0U;                 /*本地联锁ID*/
	UINT8 cancelEsbRelayBelongCiId = 0U;  /*取消esb采集继电器1所属CI*/
	UINT32 zfsBtnRelayCollCycNum = 0U;     /*自复式按钮继电器判断采集有效周期数*/
	UINT32 zfsBtnRelayFaultCycNum = 0U;    /*自复式按钮继电器判断故障周期数*/
	UINT32 zfsBtnRelayErrTriggerCycNum = 0U;    /*自复式按钮继电器判断误触发周期数*/
	UINT32 cancelEsbPressCycNum = 0U;      /*取消紧急关闭按钮按下周期*/
	UINT32 cancelEsbErrTriggerPressCycNum = 0U;      /*取消紧急关闭按钮误触发按下周期*/
	UINT8 cancelEsbValidFlag = ESB_CANCEL_VALID_NO;   /*取消紧急关闭按钮有效标志*/
	UINT8 btnPressValidTime = CI_TIME_NO;   /*按钮按下时间是否达到有效时间*/
	UINT8 btnPressFaultTime = CI_TIME_NO;   /*按钮按下时间是否达到故障时间*/
	UINT8 btnPressErrTriggerTime = CI_TIME_NO;   /*按钮按下时间是否达到误触发时间*/
	UINT16 wEsbRelayId = 0U;  /*ESB采集继电器ID*/
	UINT8 cEsbRelayCollState = 0U;  /*ESB采集继电器状态*/
	UINT16 wEsbRelayBelongOcId = 0U;  /*esb采集继电器所属OC*/
	UINT8 cEsbRelayDownState = ESB_RELAY_ERROR_DOWN_NO;  /*紧急关闭按钮继电器落下状态*/

	wEsbIdIndex = GetEsbConfigBufIndex(esbId);

	if (wEsbIdIndex < ESB_SUM_MAX)
	{
		cancelEsbRelayId = GetCancelEsbRelayId(esbId);
		cancelEsbRelayBelongCiId = GetRelayBelongCiId(cancelEsbRelayId);
		localCiId = GetSystemParaLocalCiId();

		if ((0U != localCiId) && (localCiId == cancelEsbRelayBelongCiId))
		{
			/***** 1.处理紧急关闭取消按钮正常/误触发按下周期和采集继电器落下状态 *****/
			EsbZfsCancelBtnPressStateProc(esbId, cancelEsbRelayId);

			/***** 2.处理紧急关闭取消按钮有效标志 *****/
			EsbNXRailCancelBtnValidFlagProc(esbId, cancelEsbRelayId);

			/***** 3.处理紧急状态及紧急关闭取消按钮有效标志 *****/
			cancelEsbValidFlag = GetCancelEsbValidFlag(esbId);
			cancelEsbPressCycNum = GetCancelEsbPressCycNum(esbId);
			zfsBtnRelayCollCycNum = GetSelfButCollCount();
			btnPressValidTime = SystemOverTimeCheck(cancelEsbPressCycNum, zfsBtnRelayCollCycNum);
			zfsBtnRelayFaultCycNum = GetSelfCancelButErrCount();
			btnPressFaultTime = SystemOverTimeCheck(cancelEsbPressCycNum, zfsBtnRelayFaultCycNum);
			wEsbRelayId = GetEsbRelayId(esbId);
			cEsbRelayCollState = GetRelayCollState(wEsbRelayId);  /*获取ESB继电器采集状态*/
			wEsbRelayBelongOcId = GetRelayBelongOCId(wEsbRelayId);
			cEsbRelayDownState = GetEsbRelayDownState(esbId);  /*获取紧急按钮采集继电器落下状态*/

			if ((ESB_CANCEL_VALID_YES == cancelEsbValidFlag) && (CI_TIME_OUT == btnPressValidTime) && (CI_TIME_OUT != btnPressFaultTime))
			{
				/*取消紧急关闭按钮有效且按钮按下时间达到判断采集有效时间且未达到故障判断时间，设置紧急关闭无效，设置取消紧急关闭按钮无效*/
				(void)SetEsbState(esbId, ESB_STATE_VALID_NO);
				SetCancelEsbValidFlag(esbId, ESB_CANCEL_VALID_NO);
			}
			else if ((RELAY_STATE_UP == cEsbRelayCollState) && (ESB_RELAY_ERROR_DOWN_YES == cEsbRelayDownState))
			{
				/*与OC初始通信当周期或继电器双系板卡恢复当周期，若紧急关闭按钮吸起，设置紧急关闭无效*/
				(void)SetEsbState(esbId, ESB_STATE_VALID_NO);
			}
			else
			{
				/*不处理*/
			}

			/***** 4.处理紧急关闭取消按钮故障标志 *****/
			cancelEsbErrTriggerPressCycNum = GetCancelEsbErrTrigPressCycNum(esbId);  /*获取取消按钮误触发按下周期*/
			zfsBtnRelayErrTriggerCycNum = GetSelfCancelButErrTriggerCount();  /*获取自复式取消按钮误触发判断时间*/
			btnPressErrTriggerTime = SystemOverTimeCheck(cancelEsbErrTriggerPressCycNum, zfsBtnRelayErrTriggerCycNum);

			if ((CI_TIME_OUT == btnPressFaultTime) || (CI_TIME_OUT == btnPressErrTriggerTime))
			{
				/*取消按钮正常按下时间达到故障判断时间或误触发按下时间达到误触发判断时间，设置取消紧急停车按钮故障标志*/
				SetCancelEsbErrFlag(esbId, ESB_ERROR_FLAG_YES);
			}
			else
			{
				SetCancelEsbErrFlag(esbId, ESB_ERROR_FLAG_NO);
			}
		}
		else
		{
			/*继电器ID错误/非本联锁，不处理*/
		}
	}
	else
	{
		/*索引错误，不处理*/
	}
}

/*
* 功能描述：宁象市域铁路紧急停车取消按钮有效标志处理
* 参数说明：const UINT16 wEsbId ESB ID
*           const UINT16 wCancelEsbRelayId  ESB取消按钮采集继电器ID
* 返回值  ：无
* Created By LQ 2025.03.30
*/
void EsbNXRailCancelBtnValidFlagProc(const UINT16 wEsbId, const UINT16 wCancelEsbRelayId)
{
	UINT16 wEsbIdIndex = 0U;  /*ESB数组下标*/
	UINT16 wRelayIdIndex = 0U;  /*继电器数组下标*/
	UINT8 cEsbState = ESB_STATE_VALID_NO;  /*紧急关闭状态*/
	UINT16 wEsbRelayId = 0U;  /*ESB采集继电器ID*/
	UINT8 cEsbRelayCollState = 0U;  /*ESB采集继电器状态*/
	UINT8 cCancelEsbRelayCollState = 0U;  /*ESB取消按钮采集继电器状态*/
	UINT8 cCancelEsbRelayDownState = ESB_RELAY_ERROR_DOWN_YES;  /*ESB取消按钮继电器落下状态*/

	wEsbIdIndex = GetEsbConfigBufIndex(wEsbId);
	wRelayIdIndex = GetRelayConfigBufIndex(wCancelEsbRelayId);

	if ((wEsbIdIndex < ESB_SUM_MAX) && (wRelayIdIndex < RELAY_SUM_MAX))
	{
		cEsbState = GetEsbState(wEsbId);  /*获取ESB状态*/
		wEsbRelayId = GetEsbRelayId(wEsbId);
		cEsbRelayCollState = GetRelayCollState(wEsbRelayId);  /*获取ESB继电器采集状态*/
		cCancelEsbRelayCollState = GetRelayCollState(wCancelEsbRelayId);  /*获取ESB取消按钮继电器采集状态*/
		cCancelEsbRelayDownState = GetCancelEsbRelayDownState(wEsbId);  /*获取ESB取消按钮采集继电器落下状态*/

		if ((ESB_STATE_VALID_YES == cEsbState) && (RELAY_STATE_UP == cEsbRelayCollState)
			&& (RELAY_STATE_DOWN == cCancelEsbRelayCollState) && (ESB_RELAY_ERROR_DOWN_NO == cCancelEsbRelayDownState))
		{
			/*紧急关闭有效且紧急关闭按钮采集继电器吸起且取消紧急关闭按钮采集继电器落下且为正常落下，设置取消紧急关闭按钮有效*/
			SetCancelEsbValidFlag(wEsbId, ESB_CANCEL_VALID_YES);
		}
		else if ((RELAY_STATE_UP != cEsbRelayCollState) || (ESB_RELAY_ERROR_DOWN_NO != cCancelEsbRelayDownState))
		{
			/*紧急关闭按钮采集继电器未吸起或取消按钮采集继电器落下状态非正常落下，设置取消紧急关闭按钮无效*/
			SetCancelEsbValidFlag(wEsbId, ESB_CANCEL_VALID_NO);
		}
		else
		{
			/*不处理*/
		}
	}
	else
	{
		/*入参非法，不处理*/
	}
}

/*
* 功能描述：宁象市域铁路紧急停车旁路按钮处理
* 参数说明：UINT16 esbId ESB ID
* 返 回 值：无
* Created By LQ 2025.03.30
*/
void EsbNXRailCutBtnProc(UINT16 esbId)
{
	UINT16 wEsbIdIndex = 0U;    /*ESB数组下标*/
	UINT16 wEsbCutRelayId = 0u;         /*紧急关闭旁路按钮采集继电器ID*/
	UINT8 localCiId = 0U;                 /*本地联锁ID*/
	UINT8 EsbCutRelayBelongCiId = 0U;  /*紧急关闭旁路按钮采集继电器所属CI*/
	UINT8 cEsbState = ESB_STATE_VALID_NO;  /*紧急关闭状态*/
	UINT32 zfsBtnRelayCollCycNum = 0U;     /*自复式按钮继电器判断采集有效周期数*/
	UINT32 zfsBtnRelayFaultCycNum = 0U;    /*自复式按钮继电器判断故障周期数*/
	UINT32 zfsBtnRelayErrTriggerCycNum = 0U;    /*自复式按钮继电器判断误触发周期数*/
	UINT32 dwEsbCutPressCycNum = 0U;      /*紧急关闭旁路按钮正常按下周期*/
	UINT32 dwEsbCutErrTriggerPressCycNum = 0U;  /*紧急关闭旁路按钮误触发按下周期*/
	UINT8 btnPressValidTime = CI_TIME_NO;   /*按钮按下时间是否达到有效时间*/
	UINT8 btnPressFaultTime = CI_TIME_NO;   /*按钮按下时间是否达到故障时间*/
	UINT8 btnPressErrTriggerTime = CI_TIME_NO;   /*按钮按下时间是否达到误触发时间*/

	wEsbIdIndex = GetEsbConfigBufIndex(esbId);

	if (wEsbIdIndex < ESB_SUM_MAX)
	{		
		wEsbCutRelayId = GetEsbCutRelayId(esbId);
		EsbCutRelayBelongCiId = GetRelayBelongCiId(wEsbCutRelayId);
		localCiId = GetSystemParaLocalCiId();
		if ((0U != localCiId) && (localCiId == EsbCutRelayBelongCiId))
		{
			/***** 1.处理紧急关闭旁路按钮正常/误触发按下周期和采集继电器落下状态 *****/
			EsbNXRailCutBtnPressStateProc(esbId, wEsbCutRelayId);

			/***** 2.处理紧急关闭旁路按钮旁路状态 *****/
			cEsbState = GetEsbState(esbId);  /*获取ESB状态*/
			dwEsbCutPressCycNum = GetEsbCutPressCycNum(esbId);
			zfsBtnRelayCollCycNum = GetSelfButCollCount();
			btnPressValidTime = SystemOverTimeCheck(dwEsbCutPressCycNum, zfsBtnRelayCollCycNum);
			zfsBtnRelayFaultCycNum = GetSelfCancelButErrCount();
			btnPressFaultTime = SystemOverTimeCheck(dwEsbCutPressCycNum, zfsBtnRelayFaultCycNum);

			if ((ESB_STATE_VALID_YES == cEsbState) && (CI_TIME_OUT == btnPressValidTime) && (CI_TIME_OUT != btnPressFaultTime))
			{
				/*紧急有效且紧急关闭旁路按钮按下时间达到判断采集有效时间且未达到故障判断时间，设置旁路有效*/
				SetEsbCutState(esbId, ESB_CUT_YES);
			}
			else
			{
				SetEsbCutState(esbId, ESB_CUT_NO);  /*设置旁路无效*/
			}

			/***** 3.处理紧急关闭旁路按钮故障标志 *****/
			dwEsbCutErrTriggerPressCycNum = GetEsbCutErrTrigPressCycNum(esbId);  /*获取旁路按钮误触发按下周期*/
			zfsBtnRelayErrTriggerCycNum = GetSelfCancelButErrTriggerCount();  /*获取自复式取消按钮误触发判断时间*/
			btnPressErrTriggerTime = SystemOverTimeCheck(dwEsbCutErrTriggerPressCycNum, zfsBtnRelayErrTriggerCycNum);

			if ((CI_TIME_OUT == btnPressFaultTime) || (CI_TIME_OUT == btnPressErrTriggerTime))
			{
				/*旁路按钮正常按下时间达到故障判断时间或误触发按下时间达到误触发判断时间，设置紧急关闭旁路按钮故障标志有效*/
				SetEsbCutErrFlag(esbId, ESB_ERROR_FLAG_YES);
			}
			else
			{
				SetEsbCutErrFlag(esbId, ESB_ERROR_FLAG_NO);
			}
		}
		else
		{
			/*继电器ID错误/非本联锁，不处理*/
		}
	}
	else
	{
		/*索引错误，不处理*/
	}
}

/*
* 功能描述：宁象市域铁路紧急停车旁路按钮按下状态处理
* 参数说明：const UINT16 wEsbId ESB ID
*           const UINT16 wCutEsbRelayId  紧急旁路按钮采集继电器ID
* 返回值  ：无
* Created By LQ 2025.03.30
*/
void EsbNXRailCutBtnPressStateProc(const UINT16 wEsbId, const UINT16 wCutEsbRelayId)
{
	UINT16 wEsbIdIndex = 0U;  /*ESB数组下标*/
	UINT16 wRelayIdIndex = 0U;  /*继电器数组下标*/
	UINT8 cCutRelayCollState = 0U;  /*紧急旁路按钮采集继电器状态*/
	UINT8 cEsbState = ESB_STATE_VALID_NO;  /*紧急关闭状态*/
	UINT8 cCutRelayDownState = ESB_RELAY_ERROR_DOWN_YES;  /*紧急关闭旁路按钮继电器落下状态*/
	UINT32 dwCutBtnPressCycNum = 0U;  /*紧急关闭旁路按钮按下周期*/
	UINT32 dwBtnErrTrigPressCycNum = 0U;  /*按钮误触发按下周期*/
	UINT32 dwCurCycNum = 0U;  /*当前周期*/
	UINT16 wRelayBelongOcId = 0U;  /*继电器所属OC*/
	UINT8 cOcCommState = TRANSMIT_STATE_BAD;  /*与OC通信状态*/
	UINT8 cABoardState = RELAY_BOARD_FAULT_YES;  /*A系板卡状态*/
	UINT8 cBBoardState = RELAY_BOARD_FAULT_YES;  /*B系板卡状态*/

	wEsbIdIndex = GetEsbConfigBufIndex(wEsbId);
	wRelayIdIndex = GetRelayConfigBufIndex(wCutEsbRelayId);

	if ((wEsbIdIndex < ESB_SUM_MAX) && (wRelayIdIndex < RELAY_SUM_MAX))
	{
		cCutRelayCollState = GetRelayCollState(wCutEsbRelayId);  /*获取旁路按钮继电器采集状态*/

		if (RELAY_STATE_UP == cCutRelayCollState)
		{
			/** 继电器吸起，更新紧急关闭旁路按钮正常/误触发按下周期 **/
			cEsbState = GetEsbState(wEsbId);  /*获取ESB状态*/
			cCutRelayDownState = GetEsbCutRelayDownState(wEsbId);  /*获取旁路按钮采集继电器落下状态*/
			dwCutBtnPressCycNum = GetEsbCutPressCycNum(wEsbId);  /*获取旁路按钮正常按下周期*/
			dwBtnErrTrigPressCycNum = GetEsbCutErrTrigPressCycNum(wEsbId);  /*获取旁路按钮误触发按下周期*/
			dwCurCycNum = Get2oo2CurCycleNum();

			if ((ESB_STATE_VALID_YES == cEsbState) && (ESB_RELAY_ERROR_DOWN_NO == cCutRelayDownState))
			{
				/*紧急有效且之前紧急关闭旁路按钮采集继电器处于正常落下状态（与OC通信正常且板卡状态正常），更新紧急关闭旁路按钮正常按下周期*/
				if ((0U == dwCutBtnPressCycNum) && (0U == dwBtnErrTrigPressCycNum))
				{
					SetEsbCutPressCycNum(wEsbId, dwCurCycNum);  /*正常按下和误触发按下不同时存在*/
				}
				else
				{
					/*不处理*/
				}
			}
			else
			{
				/*紧急无效或之前紧急关闭旁路按钮采集继电器未处于正常落下状态（与OC通信中断或双系板卡状态异常），更新紧急关闭旁路按钮误触发按下周期*/
				if ((0U == dwCutBtnPressCycNum) && (0U == dwBtnErrTrigPressCycNum))
				{
					SetEsbCutErrTrigPressCycNum(wEsbId, dwCurCycNum);  /*正常按下和误触发按下不同时存在*/
				}
				else
				{
					/*不处理*/
				}
			}
		}
		else
		{
			/** 继电器落下，更新紧急关闭旁路按钮采集继电器落下状态 **/
			wRelayBelongOcId = GetRelayBelongOCId(wCutEsbRelayId);
			cOcCommState = GetCiTransmitState(CI_SYSTEM_TYPE_OC, (UINT8)wRelayBelongOcId);  /*获取与OC通信状态*/
			cABoardState = GetRelayACollBoardState(wCutEsbRelayId);  /*获取A系板卡状态*/
			cBBoardState = GetRelayBCollBoardState(wCutEsbRelayId);  /*获取B系板卡状态*/

			if ((TRANSMIT_STATE_GOOD == cOcCommState) && ((RELAY_BOARD_FAULT_NO == cABoardState) || (RELAY_BOARD_FAULT_NO == cBBoardState)))
			{
				/*OC通信正常且有一系板卡状态正常，设置继电器正常落下*/
				SetEsbCutRelayDownState(wEsbId, ESB_RELAY_ERROR_DOWN_NO);
			}
			else
			{
				/*OC通信异常或两系板卡状态均故障，设置继电器通信异常落下*/
				SetEsbCutRelayDownState(wEsbId, ESB_RELAY_ERROR_DOWN_YES);
			}

			/** 继电器落下，清除紧急关闭旁路按钮正常按下周期和误触发按下周期 **/
			SetEsbCutPressCycNum(wEsbId, 0U);
			SetEsbCutErrTrigPressCycNum(wEsbId, 0U);
		}
	}
	else
	{
		/*入参非法，不处理*/
	}
}

/*
* 功能描述：宁象市域铁路ESB指示灯和ESB旁路指示灯输出处理
* 参数说明：const UINT16 wEsbId ESB ID
* 返 回 值：无
* Created By LQ 2025.03.30
*/
void EsbNXRailDisplayDrivOutput(const UINT16 wEsbId)
{
	UINT16 esbDisplayRelayId = 0U;        /*esb指示灯继电器ID*/
	UINT16 esbPlatformDisRelayId = 0U;    /*esb站台指示灯继电器ID*/
	UINT16 cutEsbDisplayId = 0U;          /*esb旁路指示灯继电器ID*/
	UINT8  chLocalCiId = 0U;                /*本地联锁ID*/
	UINT8  devBlongCiId = 0U;             /*设备所属联锁ID*/
	UINT8 esbState = ESB_STATE_VALID_NO;  /*紧急关闭状态*/
	UINT16 bufIndex = 0U;  /*数组下标*/
	UINT8 cEsbCutState = 0U;  /*ESB旁路状态*/

	chLocalCiId = GetSystemParaLocalCiId(); /*获取本地联锁ID*/
	devBlongCiId = GetEsbBelongCiId(wEsbId); /*获取设备所属联锁ID*/

	if ((0U != chLocalCiId) && (chLocalCiId == devBlongCiId))
	{	
		esbState = GetEsbState(wEsbId);
		cEsbCutState = GetEsbCutState(wEsbId);
		/*设置ESB指示灯亮灭状态*/
		esbDisplayRelayId = GetEsbDisRelayId(wEsbId); /*根据esb ID获取esb指示灯ID*/
		bufIndex = GetRelayConfigBufIndex(esbDisplayRelayId);  /*获取继电器数组下标*/
		if (RELAY_SUM_MAX > bufIndex)
		{
			if ((ESB_STATE_VALID_YES == esbState) && (ESB_CUT_NO == cEsbCutState))
			{
				(void)SetRelayDriveState(esbDisplayRelayId, RELAY_STATE_UP); /*紧急且旁路无效，驱动ESB指示灯亮灯*/
			}
			else
			{
				(void)SetRelayDriveState(esbDisplayRelayId, RELAY_STATE_DOWN); /*未紧急或旁路有效，驱动ESB指示灯灭灯*/
			}
		}
		else
		{
			/*没有ESB指示灯，不做处理*/
		}

		/*设置ESB站台指示灯亮灭状态*/
		esbPlatformDisRelayId = GetEsbPlatformDisRelayId(wEsbId); /*根据esb ID获取esb站台指示灯继电器ID*/
		bufIndex = GetRelayConfigBufIndex(esbPlatformDisRelayId);  /*获取继电器数组下标*/
		if (RELAY_SUM_MAX > bufIndex)
		{
			/*设置ESB指示灯亮灭状态*/
			if ((ESB_STATE_VALID_YES == esbState) && (ESB_CUT_NO == cEsbCutState))
			{
				(void)SetRelayDriveState(esbPlatformDisRelayId, RELAY_STATE_UP); /*紧急且旁路无效，驱动ESB站台指示灯亮灯*/
			}
			else
			{
				(void)SetRelayDriveState(esbPlatformDisRelayId, RELAY_STATE_DOWN); /*未紧急或旁路有效，驱动ESB站台指示灯灭灯*/
			}
		}
		else
		{
			/*没有ESB站台指示灯，不做处理*/
		}

		cutEsbDisplayId = GetEsbCutDisRelayId(wEsbId); /*根据esb ID获取esb旁路指示灯ID*/
		bufIndex = GetRelayConfigBufIndex(cutEsbDisplayId);  /*获取继电器数组下标*/
		if (RELAY_SUM_MAX > bufIndex)
		{
			if (ESB_CUT_YES == cEsbCutState)
			{
				(void)SetRelayDriveState(cutEsbDisplayId, RELAY_STATE_UP); /*旁路有效，驱动指示灯亮灯*/
			}
			else
			{
				(void)SetRelayDriveState(cutEsbDisplayId, RELAY_STATE_DOWN); /*旁路无效，驱动指示灯灭灯*/
			}
		}
		else
		{
			/*没有旁路按钮指示灯继电器，不做处理*/
		}
	}
	else
	{
		/*非本集中区设备不处理*/
	}
}

/*
* 功能描述：屏蔽门异常打开处理
* 参数说明：无
* 返 回 值：无
* Created By LQ 2025.05.23
*/
void PsdExceptOpenProc(void)
{
	UINT16 wPsdCurNum = 0U;  /*PSD数量*/
	UINT16 ii = 0U;
	UINT16 wPsdId = 0U;  /*屏蔽门ID*/
	UINT8 cPsdVirtualAttr = 0U;  /*虚拟属性*/
	UINT8 cPsdMutualLockRemoveState = 0U;  /*PSD互锁解除状态*/
	UINT8 cPsdState = 0U;  /*PSD开关门状态*/
	UINT16 wPsdRelPhySecId = 0U;  /*PSD所处物理区段ID*/
	UINT8 cPhySecMerOccState = 0U;  /*站台轨融合占用状态*/

	wPsdCurNum = GetPsdSum();
	for (ii = 0U; ii < wPsdCurNum; ii++)
	{
		wPsdId = GetPsdId(ii);
		cPsdVirtualAttr = GetPsdVirtualAttribute(wPsdId);  /*获取PSD虚拟属性*/
		if (PSD_VIRTUAL_ATTR_NO == cPsdVirtualAttr)
		{
			cPsdMutualLockRemoveState = GetPsdMutualLockRemoveState(wPsdId);  /*获取PSD互锁解除状态*/
			if (PSD_MUTUALLOCK_REMOVE_NO == cPsdMutualLockRemoveState)
			{
				cPsdState = GetPsdState(wPsdId);  /*获取PSD开关门状态*/
				wPsdRelPhySecId = GetPsdRelatedPhySecId(wPsdId);
				cPhySecMerOccState = GetPhySecCurMergeState(wPsdRelPhySecId);
				if ((PSD_STATE_OPEN == cPsdState) && (SECTION_OCCUPY_YES != cPhySecMerOccState))
				{
					SetPsdExceptOpenState(wPsdId, PSD_EXCEPT_OPEN_YES);  /*PSD打开且未占用，设置PSD异常打开*/
				}
				else
				{
					SetPsdExceptOpenState(wPsdId, PSD_EXCEPT_OPEN_NO);  /*设置PSD未异常打开*/
				}
			}
			else
			{
				SetPsdExceptOpenState(wPsdId, PSD_EXCEPT_OPEN_NO);  /*互锁解除，设置PSD未异常打开*/
			}
		}
		else
		{
			SetPsdExceptOpenState(wPsdId, PSD_EXCEPT_OPEN_NO);  /*虚拟PSD，设置PSD未异常打开*/
		}
	}
}

/*
* 功能描述：自复式扣车旁路按钮处理
* 参数说明：const UINT16 signalId 信号机ID
* 返 回 值：无
* Created By LQ 2025.06.20
*/
void SignalZfsDetainCutBtnPro(const UINT16 signalId)
{
	UINT16 wSignalIdIndex = 0U;  /*信号机数组下标*/
	UINT16 wDetCutBtnRelayId = 0U;     /*扣车旁路按钮采集继电器ID*/
	UINT8 cLocalCiId = 0U;   /*本地联锁ID*/
	UINT8 cDetCutRelayBelongCiId = 0U;     /*扣车旁路按钮采集继电器所属CI*/
	UINT32 dwDetCutBtnPressCycNum = 0U;    /*扣车旁路按钮正常按下周期*/
	UINT32 dwZfsCutBtnFaultCycNum = 0U;   /*自复式扣车旁路按钮故障判断周期数*/
	UINT8 cBtnFaultTimeFlag = CI_TIME_NO;   /*按钮按下时间是否达到故障时间*/
	UINT32 dwDetCutErrTrigPressCycNum = 0U;    /*扣车旁路按钮误触发按下周期*/
	UINT32 dwZfsCutBtnErrTrigCycNum = 0U;   /*自复式扣车旁路按钮误触发判断周期数*/
	UINT8 cBtnErrTrigTimeFlag = CI_TIME_NO;   /*按钮按下时间是否达到误触发时间*/
	UINT8 cDetCutBtnState = 0U;  /*扣车旁路按钮状态*/

	wSignalIdIndex = GetSignalConfigBufIndex(signalId);

	if (SIGNAL_SUM_MAX > wSignalIdIndex)
	{
		wDetCutBtnRelayId = GetSignalDetainCutRelayId(signalId);		
		cDetCutRelayBelongCiId = GetRelayBelongCiId(wDetCutBtnRelayId);
		cLocalCiId = GetSystemParaLocalCiId();

		if ((cLocalCiId == cDetCutRelayBelongCiId) && (0U != cLocalCiId))
		{
			/***** 1.处理扣车旁路按钮正常/误触发按下周期和采集继电器落下状态 *****/
			ZfsDetCutBtnPressStateProc(signalId, wDetCutBtnRelayId);

			/***** 2.处理扣车旁路按钮故障标志 *****/
			dwDetCutBtnPressCycNum = GetDetCutBtnPressCycNum(signalId);
			dwZfsCutBtnFaultCycNum = GetSelfCancelButErrCount();
			cBtnFaultTimeFlag = SystemOverTimeCheck(dwDetCutBtnPressCycNum, dwZfsCutBtnFaultCycNum);  /*判断扣车旁路按钮正常按下时间是否达到故障时间*/
			dwDetCutErrTrigPressCycNum = GetDetCutBtnErrTrigPressCycNum(signalId);
			dwZfsCutBtnErrTrigCycNum = GetSelfCancelButErrTriggerCount();
			cBtnErrTrigTimeFlag = SystemOverTimeCheck(dwDetCutErrTrigPressCycNum, dwZfsCutBtnErrTrigCycNum);  /*判断扣车旁路按钮误触发按下时间是否达到误触发时间*/

			if ((CI_TIME_OUT == cBtnFaultTimeFlag) || (CI_TIME_OUT == cBtnErrTrigTimeFlag))
			{
				/*扣车旁路正常按下时间达到判断故障有效时间或扣车旁路按钮误触发按下时间达到判断误触发有效时间，设置扣车旁路按钮故障标志有效*/
				SetSignalDetCutBtnErrFlag(signalId, SIGNAL_ZFS_BTN_ERR_FLAG_YES);
			}
			else
			{
				SetSignalDetCutBtnErrFlag(signalId, SIGNAL_ZFS_BTN_ERR_FLAG_NO);  /*设置扣车旁路按钮故障标志无效*/
			}

			/***** 3.处理扣车旁路按钮有效状态 *****/
			ZfsDetCutBtnValidStateProc(signalId, wDetCutBtnRelayId);

			/***** 4.根据旁路按钮状态刷新扣车按钮激活标志 *****/
			cDetCutBtnState = GetDetCutBtnState(signalId);
			if (SIGNAL_DETAIN_CUT_VALID_YES == cDetCutBtnState)
			{
				/*扣车旁路按钮有效，设置扣车按钮激活标志无效*/
				SetSignalDetainBtnActFlag(signalId, SIGNAL_ZFS_BTN_ACT_FLAG_NO);
			}
			else
			{
				/*扣车旁路按钮无效，不处理*/
			}
		}
		else
		{
			/*非本联锁，不处理*/
		}
	}
	else
	{
		/*入参非法，不处理*/
	}
}

/*
* 功能描述：自复式扣车旁路按钮按下状态处理
* 参数说明：const UINT16 wSignalId 信号机ID
*           const UINT16 wDetCutBtnRelayId 扣车旁路按钮采集继电器ID
* 返 回 值：无
* Created By LQ 2025.06.20
*/
void ZfsDetCutBtnPressStateProc(const UINT16 wSignalId, const UINT16 wDetCutBtnRelayId)
{
	UINT16 wSignalIdIndex = 0U;  /*信号机数组下标*/
	UINT16 wRelayIdIndex = 0U;  /*继电器数组下标*/
	UINT8 cDetCutRelayCollState = 0U;  /*扣车旁路按钮采集继电器状态*/
	UINT8 cDetainBtnActFlag = SIGNAL_ZFS_BTN_ACT_FLAG_NO;  /*扣车按钮激活标志*/
	UINT8 cDetButErrorFlag = 0U;  /*扣车按钮故障标志*/
	UINT8 cDetCancelBtnErrorFlag = 0U;  /*扣车取消按钮故障标志*/
	UINT8 cDetCutRelayDownState = SIGNAL_RELAY_ERROR_DOWN_YES;  /*扣车旁路按钮采集继电器落下状态*/
	UINT32 dwDetCutBtnPressCycNum = 0U;  /*扣车旁路按钮正常按下周期*/
	UINT32 dwDetCutErrTrigPressCycNum = 0U;  /*扣车旁路按钮误触发按下周期*/
	UINT32 dwCurCycNum = 0U;  /*当前周期*/
	UINT16 wRelayBelongOcId = 0U;  /*继电器所属OC*/
	UINT8 cOcCommState = TRANSMIT_STATE_BAD;  /*与OC通信状态*/
	UINT8 cABoardState = RELAY_BOARD_FAULT_YES;  /*A系板卡状态*/
	UINT8 cBBoardState = RELAY_BOARD_FAULT_YES;  /*B系板卡状态*/

	wSignalIdIndex = GetSignalConfigBufIndex(wSignalId);
	wRelayIdIndex = GetRelayConfigBufIndex(wDetCutBtnRelayId);

	if ((SIGNAL_SUM_MAX > wSignalIdIndex) && (RELAY_SUM_MAX > wRelayIdIndex))
	{
		cDetCutRelayCollState = GetRelayCollState(wDetCutBtnRelayId);  /*获取扣车旁路按钮继电器采集状态*/

		if (RELAY_STATE_UP == cDetCutRelayCollState)
		{
			/** 继电器吸起，更新扣车旁路按钮正常/误触发按下周期 **/
			cDetainBtnActFlag = GetSignalDetainBtnActFlag(wSignalId);
			cDetButErrorFlag = GetSignalDetainBtnErrFlag(wSignalId);  /*获取扣车按钮故障标志*/
			cDetCancelBtnErrorFlag = GetSignalCancelDetainBtnErrFlag(wSignalId);  /*获取扣车取消按钮故障标志*/
			cDetCutRelayDownState = GetDetCutBtnRelayDownState(wSignalId);  /*获取扣车旁路按钮采集继电器落下状态*/
			dwDetCutBtnPressCycNum = GetDetCutBtnPressCycNum(wSignalId);  /*获取扣车旁路车按钮正常按下时间*/
			dwDetCutErrTrigPressCycNum = GetDetCutBtnErrTrigPressCycNum(wSignalId);  /*获取扣车旁路按钮误触发按下时间*/
			dwCurCycNum = Get2oo2CurCycleNum();

			if ((SIGNAL_ZFS_BTN_ACT_FLAG_YES == cDetainBtnActFlag) && ((SIGNAL_ZFS_BTN_ERR_FLAG_YES == cDetButErrorFlag) || (SIGNAL_ZFS_BTN_ERR_FLAG_YES == cDetCancelBtnErrorFlag))
				&& (SIGNAL_RELAY_ERROR_DOWN_NO == cDetCutRelayDownState))
			{
				/** 扣车按钮激活标志有效且（扣车按钮故障或扣车取消按钮故障）且上周期扣车旁路按钮采集继电器落下状态为正常落下（与OC通信正常且存在一系板卡状态正常），更新扣车旁路按钮正常按下时间 **/
				if ((0U == dwDetCutBtnPressCycNum) && (0U == dwDetCutErrTrigPressCycNum))
				{
					SetDetCutBtnPressCycNum(wSignalId, dwCurCycNum);  /*设置扣车旁路按钮正常按下时间为当周期（误触发和正常按下不同时存在）*/
				}
				else
				{
					/*不处理*/
				}
			}
			else
			{
				/** 扣车按钮激活标志无效或上周期扣车旁路按钮采集继电器落下状态非正常落下（与OC通信中断或两系板卡状态均故障），更新扣车旁路按钮误触发按下时间 **/
				if ((0U == dwDetCutBtnPressCycNum) && (0U == dwDetCutErrTrigPressCycNum))
				{
					SetDetCutBtnErrTrigPressCycNum(wSignalId, dwCurCycNum);  /*设置扣车旁路按钮误触发按下时间为当周期（误触发和正常按下不同时存在）*/
				}
				else
				{
					/*不处理*/
				}
			}
		}
		else
		{
			/** 继电器落下，更新扣车旁路按钮采集继电器落下状态 **/
			wRelayBelongOcId = GetRelayBelongOCId(wDetCutBtnRelayId);
			cOcCommState = GetCiTransmitState(CI_SYSTEM_TYPE_OC, (UINT8)wRelayBelongOcId);  /*获取与OC通信状态*/
			cABoardState = GetRelayACollBoardState(wDetCutBtnRelayId);  /*获取A系板卡状态*/
			cBBoardState = GetRelayBCollBoardState(wDetCutBtnRelayId);  /*获取B系板卡状态*/

			if ((TRANSMIT_STATE_GOOD == cOcCommState) && ((RELAY_BOARD_FAULT_NO == cABoardState) || (RELAY_BOARD_FAULT_NO == cBBoardState)))
			{
				/*OC通信正常且有一系板卡状态正常，设置继电器正常落下*/
				SetDetCutBtnRelayDownState(wSignalId, SIGNAL_RELAY_ERROR_DOWN_NO);
			}
			else
			{
				/*OC通信异常或两系板卡状态均故障，设置继电器通信异常落下*/
				SetDetCutBtnRelayDownState(wSignalId, SIGNAL_RELAY_ERROR_DOWN_YES);
			}

			/** 继电器落下，清除扣车旁路按钮正常按下周期和误触发按下周期 **/
			SetDetCutBtnPressCycNum(wSignalId, 0U);
			SetDetCutBtnErrTrigPressCycNum(wSignalId, 0U);
		}
	}
	else
	{
		/*入参非法，不处理*/
	}
}

/*
* 功能描述：自复式扣车旁路按钮有效状态处理
* 参数说明：const UINT16 wSignalId 信号机ID
*           const UINT16 wDetCutBtnRelayId 扣车旁路按钮采集继电器ID
* 返 回 值：无
* Created By LQ 2025.06.20
*/
void ZfsDetCutBtnValidStateProc(const UINT16 wSignalId, const UINT16 wDetCutBtnRelayId)
{
	UINT16 wSignalIdIndex = 0U;  /*信号机数组下标*/
	UINT16 wRelayIdIndex = 0U;  /*继电器数组下标*/
	UINT32 dwCycNum = 0U;
	UINT32 dwDetCutBtnPressCycNum = 0U;    /*扣车旁路按钮正常按下周期*/
	UINT32 dwZfsBtnValidCycNum = 0U;    /*自复式按钮生效判断周期数*/
	UINT8 cDetainBtnActFlag = SIGNAL_ZFS_BTN_ACT_FLAG_NO;  /*扣车按钮激活标志*/
	UINT8 cDetButErrorFlag = 0U;  /*扣车按钮故障标志*/
	UINT8 cDetCancelBtnErrorFlag = 0U;  /*扣车取消按钮故障标志*/
	UINT32 dwDetBtnPressCycNum = 0U;  /*扣车按钮按下周期*/
	UINT8 cDetCutRelayDownState = SIGNAL_RELAY_ERROR_DOWN_YES;  /*扣车旁路按钮采集继电器落下状态*/
	UINT8 cDetCutBtnErrorFlag = SIGNAL_ZFS_BTN_ERR_FLAG_NO;  /*扣车旁路按钮故障标志*/

	wSignalIdIndex = GetSignalConfigBufIndex(wSignalId);
	wRelayIdIndex = GetRelayConfigBufIndex(wDetCutBtnRelayId);

	if ((SIGNAL_SUM_MAX > wSignalIdIndex) && (RELAY_SUM_MAX > wRelayIdIndex))
	{
		/**** 1.扣车旁路按钮有效状态判断 ****/
		dwCycNum = Get2oo2CurCycleNum();
		dwDetCutBtnPressCycNum = GetDetCutBtnPressCycNum(wSignalId);
		dwZfsBtnValidCycNum = GetSelfButCollCount();		

		if ((0U < dwDetCutBtnPressCycNum) && ((dwCycNum - dwDetCutBtnPressCycNum) == (dwZfsBtnValidCycNum + 1U)))
		{
			/*按下超时当周期，设置扣车旁路按钮有效（为保证旁路单次有效，故在此采用“超时当周期设置按钮有效”的方法）*/
			SetDetCutBtnState(wSignalId, SIGNAL_DETAIN_CUT_VALID_YES);
		}
		else
		{
			/*不处理*/
		}

		/**** 2.扣车旁路按钮无效状态判断 ****/
		cDetainBtnActFlag = GetSignalDetainBtnActFlag(wSignalId);  /*获取扣车按钮激活标志*/
		cDetButErrorFlag = GetSignalDetainBtnErrFlag(wSignalId);  /*获取扣车按钮故障标志*/
		cDetCancelBtnErrorFlag = GetSignalCancelDetainBtnErrFlag(wSignalId);  /*获取扣车取消按钮故障标志*/
		dwDetBtnPressCycNum = GetDetainBtnPressCycNum(wSignalId);  /*获取扣车按钮按下起始周期*/
		cDetCutRelayDownState = GetDetCutBtnRelayDownState(wSignalId);  /*获取扣车旁路按钮采集继电器落下状态*/
		cDetCutBtnErrorFlag = GetSignalDetCutBtnErrFlag(wSignalId);  /*获取扣车旁路按钮故障标志*/
		
		if (((SIGNAL_ZFS_BTN_ACT_FLAG_YES != cDetainBtnActFlag) && (SIGNAL_ZFS_BTN_ERR_FLAG_YES != cDetButErrorFlag) && (SIGNAL_ZFS_BTN_ERR_FLAG_YES != cDetCancelBtnErrorFlag))
			|| ((0U < dwDetCutBtnPressCycNum) && (dwDetBtnPressCycNum >= dwDetCutBtnPressCycNum))
			|| (SIGNAL_RELAY_ERROR_DOWN_NO != cDetCutRelayDownState) 
			|| (SIGNAL_ZFS_BTN_ERR_FLAG_NO != cDetCutBtnErrorFlag))
		{
			/* 扣车按钮未激活且（扣车按钮和扣车取消按钮均未故障）
			或 扣车按钮按下周期大于等于旁路按钮按下周期
			或 旁路按钮采集继电器非正常落下
			或 旁路按钮故障
			设置扣车旁路按钮无效*/
			SetDetCutBtnState(wSignalId, SIGNAL_DETAIN_CUT_VALID_NO);
		}
		else
		{
			/*不处理*/
		}
	}
	else
	{
		/*入参非法，不处理*/
	}
}

/*
* 功能描述：获取SPKS按钮采集容忍结果
* 参数说明：const UINT16 wSpksId SPKS编号
* 返 回 值：CI_ERROR 0 容忍结束
*           CI_SUCCESS 1 继续容忍
* Created By LQ 2025.06.26
*/
UINT8 GetSpksBtnCollTolerateRet(const UINT16 wSpksId)
{
	UINT8 cRetVal = CI_ERROR;
	UINT16 wDevIdIndex = 0U;  /*ID索引*/
	UINT16 wCollRelayId = 0U;  /*采集继电器ID*/
	UINT8 cCollState = 0U;  /*继电器采集状态*/
	UINT32 dwSpksBtnPressCycNum = 0U;  /*SPKS按钮按下起始周期*/
	UINT32 dwTempOcCollTolerateCount = 0U;
	UINT32 dwCurCycNum = 0U;  /*当前周期号*/
	UINT16 wRelayBelongOcId = 0U;  /*继电器所属OC*/
	UINT8 cOcCommState = TRANSMIT_STATE_BAD;  /*与OC通信状态*/
	UINT8 cABoardState = RELAY_BOARD_FAULT_YES;  /*A系板卡状态*/
	UINT8 cBBoardState = RELAY_BOARD_FAULT_YES;  /*B系板卡状态*/
	UINT8 cBoardType = 0U;  /*继电器板卡类型*/
	UINT8 cTimeCheckFlag = 0U;

	wDevIdIndex = GetSpksConfigBufIndex(wSpksId);

	if (SPKS_SUM_MAX > wDevIdIndex)
	{
		wCollRelayId = GetSpksColRelayId(wSpksId);  /*获取SPKS采集继电器ID*/
		cCollState = GetRelayCollState(wCollRelayId);  /*获取SPKS采集继电器状态*/
		if (RELAY_STATE_UP == cCollState)
		{
			/*SPKS采集继电器吸起，设置SPKS按钮按下起始周期为0*/
			SetSpksPressCycNum(wSpksId, 0U);
			cRetVal = CI_SUCCESS;
		}
		else
		{
			dwSpksBtnPressCycNum = GetSpksPressCycNum(wSpksId);  /*获取SPKS按钮按下起始周期号*/
			if (0U == dwSpksBtnPressCycNum)
			{
				dwCurCycNum = Get2oo2CurCycleNum();
				SetSpksPressCycNum(wSpksId, dwCurCycNum);  /*设置当前周期为SPKS按钮按下起始周期号*/
			}
			else
			{
				/*已设置SPKS按钮按下起始周期号，不处理*/
			}

			wRelayBelongOcId = GetRelayBelongOCId(wCollRelayId);
			cOcCommState = GetCiTransmitState(CI_SYSTEM_TYPE_OC, (UINT8)wRelayBelongOcId);  /*获取与OC通信状态*/
			cABoardState = GetRelayACollBoardState(wCollRelayId);  /*获取A系板卡状态*/
			cBBoardState = GetRelayBCollBoardState(wCollRelayId);  /*获取B系板卡状态*/
			cBoardType = GetRelayBoardType(wCollRelayId);  /*获取继电器板卡类型*/

			if ((TRANSMIT_STATE_GOOD == cOcCommState) && ((RELAY_BOARD_FAULT_NO == cABoardState) || (RELAY_BOARD_FAULT_NO == cBBoardState)) && (RELAY_SI_BOARD == cBoardType))
			{
				/*OC通信正常且有一系板卡状态正常且为零散输入板，判断是否超过容忍时间*/
				dwSpksBtnPressCycNum = GetSpksPressCycNum(wSpksId);  /*获取SPKS按钮按下起始周期号*/
				dwTempOcCollTolerateCount = GetOcCollTolerateCount();
				cTimeCheckFlag = SystemOverOrEqualTimeCheck(dwSpksBtnPressCycNum, dwTempOcCollTolerateCount);  /*判断SPKS按钮按下时间是否达到容忍时间*/
				if (CI_TIME_OUT != cTimeCheckFlag)
				{
					cRetVal = CI_SUCCESS;  /*未超时，需要继续容忍*/
				}
				else
				{
					cRetVal = CI_ERROR;  /*超时，不需要继续容忍*/
				}
			}
			else
			{
				/*OC通信异常或两系板卡状态均故障或继电器非零散输入板，返回0*/
				cRetVal = CI_ERROR;
			}
		}
	}
	else
	{
		cRetVal = CI_ERROR;  /*入参非法，返回0*/
	}

	return cRetVal;
}

/*
* 功能描述：获取Psd门开继电器采集容忍结果
* 参数说明：const UINT16 wPsdId PSD编号
* 返 回 值：CI_ERROR 0 容忍结束
*           CI_SUCCESS 1 继续容忍
* Created By LQ 2025.06.26
*/
UINT8 GetPsdRelayCollTolerateRet(const UINT16 wPsdId)
{
	UINT8 cRetVal = CI_ERROR;
	UINT16 wDevIdIndex = 0U;  /*ID索引*/
	UINT16 wCollRelayId = 0U;  /*采集继电器ID*/
	UINT8 cCollState = 0U;  /*继电器采集状态*/
	UINT32 dwRelayDownCycNum = 0U;  /*PSD门开继电器落下起始周期*/
	UINT32 dwTempOcCollTolerateCount;
	UINT32 dwCurCycNum = 0U;  /*当前周期号*/
	UINT16 wRelayBelongOcId = 0U;  /*继电器所属OC*/
	UINT8 cOcCommState = TRANSMIT_STATE_BAD;  /*与OC通信状态*/
	UINT8 cABoardState = RELAY_BOARD_FAULT_YES;  /*A系板卡状态*/
	UINT8 cBBoardState = RELAY_BOARD_FAULT_YES;  /*B系板卡状态*/
	UINT8 cBoardType = 0U;  /*继电器板卡类型*/
	UINT8 cTimeCheckFlag = 0U;

	wDevIdIndex = GetPsdConfigBufIndex(wPsdId);

	if (PSD_SUM_MAX > wDevIdIndex)
	{
		wCollRelayId = GetPsdStateRelayId(wPsdId);  /*获取PSD门开继电器ID*/
		cCollState = GetRelayCollState(wCollRelayId);  /*获取PSD门开继电器状态*/
		if (RELAY_STATE_UP == cCollState)
		{
			/*PSD门开继电器吸起，设置PSD门开继电器落下起始周期为0*/
			SetPsdRelayDownCycNum(wPsdId, 0U);
			cRetVal = CI_SUCCESS;
		}
		else
		{
			dwRelayDownCycNum = GetPsdRelayDownCycNum(wPsdId);  /*获取PSD门开继电器落下起始周期号*/
			if (0U == dwRelayDownCycNum)
			{
				dwCurCycNum = Get2oo2CurCycleNum();
				SetPsdRelayDownCycNum(wPsdId, dwCurCycNum);  /*设置当前周期为PSD门开继电器落下起始周期号*/
			}
			else
			{
				/*已设置PSD门开继电器落下起始周期号，不处理*/
			}

			wRelayBelongOcId = GetRelayBelongOCId(wCollRelayId);
			cOcCommState = GetCiTransmitState(CI_SYSTEM_TYPE_OC, (UINT8)wRelayBelongOcId);  /*获取与OC通信状态*/
			cABoardState = GetRelayACollBoardState(wCollRelayId);  /*获取A系板卡状态*/
			cBBoardState = GetRelayBCollBoardState(wCollRelayId);  /*获取B系板卡状态*/
			cBoardType = GetRelayBoardType(wCollRelayId);  /*获取继电器板卡类型*/

			if ((TRANSMIT_STATE_GOOD == cOcCommState) && ((RELAY_BOARD_FAULT_NO == cABoardState) || (RELAY_BOARD_FAULT_NO == cBBoardState)) && (RELAY_SI_BOARD == cBoardType))
			{
				/*OC通信正常且有一系板卡状态正常且为零散输入板，判断是否超过容忍时间*/
				dwRelayDownCycNum = GetPsdRelayDownCycNum(wPsdId);  /*获取PSD门开继电器落下起始周期号*/
				dwTempOcCollTolerateCount = GetOcCollTolerateCount();
				cTimeCheckFlag = SystemOverOrEqualTimeCheck(dwRelayDownCycNum, dwTempOcCollTolerateCount);  /*判断PSD门开继电器落下时间是否达到容忍时间*/
				if (CI_TIME_OUT != cTimeCheckFlag)
				{
					cRetVal = CI_SUCCESS;  /*未超时，需要继续容忍*/
				}
				else
				{
					cRetVal = CI_ERROR;  /*超时，不需要继续容忍*/
				}
			}
			else
			{
				/*OC通信异常或两系板卡状态均故障或继电器非零散输入板，返回0*/
				cRetVal = CI_ERROR;
			}
		}
	}
	else
	{
		cRetVal = CI_ERROR;  /*入参非法，返回0*/
	}

	return cRetVal;
}

/*
* 功能描述：获取Esb采集容忍结果
* 参数说明：const UINT16 wEsbId ESB编号
* 返 回 值：CI_ERROR 0 容忍结束
*           CI_SUCCESS 1 继续容忍
* Created By LQ 2025.06.26
*/
UINT8 GetEsbCollTolerateRet(const UINT16 wEsbId)
{
	UINT8 cRetVal = CI_ERROR;
	UINT16 wDevIdIndex = 0U;  /*ID索引*/
	UINT16 wCollRelayId = 0U;  /*采集继电器ID*/
	UINT8 cCollState = 0U;  /*继电器采集状态*/
	UINT32 dwEsbPressCycNum = 0U;  /*ESB按下起始周期*/
	UINT32 dwTempOcCollTolerateCount = 0U;
	UINT32 dwCurCycNum = 0U;  /*当前周期号*/
	UINT16 wRelayBelongOcId = 0U;  /*继电器所属OC*/
	UINT8 cOcCommState = TRANSMIT_STATE_BAD;  /*与OC通信状态*/
	UINT8 cABoardState = RELAY_BOARD_FAULT_YES;  /*A系板卡状态*/
	UINT8 cBBoardState = RELAY_BOARD_FAULT_YES;  /*B系板卡状态*/
	UINT8 cBoardType = 0U;  /*继电器板卡类型*/
	UINT8 cTimeCheckFlag = 0U;

	wDevIdIndex = GetEsbConfigBufIndex(wEsbId);

	if (ESB_SUM_MAX > wDevIdIndex)
	{
		wCollRelayId = GetEsbRelayId(wEsbId);  /*获取ESB采集继电器ID*/
		cCollState = GetRelayCollState(wCollRelayId);  /*获取ESB采集继电器状态*/
		if (RELAY_STATE_UP == cCollState)
		{
			/*ESB采集继电器吸起，设置ESB按下起始周期为0*/
			SetEsbPressCycNum(wEsbId, 0U);
			cRetVal = CI_SUCCESS;
		}
		else
		{
			dwEsbPressCycNum = GetEsbPressCycNum(wEsbId);  /*获取ESB按下起始周期号*/
			if (0U == dwEsbPressCycNum)
			{
				dwCurCycNum = Get2oo2CurCycleNum();
				SetEsbPressCycNum(wEsbId, dwCurCycNum);  /*设置当前周期为ESB按下起始周期号*/
			}
			else
			{
				/*已设置ESB按下起始周期号，不处理*/
			}

			wRelayBelongOcId = GetRelayBelongOCId(wCollRelayId);
			cOcCommState = GetCiTransmitState(CI_SYSTEM_TYPE_OC, (UINT8)wRelayBelongOcId);  /*获取与OC通信状态*/
			cABoardState = GetRelayACollBoardState(wCollRelayId);  /*获取A系板卡状态*/
			cBBoardState = GetRelayBCollBoardState(wCollRelayId);  /*获取B系板卡状态*/
			cBoardType = GetRelayBoardType(wCollRelayId);  /*获取继电器板卡类型*/

			if ((TRANSMIT_STATE_GOOD == cOcCommState) && ((RELAY_BOARD_FAULT_NO == cABoardState) || (RELAY_BOARD_FAULT_NO == cBBoardState)) && (RELAY_SI_BOARD == cBoardType))
			{
				/*OC通信正常且有一系板卡状态正常且为零散输入板，判断是否超过容忍时间*/
				dwEsbPressCycNum = GetEsbPressCycNum(wEsbId);  /*获取ESB按下起始周期号*/
				dwTempOcCollTolerateCount = GetOcCollTolerateCount();
				cTimeCheckFlag = SystemOverOrEqualTimeCheck(dwEsbPressCycNum, dwTempOcCollTolerateCount);  /*判断ESB按下时间是否达到容忍时间*/
				if (CI_TIME_OUT != cTimeCheckFlag)
				{
					cRetVal = CI_SUCCESS;  /*未超时，需要继续容忍*/
				}
				else
				{
					cRetVal = CI_ERROR;  /*超时，不需要继续容忍*/
				}
			}
			else
			{
				/*OC通信异常或两系板卡状态均故障或继电器非零散输入板，返回0*/
				cRetVal = CI_ERROR;
			}
		}
	}
	else
	{
		cRetVal = CI_ERROR;  /*入参非法，返回0*/
	}

	return cRetVal;
}

/*
* 功能描述：获取扣车按钮1采集容忍结果
* 参数说明：const UINT16 wSignalId 信号机编号
* 返 回 值：CI_ERROR 0 容忍结束
*           CI_SUCCESS 1 继续容忍
* Created By LQ 2025.06.26
*/
UINT8 GetFstDetBtnCollTolerateRet(const UINT16 wSignalId)
{
	UINT8 cRetVal = CI_ERROR;
	UINT16 wDevIdIndex = 0U;  /*ID索引*/
	UINT16 wCollRelayId = 0U;  /*采集继电器ID*/
	UINT8 cCollState = 0U;  /*继电器采集状态*/
	UINT8 cDetValidFlag = 0U;
	UINT32 dwDetBtnPressCycNum = 0U;  /*扣车按钮按下起始周期*/
	UINT32 dwTempOcCollTolerateCount = 0U;
	UINT32 dwCurCycNum = 0U;  /*当前周期号*/
	UINT16 wRelayBelongOcId = 0U;  /*继电器所属OC*/
	UINT8 cOcCommState = TRANSMIT_STATE_BAD;  /*与OC通信状态*/
	UINT8 cABoardState = RELAY_BOARD_FAULT_YES;  /*A系板卡状态*/
	UINT8 cBBoardState = RELAY_BOARD_FAULT_YES;  /*B系板卡状态*/
	UINT8 cBoardType = 0U;  /*继电器板卡类型*/
	UINT8 cTimeCheckFlag = 0U;

	wDevIdIndex = GetSignalConfigBufIndex(wSignalId);

	if (SIGNAL_SUM_MAX > wDevIdIndex)
	{
		wCollRelayId = GetSignalDetainRelayId(wSignalId);  /*获取扣车按钮采集继电器ID*/
		cCollState = GetRelayCollState(wCollRelayId);  /*获取扣车按钮采集继电器状态*/
		cDetValidFlag = GetCiFunctionSwitchConfig(FUNC_RELAY_DETAIN_VALID_FLAG);  /*获取硬线扣车有效标志*/

		if (((UP_VALID == cDetValidFlag) && (RELAY_STATE_DOWN == cCollState)) || ((DOWN_VALID == cDetValidFlag) && (RELAY_STATE_UP == cCollState)))
		{
			/*扣车按钮抬起，设置扣车按钮按下起始周期为0*/
			SetDetainBtnPressCycNum(wSignalId, 0U);
			cRetVal = CI_SUCCESS;
		}
		else
		{
			dwDetBtnPressCycNum = GetDetainBtnPressCycNum(wSignalId);  /*获取扣车按钮按下起始周期号*/
			if (0U == dwDetBtnPressCycNum)
			{
				dwCurCycNum = Get2oo2CurCycleNum();
				SetDetainBtnPressCycNum(wSignalId, dwCurCycNum);  /*设置当前周期为扣车按钮按下起始周期号*/
			}
			else
			{
				/*已设置扣车按钮按下起始周期号，不处理*/
			}

			wRelayBelongOcId = GetRelayBelongOCId(wCollRelayId);
			cOcCommState = GetCiTransmitState(CI_SYSTEM_TYPE_OC, (UINT8)wRelayBelongOcId);  /*获取与OC通信状态*/
			cABoardState = GetRelayACollBoardState(wCollRelayId);  /*获取A系板卡状态*/
			cBBoardState = GetRelayBCollBoardState(wCollRelayId);  /*获取B系板卡状态*/
			cBoardType = GetRelayBoardType(wCollRelayId);  /*获取继电器板卡类型*/

			if ((TRANSMIT_STATE_GOOD == cOcCommState) && ((RELAY_BOARD_FAULT_NO == cABoardState) || (RELAY_BOARD_FAULT_NO == cBBoardState)) && (RELAY_SI_BOARD == cBoardType))
			{
				/*OC通信正常且有一系板卡状态正常且为零散输入板，判断是否超过容忍时间*/
				dwDetBtnPressCycNum = GetDetainBtnPressCycNum(wSignalId);  /*获取扣车按钮按下起始周期号*/
				dwTempOcCollTolerateCount = GetOcCollTolerateCount();
				cTimeCheckFlag = SystemOverOrEqualTimeCheck(dwDetBtnPressCycNum, dwTempOcCollTolerateCount);  /*判断扣车按钮按下时间是否达到容忍时间*/
				if (CI_TIME_OUT != cTimeCheckFlag)
				{
					cRetVal = CI_SUCCESS;  /*未超时，需要继续容忍*/
				}
				else
				{
					cRetVal = CI_ERROR;  /*超时，不需要继续容忍*/
				}
			}
			else
			{
				/*OC通信异常或两系板卡状态均故障或继电器非零散输入板，返回0*/
				cRetVal = CI_ERROR;
			}
		}
	}
	else
	{
		cRetVal = CI_ERROR;  /*入参非法，返回0*/
	}

	return cRetVal;
}

/*
* 功能描述：获取扣车按钮2采集容忍结果
* 参数说明：const UINT16 wSignalId 信号机编号
* 返 回 值：CI_ERROR 0 容忍结束
*           CI_SUCCESS 1 继续容忍
* Created By LQ 2025.06.26
*/
UINT8 GetSndDetBtnCollTolerateRet(const UINT16 wSignalId)
{
	UINT8 cRetVal = CI_ERROR;
	UINT16 wDevIdIndex = 0U;  /*ID索引*/
	UINT16 wCollRelayId = 0U;  /*采集继电器ID*/
	UINT8 cCollState = 0U;  /*继电器采集状态*/
	UINT8 cDetValidFlag = 0U;
	UINT32 dwDetBtnPressCycNum = 0U;  /*扣车按钮按下起始周期*/
	UINT32 dwTempOcCollTolerateCount = 0U;
	UINT32 dwCurCycNum = 0U;  /*当前周期号*/
	UINT16 wRelayBelongOcId = 0U;  /*继电器所属OC*/
	UINT8 cOcCommState = TRANSMIT_STATE_BAD;  /*与OC通信状态*/
	UINT8 cABoardState = RELAY_BOARD_FAULT_YES;  /*A系板卡状态*/
	UINT8 cBBoardState = RELAY_BOARD_FAULT_YES;  /*B系板卡状态*/
	UINT8 cBoardType = 0U;  /*继电器板卡类型*/
	UINT8 cTimeCheckFlag = 0U;

	wDevIdIndex = GetSignalConfigBufIndex(wSignalId);

	if (SIGNAL_SUM_MAX > wDevIdIndex)
	{
		wCollRelayId = GetSignalDetainRelayId_2(wSignalId);  /*获取扣车按钮采集继电器ID*/
		cCollState = GetRelayCollState(wCollRelayId);  /*获取扣车按钮采集继电器状态*/
		cDetValidFlag = GetCiFunctionSwitchConfig(FUNC_RELAY_DETAIN_VALID_FLAG);  /*获取硬线扣车有效标志*/

		if (((UP_VALID == cDetValidFlag) && (RELAY_STATE_DOWN == cCollState)) || ((DOWN_VALID == cDetValidFlag) && (RELAY_STATE_UP == cCollState)))
		{
			/*扣车按钮抬起，设置扣车按钮按下起始周期为0*/
			SetDetainSndBtnPressCycNum(wSignalId, 0U);
			cRetVal = CI_SUCCESS;
		}
		else
		{
			dwDetBtnPressCycNum = GetDetainSndBtnPressCycNum(wSignalId);  /*获取扣车按钮按下起始周期号*/
			if (0U == dwDetBtnPressCycNum)
			{
				dwCurCycNum = Get2oo2CurCycleNum();
				SetDetainSndBtnPressCycNum(wSignalId, dwCurCycNum);  /*设置当前周期为扣车按钮按下起始周期号*/
			}
			else
			{
				/*已设置扣车按钮按下起始周期号，不处理*/
			}

			wRelayBelongOcId = GetRelayBelongOCId(wCollRelayId);
			cOcCommState = GetCiTransmitState(CI_SYSTEM_TYPE_OC, (UINT8)wRelayBelongOcId);  /*获取与OC通信状态*/
			cABoardState = GetRelayACollBoardState(wCollRelayId);  /*获取A系板卡状态*/
			cBBoardState = GetRelayBCollBoardState(wCollRelayId);  /*获取B系板卡状态*/
			cBoardType = GetRelayBoardType(wCollRelayId);  /*获取继电器板卡类型*/

			if ((TRANSMIT_STATE_GOOD == cOcCommState) && ((RELAY_BOARD_FAULT_NO == cABoardState) || (RELAY_BOARD_FAULT_NO == cBBoardState)) && (RELAY_SI_BOARD == cBoardType))
			{
				/*OC通信正常且有一系板卡状态正常且为零散输入板，判断是否超过容忍时间*/
				dwDetBtnPressCycNum = GetDetainSndBtnPressCycNum(wSignalId);  /*获取扣车按钮按下起始周期号*/
				dwTempOcCollTolerateCount = GetOcCollTolerateCount();
				cTimeCheckFlag = SystemOverOrEqualTimeCheck(dwDetBtnPressCycNum, dwTempOcCollTolerateCount);  /*判断扣车按钮按下时间是否达到容忍时间*/
				if (CI_TIME_OUT != cTimeCheckFlag)
				{
					cRetVal = CI_SUCCESS;  /*未超时，需要继续容忍*/
				}
				else
				{
					cRetVal = CI_ERROR;  /*超时，不需要继续容忍*/
				}
			}
			else
			{
				/*OC通信异常或两系板卡状态均故障或继电器非零散输入板，返回0*/
				cRetVal = CI_ERROR;
			}
		}
	}
	else
	{
		cRetVal = CI_ERROR;  /*入参非法，返回0*/
	}

	return cRetVal;
}


/*
* 功能描述：清除物理区段复位起始周期
* 参数说明：无
* 返 回 值：无
* 注：解决复位指令执行期间，总复位未按下一直下发复位指令的问题
* Created By fan 2026.03.24
*/
void CleanPhySecResetStartCycNum(void)
{
	UINT16 wPhysecNum = 0U;
	UINT16 wPhySecId = 0U;
	UINT16 ii = 0U;
	UINT8 chZfwValid = CI_ERROR;
	UINT16 wZFWrelayId = 0U;
	UINT8 chLocalCi = 0U;
	chLocalCi = GetSystemParaLocalCiId();
	wPhysecNum = GetPhySecCurSum();
	wZFWrelayId = GetZFWRelayId(chLocalCi);/*检查集中区是否存在总复位继电器*/
	if (0U < wZFWrelayId)
	{
		/*集中区存在计轴复位继电器 复位过程中总复位未按下 清除复位起始周期*/
		for (ii = 0U; ii < wPhysecNum; ii++)
		{
			wPhySecId = GetPhySecId(ii);
			chZfwValid = GetZFWValidByPhySecId(wPhySecId);
			/*区段配置总复位继电器且总复位继电器落下*/
			if (CI_ERROR == chZfwValid)
			{
				SetPhySecResetStartCycNum(wPhySecId, 0U);
			}
			else
			{
				;/*不处理*/
			}
		}
	}
	else
	{
		;/*不处理*/
	}
}