/********************************************************
*                                                                                                            
* 文 件 名： ParsePackIoData.c   
* 版权说明： 北京交控科技有限公司 
* 创建时间： 2012-03-28
* 作    者： 联锁组
* 功能描述： IO数据解析
* 修改记录：   
*
********************************************************/ 

#include "ParsePackIoData.h"
#include "ParsePackOcData.h"
#include "./ParsePackManage.h"
#include "../HLHTMsgHead/HLHTCommonDataPacketHead.h"
#include "../HLHTMsgHead/HLHTHeadContexManage.h"

#include "dfsDataRead.h"
#include "dquCIInit.h"




OcToCiOriginDataStruct m_OcToCiOrginDataArr[OC_SUM_MAX]; /*OC到CI数据帧结构体,【原始数据】*/
UINT8 m_OcToCiOrginDataNum = 0u;	/*Oc到Ci的数据当前的数量*/


OcCollBoardDataStruct m_OcConvertedPtDataArr[OC_SUM_MAX];/*CI收到的所有OC采集板数据【转换后的点位数据，吸起|落下】*/

OcFaultStateStruct m_OcFaultState[OC_SUM_MAX];/*CI收到的所有OC故障状态*/

OcDeviceStruct m_Signals[CI_SIGNAL_MAX];/*来自OC的所有信号机设备*/
UINT16 m_SignalNum = 0u;

OcDeviceStruct m_Switches[CI_SWITCH_MAX];/*来自OC的所有道岔设备*/
UINT16 m_SwitchNum = 0u;

OcGdDevice m_Gds[CI_GD_MAX];/*轨道设备*/
UINT16 m_GdNum = 0u;


UINT16 LocalOcIds[OC_SUM_MAX];

UINT8 xingshiTestStart = 0u;
UINT32 xingshiTestStartCycle = 0u;
UINT8 xingshiTestStop = 0u;
UINT32 xingshiTestStopCycle = 0u;


UINT8 ocsBoardsIsScatter[OC_SUM_MAX][BOARD_SUM_MAX][1] = { 0u }; /*各OC的各板卡是否零散板卡*/

UINT8 InitOcsBoardsIsScatter(void);

/*
* 功能描述： 把道岔驱动位置转化为道岔驱动命令
* 参数说明： 
*		输入参数：
*			UINT8 drvColor：道岔驱动位置
* 返回值  ： 0:道岔驱动命令转化失败
*			 1:道岔驱动命令    
*/
UINT16 ConvertSwitchDrvPosToSwDrvCmd(UINT8 drvPos)
{
	UINT16 retDrvCmd = 0u;
	switch(drvPos)
	{
	case SWITCH_DRIVE_POS_DINGWEI:
		retDrvCmd = OC_SWITCH_DRIVE_POS_DINGWEI;
		break;
	case SWITCH_DRIVE_POS_FANWEI:
		retDrvCmd = OC_SWITCH_DRIVE_POS_FANWEI;
		break;
	case SWITCH_DRIVE_POS_INVALID:
		retDrvCmd = OC_SWITCH_DRIVE_POS_KEEP;
		break;
	default:
		retDrvCmd = OC_SWITCH_DRIVE_POS_KEEP;
		break;
	}
	return retDrvCmd;
}

/*
* 功能描述： 把信号机驱动颜色转化为信号机驱动命令
* 参数说明： 
*		输入参数：
*			UINT8 drvColor：信号机驱动颜色
* 返回值  ： 0:信号机驱动命令转化失败
*			 1:信号机驱动命令      
*/
UINT16 ConvertSigDrvColorToSigDrvCmd(const UINT16 signalId, const UINT8 drvColor)
{
	UINT16 retDrvCmd = 0u;
	UINT8 ocHasBlue = 0u;
	UINT8 funSwitchGreenYellow = GetCiFunctionSwitchConfig(CI_FUNCTION_SWITCH_SHOW_SIGNAL_GreenYellow);/*显示绿黄功能开关是否打开*/
	UINT8 funSwitchALLCloseUseBlue = GetCiFunctionSwitchConfig(FUNC_SWITCH_ZX_ALLCLOSE_USEBLUE);/*杭德正线灭灯均转蓝灯功能开关*/
	UINT8 ciType = GetLocalCiType();
	switch (drvColor)
	{
	case SIGNAL_DRIVECOLOUR_RED:/*红*/
		/*信号机有蓝灯 只在车辆段设置红灯转驱蓝灯*/
		ocHasBlue = OcSignalHasBlue(signalId);
		if ((1u == ocHasBlue) &&(CI_TYPE_CLD == ciType))
		{
			retDrvCmd = OC_SIGNAL_DRIVECOLOR_BLUE;
		}
		else /*否则,驱红灯命令*/
		{
			retDrvCmd = OC_SIGNAL_DRIVECOLOR_RED;
		}
		break;
	case SIGNAL_DRIVECOLOUR_YELLOW:/*黄*/
		retDrvCmd = OC_SIGNAL_DRIVECOLOR_YELLOW;
		break;
	case SIGNAL_DRIVECOLOUR_REDYELLOW:/*红黄*/
		retDrvCmd = OC_SIGNAL_DRIVECOLOR_REDYELLOW;
		break;
	case SIGNAL_DRIVECOLOUR_GREEN:/*绿*/
		retDrvCmd = OC_SIGNAL_DRIVECOLOR_GREEN;
		break;
	case SIGNAL_DRIVECOLOUR_YELLOWCLOSE:/*黄灭*/
		if ((FUNC_SWITCH_ON == funSwitchGreenYellow)||(FUNC_SWITCH_ON == funSwitchALLCloseUseBlue))
		{
			retDrvCmd = OC_SIGNAL_DRIVECOLOR_BLUE;
		}
		else
		{
			retDrvCmd = OC_SIGNAL_DRIVECOLOR_CLOSE;
		}
		break;
	case SIGNAL_DRIVECOLOUR_REDCLOSE:/*红灭*/
		if (FUNC_SWITCH_ON == funSwitchALLCloseUseBlue)
		{
			retDrvCmd = OC_SIGNAL_DRIVECOLOR_BLUE;/*杭德红灭驱蓝需求*/
		}
		else
		{
			retDrvCmd = OC_SIGNAL_DRIVECOLOR_CLOSE;
		}
		break;
	case SIGNAL_DRIVECOLOUR_GREENCLOSE:/*绿灭*/
		if ((FUNC_SWITCH_ON == funSwitchGreenYellow) || (FUNC_SWITCH_ON == funSwitchALLCloseUseBlue))
		{
			retDrvCmd = OC_SIGNAL_DRIVECOLOR_BLUE;
		}
		else
		{
			retDrvCmd = OC_SIGNAL_DRIVECOLOR_CLOSE;
		}
		break;
	case SIGNAL_DRIVECOLOUR_WHITE:/*白*/
		retDrvCmd = OC_SIGNAL_DRIVECOLOR_WHITE;
		break;
	case SIGNAL_DRIVECOLOUR_RED_WHITE:/*红白*/
		retDrvCmd = OC_SIGNAL_DRIVECOLOR_REDWHITE;
		break;
	case SIGNAL_DRIVECOLOUR_GREENYELLOW:/*绿黄*/
		if (FUNC_SWITCH_ON == funSwitchGreenYellow)
		{
			retDrvCmd = OC_SIGNAL_DRIVECOLOR_GREENYELLOW;
		}
		else
		{
			retDrvCmd = OC_SIGNAL_DRIVECOLOR_RED;  /*无效*/
		}
		break;
	case SIGNAL_DRIVECOLOUR_GREENYELLOWCLOSE:/*绿黄灭*/
		if (FUNC_SWITCH_ON == funSwitchGreenYellow)
		{
			retDrvCmd = OC_SIGNAL_DRIVECOLOR_BLUE;
		}
		else
		{
			retDrvCmd = OC_SIGNAL_DRIVECOLOR_RED;  /*无效*/
		}
		break;
	case SIGNAL_DRIVECOLOUR_DOUBLE_GREEN:/*双绿*/
		if (FUNC_SWITCH_ON == funSwitchGreenYellow)
		{
			retDrvCmd = OC_SIGNAL_DRIVECOLOR_DOUBLEGREEN;
		}
		else
		{
			retDrvCmd = OC_SIGNAL_DRIVECOLOR_RED;  /*无效*/
		}
		break;
	case SIGNAL_DRIVECOLOUR_DOUBLE_YELLOW:/*双黄*/
		if (FUNC_SWITCH_ON == funSwitchGreenYellow)
		{
			retDrvCmd = OC_SIGNAL_DRIVECOLOR_DOUBLEYELLOW;
		}
		else
		{
			retDrvCmd = OC_SIGNAL_DRIVECOLOR_RED;  /*无效*/
		}
		break;
	case SIGNAL_DRIVECOLOUR_NULL:/*无效*/
		retDrvCmd = OC_SIGNAL_DRIVECOLOR_RED;
		break;
	default:
		retDrvCmd = OC_SIGNAL_DRIVECOLOR_RED;
		break;
	}
	return retDrvCmd;
}



/*
* 功能描述： 组OC数据
* 参数说明：  UINT8 deviceId, 设备ID
*            UINT8 deviceId, OC的ID
* 返回值  ： 0:组数据失败
*			 1:组数据成功      
*/
UINT8 PackCiToOcData( UINT8 deviceId)
{
	UINT8 Ci2OcDataBuffer[OC_TO_CI_DATA_LEN_MAX] = {0u};/*CI到VOBC组帧数组*/
	UINT8 siBoardNum = 0u; /*SI板卡数量*/
	UINT8 ciSiToOc[OC_TO_CI_DATA_LEN_MAX] = { 0u };/*CI的SI到OC组帧数组*/
	UINT32 ciSiToOcIdx = 0u; /*CI的SI到OC组帧数组下标*/
	UINT8 sorBoardNum = 0U;/*SOR板卡数量*/
	UINT8 ciSorToOc[OC_TO_CI_DATA_LEN_MAX] = { 0U };/*CI的SOR到OC组帧数组*/
	UINT32 ciSorToOcIdx = 0U; /*CI的SOR到OC组帧数组下标*/
	UINT32 pBoardNumStartIndex = 0u;/*驱动板数目下标索引*/
	UINT8 boardNum = 0u;/*板卡数目*/
	UINT16 i = 0u;
	UINT32 ii = 0u;
	UINT16 mm = 0u;
	UINT8 kk = 0u;
	UINT16 nn = 0u;
	UINT16 relayId = 0u;
	UINT8 relayDrvState = 0u;	
	UINT32 ciEtcsId = 0u;
	UINT32 ocEtcsId = 0u;
	UINT32 emapCheckVer = 0u;
	UINT8 retVal= CI_ERROR;
	UINT8 localCiId = GetSystemParaLocalCiId();  /*本地联锁ID*/
	UINT32 curCycleNum = Get2oo2CurCycleNum();	/*联锁应用周期号*/
	UINT32 appCycleTime = GetSystemParaAppCycleTime();	/*联锁应用周期*/
	UINT8 drvClor = 0u;/*信号机驱动颜色*/
	UINT8 drvPos = 0u;/*道岔驱动位置*/
	UINT16 drvCmd = 0u;/*驱动命令*/
	UINT16 tmpInd = 0u;/*临时索引*/
	OcToCiOriginDataStruct *pOcData = NULL; /*OC到CI数据结构*/
	UINT16 dstDevId = 0u;
	UINT8 outnetSafeSendRtn = 0u;
	UINT16 OcDevName = 0U; /*OC名称：类型+ID*/
	UINT8 chSwitch = GetCiFunctionSwitchConfig(FUNC_OC_100_OR_200);
	UINT8 chLocalOcType = GetLocalOcPattern(); /*OC类型*/
	UINT16 deviceSum = 0u;
	UINT16 kqChangeCommand = 0u;/*控权切换命令*/
#if 0
	QueueClear(CiToOcDataQueue);	/*清队列*/
#endif
	if (0u != deviceId)
	{
		retVal = CI_SUCCESS;
	}
	else
	{
	}

	if (CI_SUCCESS == retVal)
	{
		for (i = 0u; i < m_OcToCiOrginDataNum; i++)
		{
			if (m_OcToCiOrginDataArr[i].OcId == deviceId)
			{
				break;
			}
			else
			{
			}
		}
		pOcData = &m_OcToCiOrginDataArr[i];
		OcDevName = (CI_SYSTEM_TYPE_OC) * 256U + deviceId;
		emapCheckVer = GetCiTranOcDataCheckVer(localCiId, OcDevName);
		ciEtcsId = localCiId;
		ocEtcsId = deviceId;
		ShortToChar(CI_OC_INTERFACE, &Ci2OcDataBuffer[ii]);/*接口类型：CI-OC接口0206*/
		ii += 2u;
		LongToChar(ciEtcsId, &Ci2OcDataBuffer[ii]);/*发送方标识信息*/
		ii += 4u;
		LongToChar(ocEtcsId, &Ci2OcDataBuffer[ii]);/*接收方标识信息*/
		ii += 4u;
		LongToChar(emapCheckVer, &Ci2OcDataBuffer[ii]);/*电子地图版本校验信息*/
		ii += 4u;
		LongToChar(curCycleNum, &Ci2OcDataBuffer[ii]);/*本方消息序列号*/
		ii += 4u;
		ShortToChar((UINT16)appCycleTime, &Ci2OcDataBuffer[ii]);/*设备通讯周期*/
		ii += 2u;
		LongToChar(GetHLHTHeadCtxSrcCrntSN(CI_SYSTEM_TYPE_OC, (UINT8)pOcData->OcId), &Ci2OcDataBuffer[ii]);/*对方消息序列号：recvOppMsgSN记录收到对方上一条消息中的对方消息序列号*/
		ii += 4u;
		LongToChar(GetHLHTHeadCtxCiRcvSN(CI_SYSTEM_TYPE_OC, (UINT8)pOcData->OcId), &Ci2OcDataBuffer[ii]);/*收到上一条消息时本方序列号*/
		ii += 4u;
		Ci2OcDataBuffer[ii++] = (UINT8)CI_OC_PRTCL_VER;/*CI_OC接口协议版本号*/
		ii += 2u;/*通用报文头中的应用层报文总长度*/
		/****************以下是应用报文内容*************/

		ii += 2u;/*应用报文长度*/
		ShortToChar(CI_OC_CONTROL_INFO, &Ci2OcDataBuffer[ii]);
		ii += 2u;
		ii += 2u;/*预留2个字节*/

		if (OC_HAVE_YJK == pOcData->chHaveYjk)
		{
			deviceSum = pOcData->OcDeviceNum + 1u;		/*设备数量+控权切换*/
		}
		else
		{
			deviceSum = pOcData->OcDeviceNum;
		}
		
		ShortToChar(deviceSum, &Ci2OcDataBuffer[ii]);/*设备数量*/
		ii += 2u;
		for (kk = 0u; kk < pOcData->OcDeviceNum; kk++)/*遍历设备*/
		{
			if( MAX_OC_DEVICE_NUM == kk)
			{
				retVal = CI_ERROR;
				break;
			}
			else
			{
			}
			switch (pOcData->OcDevices[kk].DeviceType)
			{
				case CI_DEVICE_TYPE_SWITCH:/*道岔设备*/
				{
					Ci2OcDataBuffer[ii++] = CI_DEVICE_TYPE_SWITCH;
					ShortToChar(pOcData->OcDevices[kk].DeviceId, &Ci2OcDataBuffer[ii]);
					ii += 2u;
					drvPos = GetSwitchDrivePostion(pOcData->OcDevices[kk].DeviceId);
					drvCmd = ConvertSwitchDrvPosToSwDrvCmd(drvPos);
					ShortToChar(drvCmd, &Ci2OcDataBuffer[ii]);
					ii += 2u;
					break;
				}
				case CI_DEVICE_TYPE_SIGNAL:/*信号机设备*/
				{
					Ci2OcDataBuffer[ii++] = CI_DEVICE_TYPE_SIGNAL;
					ShortToChar(pOcData->OcDevices[kk].DeviceId, &Ci2OcDataBuffer[ii]);
					ii += 2u;
					drvClor = GetSignalCurDriveColor(pOcData->OcDevices[kk].DeviceId);/*获取信号机当前驱动颜色*/
					drvCmd = ConvertSigDrvColorToSigDrvCmd(pOcData->OcDevices[kk].DeviceId, drvClor);
					ShortToChar(drvCmd, &Ci2OcDataBuffer[ii]);
					ii += 2u;
					break;
				}
				default:
				{
					ii += 5u;
					break;
				}
			}
		}/*此为oc设备组包完毕*/
		
		if (OC_HAVE_YJK == pOcData->chHaveYjk)
		{
			Ci2OcDataBuffer[ii++] = CI_SYSTEM_TYPE_OC;/*控权切换*/
			ShortToChar(pOcData->OcId, &Ci2OcDataBuffer[ii]);/*设备ID*/
			ii += 2u;

			kqChangeCommand = GetKqChangeCommand();
			ShortToChar(kqChangeCommand, &Ci2OcDataBuffer[ii]);/*控权切换命令*/
			ii += 2u;
		}
		else
		{/*不处理*/
		}


		pBoardNumStartIndex = ii;/*结束赋值*/
		ii += 2u;/*跳过，最后赋值*/

		/*开始组包驱动板卡数据*/
		for (kk = 0u; kk < GetDrvRelayStructSum(); kk++)
		{
			BoardDataStruct* pDrvBoard = GetDrvRelayStruct();
			if (pDrvBoard[kk].OcId == pOcData->OcId)
			{
				/*零散输出板卡*/
				if (1u == ocsBoardsIsScatter[pOcData->OcId][pDrvBoard[kk].BoardAddress][0])
				{
					ciSiToOc[ciSiToOcIdx++] = 0u;
					ciSiToOc[ciSiToOcIdx++] = pDrvBoard[kk].BoardAddress;
					tmpInd = (UINT16)(ciSiToOcIdx);
					for (nn = 0u; nn < 24u / 2u; nn++)
					{/*先把所有的SI板卡继电器状态设置成驱动落下*/
						ciSiToOc[tmpInd] = (UINT8)(OC_RELAY_DOWN << 4u) + OC_RELAY_DOWN;
						tmpInd++;
					}
					/*填充继电器驱动命令 8B*/
					for (nn = 0u; nn < 24u / 2u; nn++)
					{
						relayId = pDrvBoard[kk].RelayIdBuf[nn * 2U];

						if ((0u != relayId) && (relayId < RELAY_SUM_MAX))
						{
							relayDrvState = GetRelayDriveState(relayId);/*填充到低字节*/

							if (RELAY_STATE_DOWN == relayDrvState)
							{ /*继电器驱动落下*/
								ciSiToOc[ciSiToOcIdx] = (ciSiToOc[ciSiToOcIdx] & 0xf0u) | OC_RELAY_DOWN;
							}
							else if (RELAY_STATE_UP == relayDrvState)
							{ /*继电器驱动吸起*/

								/*drvData = drvData | (0x0001 << jj);*/
								ciSiToOc[ciSiToOcIdx] = (ciSiToOc[ciSiToOcIdx] & 0xf0u) | OC_RELAY_UP;
							}
							else
							{ /*继电器驱动无效*/

								/*继电器落下*/
								ciSiToOc[ciSiToOcIdx] = (ciSiToOc[ciSiToOcIdx] & 0xf0u) | OC_RELAY_DOWN;
							}

						}
						else
						{
						}

						relayId = pDrvBoard[kk].RelayIdBuf[nn * 2U + 1U];

						if ((0u != relayId) && (relayId < RELAY_SUM_MAX))
						{
							relayDrvState = GetRelayDriveState(relayId);/*填充到高字节*/

							if (RELAY_STATE_DOWN == relayDrvState)
							{ /*继电器驱动落下*/
								ciSiToOc[ciSiToOcIdx] = (ciSiToOc[ciSiToOcIdx] & 0x0fu) | (UINT8)(OC_RELAY_DOWN << 4u);
							}
							else if (RELAY_STATE_UP == relayDrvState)
							{ /*继电器驱动吸起*/

								/*drvData = drvData | (0x0001 << jj);*/
								ciSiToOc[ciSiToOcIdx] = (ciSiToOc[ciSiToOcIdx] & 0x0fu) | (UINT8)(OC_RELAY_UP << 4u);
							}
							else
							{ /*继电器驱动无效*/

								/*继电器落下*/
								ciSiToOc[ciSiToOcIdx] = (ciSiToOc[ciSiToOcIdx] & 0x0fu) | (UINT8)(OC_RELAY_DOWN << 4u);
							}

						}
						else
						{
						}
						ciSiToOcIdx++;
					}

					siBoardNum++;

				}
				/*安全输出继电器板卡 SOR*/
				else if (2u == ocsBoardsIsScatter[pOcData->OcId][pDrvBoard[kk].BoardAddress][0])
				{
					ciSorToOc[ciSorToOcIdx++] = pDrvBoard[kk].BoardAddress;
					tmpInd = ciSorToOcIdx;
					for (nn = 0U; nn < 8u / 2u; nn++)
					{/*先把所有的SOR板卡继电器状态设置成驱动落下*/
						ciSorToOc[tmpInd] = (OC_RELAY_DOWN << 4) + OC_RELAY_DOWN;
						tmpInd++;
					}

					/*填充继电器驱动命令 8B*/
					for (nn = 0U; nn < 8u / 2u; nn++)
					{
						relayId = pDrvBoard[kk].RelayIdBuf[nn * 2u];

						if ((0U != relayId) && (relayId < RELAY_SUM_MAX))
						{
							relayDrvState = GetRelayDriveState(relayId);/*填充到低字节*/

							if (RELAY_STATE_DOWN == relayDrvState)
							{ /*继电器驱动落下*/
								ciSorToOc[ciSorToOcIdx] = (ciSorToOc[ciSorToOcIdx] & 0xf0U) | OC_RELAY_DOWN;
							}
							else if (RELAY_STATE_UP == relayDrvState)
							{ /*继电器驱动吸起*/

							  /*drvData = drvData | (0x0001 << jj);*/
								ciSorToOc[ciSorToOcIdx] = (ciSorToOc[ciSorToOcIdx] & 0xf0U) | OC_RELAY_UP;
							}
							else
							{ /*继电器驱动无效*/

							  /*继电器落下*/
								ciSorToOc[ciSorToOcIdx] = (ciSorToOc[ciSorToOcIdx] & 0xf0U) | OC_RELAY_DOWN;
							}

						}

						relayId = pDrvBoard[kk].RelayIdBuf[nn * 2U + 1U];

						if ((0U != relayId) && (relayId < RELAY_SUM_MAX))
						{
							relayDrvState = GetRelayDriveState(relayId);/*填充到高字节*/

							if (RELAY_STATE_DOWN == relayDrvState)
							{ /*继电器驱动落下*/
								ciSorToOc[ciSorToOcIdx] = (ciSorToOc[ciSorToOcIdx] & 0x0fU) | (UINT8)(OC_RELAY_DOWN << 4U);
							}
							else if (RELAY_STATE_UP == relayDrvState)
							{ /*继电器驱动吸起*/

							  /*drvData = drvData | (0x0001 << jj);*/
								ciSorToOc[ciSorToOcIdx] = (ciSorToOc[ciSorToOcIdx] & 0x0fU) | (UINT8)(OC_RELAY_UP << 4U);
							}
							else
							{ /*继电器驱动无效*/

							  /*继电器落下*/
								ciSorToOc[ciSorToOcIdx] = (ciSorToOc[ciSorToOcIdx] & 0x0fU) | (UINT8)(OC_RELAY_DOWN << 4U);
							}

						}
						ciSorToOcIdx++;
					}

					sorBoardNum++;
				}
				else
				{
					/*填充板卡地址 2B*/
					Ci2OcDataBuffer[ii++] = 0u;
					Ci2OcDataBuffer[ii++] = pDrvBoard[kk].BoardAddress;
					tmpInd = (UINT16)(ii);
					for (nn = 0u; nn < DRV_BOARD_POSITION_MAX / 2u; nn++)
					{/*先把所有的DO板卡继电器状态设置成驱动落下*/
						Ci2OcDataBuffer[tmpInd] = (UINT8)(OC_RELAY_DOWN << 4u) + OC_RELAY_DOWN;
						tmpInd++;
					}
					/*填充继电器驱动命令 8B*/
					for (nn = 0u; nn < DRV_BOARD_POSITION_MAX / 2u; nn++)
					{
						relayId = pDrvBoard[kk].RelayIdBuf[nn * 2u];

						if ((0u != relayId) && (relayId < RELAY_SUM_MAX))
						{
							relayDrvState = GetRelayDriveState(relayId);/*填充到低字节*/

							if (RELAY_STATE_DOWN == relayDrvState)
							{ /*继电器驱动落下*/
								Ci2OcDataBuffer[ii] = (Ci2OcDataBuffer[ii] & 0xf0u) | OC_RELAY_DOWN;
							}
							else if (RELAY_STATE_UP == relayDrvState)
							{ /*继电器驱动吸起*/

								/*drvData = drvData | (0x0001 << jj);*/
								Ci2OcDataBuffer[ii] = (Ci2OcDataBuffer[ii] & 0xf0u) | OC_RELAY_UP;
							}
							else
							{ /*继电器驱动无效*/

								/*继电器落下*/
								Ci2OcDataBuffer[ii] = (Ci2OcDataBuffer[ii] & 0xf0u) | OC_RELAY_DOWN;
							}

						}
						else
						{
						}

						relayId = pDrvBoard[kk].RelayIdBuf[nn * 2u + 1u];

						if ((0u != relayId) && (relayId < RELAY_SUM_MAX))
						{
							relayDrvState = GetRelayDriveState(relayId);/*填充到高字节*/

							if (RELAY_STATE_DOWN == relayDrvState)
							{ /*继电器驱动落下*/
								Ci2OcDataBuffer[ii] = (Ci2OcDataBuffer[ii] & 0x0fu) | (UINT8)(OC_RELAY_DOWN << 4u);
							}
							else if (RELAY_STATE_UP == relayDrvState)
							{ /*继电器驱动吸起*/

								/*drvData = drvData | (0x0001 << jj);*/
								Ci2OcDataBuffer[ii] = (Ci2OcDataBuffer[ii] & 0x0fu) | (UINT8)(OC_RELAY_UP << 4u);
							}
							else
							{ /*继电器驱动无效*/

								/*继电器落下*/
								Ci2OcDataBuffer[ii] = (Ci2OcDataBuffer[ii] & 0x0fu) | (UINT8)(OC_RELAY_DOWN << 4u);
							}

						}
						else
						{
						}
						ii++;
					}

					boardNum++;

				}
				
			}
			else
			{
			}
		}
		Ci2OcDataBuffer[pBoardNumStartIndex] = (UINT8)((boardNum >> 8u) & 0xffu);
		Ci2OcDataBuffer[pBoardNumStartIndex + 1U] = (UINT8)(boardNum & 0xffu);

		ShortToChar(siBoardNum, &Ci2OcDataBuffer[ii]);
		ii += 2u;
		(void)CommonMemCpy(&Ci2OcDataBuffer[ii], OC_TO_CI_DATA_LEN_MAX-ii, ciSiToOc, ciSiToOcIdx);
		ii += ciSiToOcIdx;

		if ((FUNC_SWITCH_ON == chSwitch)&&(DATA_TYPE_NEW == chLocalOcType))
		{
			/*OC200 数据结构25以上才支持SOR*/
			Ci2OcDataBuffer[ii] = sorBoardNum;
			ii += 1U;
			(void)CommonMemCpy(&Ci2OcDataBuffer[ii], OC_TO_CI_DATA_LEN_MAX - ii, ciSorToOc, ciSorToOcIdx);
			ii += ciSorToOcIdx;
		}		

#if 0 /*屏蔽型式实验，以后有需要再打开*/
		if (curCycleNum == xingshiTestStartCycle && 1 == xingshiTestStart)
		{
			Ci2OcDataBuffer[ii++] = 0xaa;
			Ci2OcDataBuffer[ii++] = 0xbb;
		}
		else if (curCycleNum == xingshiTestStopCycle && 1 == xingshiTestStop)
		{
			Ci2OcDataBuffer[ii++] = 0xcc;
			Ci2OcDataBuffer[ii++] = 0xdd;
		}
		else
		{
			Ci2OcDataBuffer[ii++] = 0xff;
			Ci2OcDataBuffer[ii++] = 0xff;
		}
#endif
		/*OC100、OC数据结构24 接口保留预留20字节*/
		if ((FUNC_SWITCH_OFF == chSwitch) || (DATA_TYPE_OLD == chLocalOcType)) 
		{
			Ci2OcDataBuffer[ii++] = 0xffu;
			Ci2OcDataBuffer[ii++] = 0xffu;
			for (mm = 2u; mm < 20u; mm++)/*预留*/
			{
				Ci2OcDataBuffer[ii++] = 0xffu;
			}
		}
		else
		{
			; /*OC200 且OC3.0删除预留20字节*/
		}

		Ci2OcDataBuffer[31] = (UINT8)(((ii - 33U) >> 8u) & 0xffu);
		Ci2OcDataBuffer[32] = (UINT8)((ii - 33U) & 0xffu);/*填充长度*/

		Ci2OcDataBuffer[29] = (UINT8)(((ii - 31U) >> 8u) & 0xffu);
		Ci2OcDataBuffer[30] = (UINT8)((ii - 31U) & 0xffu);

		dstDevId = ((UINT16)(CI_SYSTEM_TYPE_OC << 8u) | ((UINT16)deviceId));
		outnetSafeSendRtn = OutnetSafeSend(dstDevId, 0u, &Ci2OcDataBuffer[0], ii);
		if (1u == outnetSafeSendRtn)
		{ /*写队列成功*/
#ifdef LOGPRINT/*日志打印宏*/                 
#ifdef PLATFORM_2OO2/*2oo2平台打印*/
			debug_infor_printf((const)"\nOC_SEND:%d", ii);
			debug_out_array(0xAA, Ci2OcDataBuffer, (UINT16)ii);
#endif/*平台打印结束*/
#endif
		}
		else
		{
			/*写队列失败*/
			retVal = CI_ERROR;
		}

			
	}
	else
	{
	}
	
	

	return retVal;
}


/*
* 功能描述： 校验Oc到CI的单帧数据长度合法性
* 参数说明： const UINT8* dataBuf, 数据缓冲区
*            const UINT16 dataLength, 数据长度
* 返回值  ： 0: 数据解析失败
*			 1: 数据解析成功      
*/
UINT8 CheckOc2CiDataLenValid(const UINT8* dataBuf, const UINT16 totalLength)
{
	/*OC100长度校验：总长度=32(GAL头包长度) + 1(协议版本)+ 2(GAL总长度) + 2(应用总长度) +2(消息类型0x8802) +2(预留) +
		*					2（设备数量m）+ 8*m +
		*					2（轨道数量n）+ 8*n + 
		*					2 (DI板卡数量p) + 20*p + 
		*					2 (DO板卡数量q) + 2*q
		*					2 (零散输入板卡数量r) + 14*r + 
		*					2 (零散输出板卡数量s) + 2*s				
		* 设备数量索引 = 32+1+2+2+2+2 
		* 轨道区段索引 = 32+1+2+2+2+2+  2+8m
		* DI板卡数量索引 = 32+1+2+2+2+  2+8m+2+8n
		* DO板卡数量索引 = 32+1+2+2+2+  2+8m+2+8n+2+20*p
		* 零散输入板卡数量索引 = 32+1+2+2+2+  2+8m+2+8n+2+20*p+2*q
		* 零散输出板卡数量索引 = 32+1+2+2+2+  2+8m+2+8n+2+2*r+2*q+14*r
		*OC200 3.0长度校验：修改设备信息
		*					1（道岔数量m）+ (3+1（转辙机个数z）+z+1（板卡数量b）+2b）*m+
		*					1（信号机个数x）+7*x+
		*                   轨道区段、DI/DO/SI/DO板卡未修改
		* 新增          1 (SOR板卡数量h) + 7h + 
	*/
		
	UINT8 retVal = CI_ERROR;
	UINT16 devNumber = 0u;/*设备数量*/
	UINT8 switchNum = 0u;/*道岔设备数量*/
	UINT8 switchBoardNum = 0U; /*道岔板卡数量*/
	UINT8 signalNum = 0u;/*信号机设备数量*/
	UINT16 gdBoardNumber = 0u;/*轨道板数量*/
	UINT16 diBoardNumber = 0u;/*DI板卡数量*/
	UINT16 doBoardNumber = 0u;/*DO板卡数量*/
	UINT16 siBoardNumber = 0u;/*SI板卡数量*/
	UINT16 soBoardNumber = 0u;/*SO板卡数量*/
	UINT8 sorBoardNumber = 0u;/*SOR板卡数量*/
	UINT16 SwapBoardNumber = 0U;/*切系板卡数量*/
	UINT8 chPbNumber = 0u;	/*执行电插箱数量*/
	UINT8 chPsdNumber = 0u;	/*屏蔽门数量*/

	UINT16 upToGDNumber = 0u;
	UINT16 upToDIBoardNumber = 0u;
	UINT16 upToDOBoardNumber = 0u;
	UINT16 upToSIBoardNumber = 0u;
	UINT16 upToSOBoardNumber = 0u;
	UINT16 upToSORBoardNumber = 0u;
	UINT16 upToPbNumer = 0u;/*到执行电插箱数据个数*/
	UINT16 upToSwapSysBoardNumber = 0U;
	UINT16 upToPsdNumber = 0U;
	UINT16 tmpTotalLen = 0u;/*临时变量：总长度*/
	UINT8 chSwitch = 0u;
	UINT8 ocInterfaceFlag = 0u;/*与OC接口标识*/
	UINT8 ii = 0U;/*设备数量的循环变量*/
	UINT16 wDevInfoIndex = LEN_OC_UP_TO_DEV_NO-1U;/*道岔包含转辙机个数索引 oc200使用*/
	UINT16 wZzjStateNumber = 0U;/*转辙机状态所占字节数*/
	UINT8 chLocalOcType = GetLocalOcPattern(); /*获取OC版本信息*/
	UINT16 wSwitchIncludeZzjIndex = LEN_OC_UP_TO_DEV_NO;/*道岔包含转辙机个数索引*/
	UINT16 wOffSet = 0U;
	if(NULL != dataBuf)
	{
		retVal = CI_SUCCESS;
		chSwitch = GetCiFunctionSwitchConfig(FUNC_OC_100_OR_200);
		ocInterfaceFlag = GetCiFunctionSwitchConfig(FUNC_OC_INTERFACE_CONF);
		if (totalLength < LEN_OC_UP_TO_DEV_NO)
		{/*校验OC数据从开始到设备数量截止，计算设备数量*/
			retVal = CI_CHECK_LEN_ERROR;
		}
		else
		{
			;  /*继续*/
		}
	}

	if (FUNC_SWITCH_ON == chSwitch)
	{
		/*OC-200  且较新OC接口校验*/
		
		if (CI_SUCCESS == retVal)
		{/*校验OC数据从开头到轨道板数据截止，计算轨道板数量*/

			if (DATA_TYPE_NEW == chLocalOcType)
			{
				/*计算道岔数据长度*/
				switchNum = dataBuf[LEN_OC_UP_TO_DEV_NO - 2U];
				for (ii = 0U; ii < switchNum; ii++)
				{
					wDevInfoIndex += 3U;
					wZzjStateNumber = wZzjStateNumber + (UINT16)(dataBuf[wDevInfoIndex] * 1U);
					wDevInfoIndex += 1U + (UINT16)dataBuf[wDevInfoIndex] * 1U;
					switchBoardNum += (UINT8)dataBuf[wDevInfoIndex];
					wDevInfoIndex += 1U + (UINT16)dataBuf[wDevInfoIndex] * 2U;
				}
				/*计算信号机数据*/
				signalNum = dataBuf[wDevInfoIndex];
				//wDevInfoIndex += 1U;
				upToGDNumber = (UINT16)LEN_OC_UP_TO_GD_NO_200(wZzjStateNumber, (UINT16)switchNum, (UINT16)switchBoardNum, (UINT16)signalNum);
				wDevInfoIndex = upToGDNumber;
			}
			else
			{
				/*OC数据结构24对应OC*/
				devNumber = ShortFromChar(&dataBuf[LEN_OC_UP_TO_DEV_NO - 2U]);
				for (ii = 0U; ii < devNumber; ii++)
				{
					wSwitchIncludeZzjIndex += 4U;
					wZzjStateNumber = wZzjStateNumber +(UINT16)(dataBuf[wSwitchIncludeZzjIndex] * 1U);
					wSwitchIncludeZzjIndex += 1U + (UINT16)(dataBuf[wSwitchIncludeZzjIndex] * 1U) + 4U;
				}
				upToGDNumber = LEN_OC_UP_TO_GD_NO_200_2(devNumber, wZzjStateNumber);
				wDevInfoIndex = upToGDNumber;
			}
			if (totalLength < upToGDNumber)
			{
				retVal = CI_CHECK_LEN_ERROR;
			}
			else
			{
				/*校验成功，计算轨道板数量*/
				gdBoardNumber = ShortFromChar(&dataBuf[upToGDNumber - 2U]);
			}
		}

		if (CI_SUCCESS == retVal)
		{/*校验OC数据从开头到DI板数据截止，计算DI板数量*/
			upToDIBoardNumber = LEN_OC_UP_TO_DIBOARD_NO_200(wDevInfoIndex, gdBoardNumber);

			if (totalLength < upToDIBoardNumber)
			{
				retVal = CI_CHECK_LEN_ERROR;
			}
			else
			{
				/*校验成功，计算DI板卡数量*/
				diBoardNumber = ShortFromChar(&dataBuf[upToDIBoardNumber - 2U]);
			}
		}

		if (CI_SUCCESS == retVal)
		{/*校验OC数据从开头到DO板数据截止，计算DO板数量*/
			upToDOBoardNumber = LEN_OC_UP_TO_DOBOARD_NO_200(wDevInfoIndex, gdBoardNumber, diBoardNumber);
			if (totalLength < upToDOBoardNumber)
			{
				retVal = CI_CHECK_LEN_ERROR;
			}
			else
			{
				/*校验成功，计算do板卡数量*/
				doBoardNumber = ShortFromChar(&dataBuf[upToDOBoardNumber - 2U]);
			}
		}

		if (CI_SUCCESS == retVal)
		{/*校验OC数据从开头到SI板数据截止，计算SI板数量*/
			upToSIBoardNumber = LEN_OC_UP_TO_SIBOARD_NO_200(wDevInfoIndex, gdBoardNumber, diBoardNumber, doBoardNumber);
			if (totalLength < upToSIBoardNumber)
			{
				retVal = CI_CHECK_LEN_ERROR;
			}
			else
			{
				/*校验成功，计算si板卡数量*/
				siBoardNumber = ShortFromChar(&dataBuf[upToSIBoardNumber - 2U]);
			}
		}

		if (CI_SUCCESS == retVal)
		{/*校验OC数据从开头到SO板数据截止，计算SO板数量*/
			upToSOBoardNumber = LEN_OC_UP_TO_SOBOARD_NO_200(wDevInfoIndex, gdBoardNumber, diBoardNumber, doBoardNumber, siBoardNumber);
			if (totalLength < upToSOBoardNumber)
			{
				retVal = CI_CHECK_LEN_ERROR;
			}
			else
			{
				/*校验成功，计算so板卡数量*/
				soBoardNumber = ShortFromChar(&dataBuf[upToSOBoardNumber - 2U]);
			}
		}
		if (DATA_TYPE_NEW == chLocalOcType)
		{
			wOffSet = 0U;
			if (CI_SUCCESS == retVal)
			{/*校验OC数据从开头到SOR板数据截止，计算SOR板数量*/
				upToSORBoardNumber = LEN_OC_UP_TO_SORBOARD_NO_200(wDevInfoIndex, gdBoardNumber, diBoardNumber, doBoardNumber, siBoardNumber, soBoardNumber);
				if (totalLength < upToSORBoardNumber)
				{
					retVal = CI_CHECK_LEN_ERROR;
				}
				else
				{
					/*校验成功，计算sor板卡数量*/
					sorBoardNumber = dataBuf[upToSORBoardNumber - 1U];
				}
			}
		}
		else
		{
			/*不支持SOR*/
			wOffSet = 1U;
			sorBoardNumber = 0U;
		}

		if (CI_SUCCESS == retVal)
		{/*校验OC数据从开头到执行电插箱数据截止，计算执行电插箱数量*/
			upToPbNumer = LEN_OC_UP_TO_PLUSBOX_NO_200(wDevInfoIndex, gdBoardNumber, diBoardNumber, doBoardNumber, siBoardNumber, soBoardNumber, (UINT16)sorBoardNumber);
			if (totalLength < upToPbNumer)
			{
				retVal = CI_CHECK_LEN_ERROR;
			}
			else
			{
				/*校验成功，计算执行电插箱数量*/
				chPbNumber = dataBuf[upToPbNumer - 1U- wOffSet];
			}
		}

		if (CI_SUCCESS == retVal)
		{/*校验OC数据从开头到切系板卡数据截止，计算切系板卡数量*/
			upToSwapSysBoardNumber = LEN_OC_UP_TO_SWAPSYSBOARD_NO_200(wDevInfoIndex, gdBoardNumber, diBoardNumber, doBoardNumber, siBoardNumber, soBoardNumber, (UINT16)sorBoardNumber, (UINT16)chPbNumber);
			upToSwapSysBoardNumber -= wOffSet;
			if (totalLength < upToSwapSysBoardNumber)
			{
				retVal = CI_CHECK_LEN_ERROR;
			}
			else
			{
				/*校验成功，计算切系板卡数量*/
				SwapBoardNumber = ShortFromChar(&dataBuf[upToSwapSysBoardNumber - 2U]);
			}
		}

		if (CI_SUCCESS == retVal)
		{/*校验OC数据从开头到屏蔽门数据截至，计算屏蔽门数量*/
			upToPsdNumber = LEN_OC_UP_TO_END_200(wDevInfoIndex, gdBoardNumber, diBoardNumber, doBoardNumber, siBoardNumber, soBoardNumber, (UINT16)sorBoardNumber, (UINT16)chPbNumber, SwapBoardNumber);
			upToPsdNumber -= wOffSet;
			if (totalLength < upToPsdNumber)
			{
				retVal = CI_CHECK_LEN_ERROR;
			}
			else if (totalLength == upToPsdNumber)
			{/*长度已经相等，后面没有屏蔽门数据*/
				if (CI_SUCCESS == retVal)
				{/*校验总数据长度*/
					tmpTotalLen = LEN_OC_UP_TO_END_200(wDevInfoIndex, gdBoardNumber, diBoardNumber, doBoardNumber, siBoardNumber, soBoardNumber, (UINT16)sorBoardNumber, (UINT16)chPbNumber, SwapBoardNumber);
					tmpTotalLen -= wOffSet;
					if (totalLength == tmpTotalLen)
					{
						retVal = CI_SUCCESS;
					}
					else
					{
						retVal = CI_CHECK_LEN_ERROR;
					}
				}
			}
			else
			{
				/*后面还有数据，即OC-200 3.3、OC-300 1.0.1*/
				if (OC200_VER3_2_AFTER == ocInterfaceFlag)
				{/*OC-200 3.2之后的版本，有应急盘数据*/
					if (OC_HAVE_YJK == dataBuf[upToPsdNumber])
					{/*具备应急控*/
						tmpTotalLen = upToPsdNumber + 3u;
					}
					else
					{/*不具备应急控*/
						tmpTotalLen = upToPsdNumber + 1u;
					}

					if (totalLength == tmpTotalLen)
					{
						retVal = CI_SUCCESS;
					}
					else
					{
						retVal = CI_CHECK_LEN_ERROR;
					}
				}
				else if (OC300_VER1_0_1_ANDAFTER == ocInterfaceFlag)
				{/*OC-300 1.0.1之后的版本，有屏蔽门数据和应急盘数据*/
					chPsdNumber = dataBuf[upToPsdNumber];

					if (CI_SUCCESS == retVal)
					{/*校验总数据长度*/
						tmpTotalLen = LEN_OC_UP_TO_END_300(wDevInfoIndex, gdBoardNumber, diBoardNumber, doBoardNumber, siBoardNumber, soBoardNumber, (UINT16)sorBoardNumber, (UINT16)chPbNumber, SwapBoardNumber, (UINT16)chPsdNumber);
						tmpTotalLen -= wOffSet;

						/*屏蔽门数据与应急控数据一起发*/
						if (OC_HAVE_YJK == dataBuf[tmpTotalLen])
						{/*具备应急控*/
							tmpTotalLen += 3u;
						}
						else
						{/*不具备应急控*/
							tmpTotalLen += 1u;
						}

						if (totalLength == tmpTotalLen)
						{
							retVal = CI_SUCCESS;
						}
						else
						{
							retVal = CI_CHECK_LEN_ERROR;
						}
					}
				}
				else
				{
				}
			}
		}
		
	}
	else if (FUNC_SWITCH_OFF == chSwitch)
	{
		/*OC-100接口*/
		devNumber = ShortFromChar(&dataBuf[LEN_OC_UP_TO_DEV_NO - 2U]);
		if (CI_SUCCESS == retVal)
		{/*校验OC数据从开头到轨道板数据截止，计算轨道板数量*/
			upToGDNumber = LEN_OC_UP_TO_GD_NO(devNumber);

			if (totalLength < upToGDNumber)
			{
				retVal = CI_CHECK_LEN_ERROR;
			}
			else
			{
				/*校验成功，计算轨道板数量*/
				gdBoardNumber = ShortFromChar(&dataBuf[upToGDNumber - 2U]);
			}
		}

		if (CI_SUCCESS == retVal)
		{/*校验OC数据从开头到DI板数据截止，计算DI板数量*/
			upToDIBoardNumber = LEN_OC_UP_TO_DIBOARD_NO(devNumber, gdBoardNumber);

			if (totalLength < upToDIBoardNumber)
			{
				retVal = CI_CHECK_LEN_ERROR;
			}
			else
			{
				/*校验成功，计算DI板卡数量*/
				diBoardNumber = ShortFromChar(&dataBuf[upToDIBoardNumber - 2U]);
			}
		}

		if (CI_SUCCESS == retVal)
		{/*校验OC数据从开头到DO板数据截止，计算DO板数量*/
			upToDOBoardNumber = LEN_OC_UP_TO_DOBOARD_NO(devNumber, gdBoardNumber, diBoardNumber);
			if (totalLength < upToDOBoardNumber)
			{
				retVal = CI_CHECK_LEN_ERROR;
			}
			else
			{
				/*校验成功，计算do板卡数量*/
				doBoardNumber = ShortFromChar(&dataBuf[upToDOBoardNumber - 2U]);
			}
		}

		if (CI_SUCCESS == retVal)
		{/*校验OC数据从开头到SI板数据截止，计算SI板数量*/
			upToSIBoardNumber = LEN_OC_UP_TO_SIBOARD_NO(devNumber, gdBoardNumber, diBoardNumber, doBoardNumber);
			if (totalLength < upToSIBoardNumber)
			{
				retVal = CI_CHECK_LEN_ERROR;
			}
			else
			{
				/*校验成功，计算do板卡数量*/
				siBoardNumber = ShortFromChar(&dataBuf[upToSIBoardNumber - 2U]);
			}
		}

		if (CI_SUCCESS == retVal)
		{/*校验OC数据从开头到SO板数据截止，计算SO板数量*/
			upToSOBoardNumber = LEN_OC_UP_TO_SOBOARD_NO(devNumber, gdBoardNumber, diBoardNumber, doBoardNumber, siBoardNumber);
			if (totalLength < upToSOBoardNumber)
			{
				retVal = CI_CHECK_LEN_ERROR;
			}
			else
			{
				/*校验成功，计算do板卡数量*/
				soBoardNumber = ShortFromChar(&dataBuf[upToSOBoardNumber - 2U]);
			}
		}

		if (CI_SUCCESS == retVal)
		{/*校验OC数据从开头到切系板卡数据截止，计算切系板卡数量*/
			upToSwapSysBoardNumber = LEN_OC100_UP_TO_SWAPSYSBOARD_NO(devNumber, gdBoardNumber, diBoardNumber, doBoardNumber, siBoardNumber, soBoardNumber);
			if (totalLength < upToSwapSysBoardNumber)
			{
				retVal = CI_CHECK_LEN_ERROR;
			}
			else
			{
				/*校验成功，计算切系板卡数量*/
				SwapBoardNumber = ShortFromChar(&dataBuf[upToSwapSysBoardNumber - 2U]);
			}
		}

		if (CI_SUCCESS == retVal)
		{/*校验总数据长度*/
			tmpTotalLen = LEN_OC100_UP_TO_END(devNumber, gdBoardNumber, diBoardNumber, doBoardNumber, siBoardNumber, soBoardNumber, SwapBoardNumber);
			if (totalLength == tmpTotalLen)
			{
				retVal = CI_SUCCESS;
			}
			else
			{
				retVal = CI_CHECK_LEN_ERROR;
			}
		}
	}
	else
	{
		retVal = CI_CHECK_LEN_ERROR;
	}
	return retVal;
}

/*
* 功能描述： 重置oc原始状态
* 参数说明： const UINT8 ocId, ocId
* 返回值  ： void
*			       
*/
void ResetOcOriginalState(const UINT8 ocId)
{
	UINT16 ii=0u;
	UINT16 jj=0u;
	UINT16 toFindIndex = 0u;/*查找到的索引*/
	UINT8 findFlag = 0u;/*查找标志，0：未找到  1：找到*/
	for (ii=0u;ii<m_OcToCiOrginDataNum;ii++)
	{
		if(OC_SUM_MAX > ii)
		{            	
			if (m_OcToCiOrginDataArr[ii].OcId == ocId)
			{
				toFindIndex = ii;
				findFlag = 1u;
				break;
			}
		}
	}
	if (1u == findFlag)
	{/*找到*/
		for (ii=0u;ii<m_OcToCiOrginDataArr[toFindIndex].OcDeviceNum;ii++)
		{
			OcDeviceStruct* pDev = &(m_OcToCiOrginDataArr[toFindIndex].OcDevices[ii]);
			switch(pDev->DeviceType)
			{
			case OC_DEVICE_TYPE_SWITCH:
				{
					pDev->DeviceState = OC_SWITCH_POSITION_SIKAI;/*置道岔位置为四开*/
					for (jj = 0U; jj < pDev->chSwitchIncldeZzjNum; jj++)
					{
						pDev->szSwitchIncldeZzjState[jj] = OC_SWITCH_POSITION_SIKAI;/*置转辙机状态为四开*/
					}
				}
				break;
			case OC_DEVICE_TYPE_SIGNAL:
				{
				pDev->DeviceState = OC_SIGNAL_SHOWCOLOR_RED_BREAK; /*置信号机显示颜色为红断*/
				}
				break;
			default:
				/* 3轨道区段/CC采集板卡/DD驱动板卡*/
				break;
			}
		}

		for (ii=0u;ii<m_OcToCiOrginDataArr[toFindIndex].OcGdNum;ii++)
		{
			OcGdDevice *pGdDev = &(m_OcToCiOrginDataArr[toFindIndex].OcGdDevices[ii]);
			pGdDev->GdState1 = OC_GD_STATE_OCCUPY;
			pGdDev->GdState2 = OC_GD_STATE_OCCUPY;
			pGdDev->GdMergeState = OC_GD_STATE_OCCUPY;/*置A/B系轨道状态为占用*/
		}
		
		for (ii=0u;ii<m_OcToCiOrginDataArr[toFindIndex].OcDIBoardDataNum;ii++)
		{
			OcDIBoard *pDIBoard = &(m_OcToCiOrginDataArr[toFindIndex].OcDIBoardDatas[ii]);
			for (jj=0u;jj<18u;jj++)
			{
				pDIBoard->BoardCollData[jj] = 0xaau;/*置DI板卡继电器数据全部落下*/
			}
		}

		for (ii = 0u; ii<m_OcToCiOrginDataArr[toFindIndex].OcSORBoardNum; ii++)
		{
			OcDIBoard *pDIBoard = &(m_OcToCiOrginDataArr[toFindIndex].OcSORBoardDatas[ii]);
			for (jj = 0u; jj<5u; jj++)
			{
				pDIBoard->BoardCollData[jj] = 0xaau;/*置SOR板卡继电器数据全部落下*/
			}
		}

		SetOcToCiDefaultDataStru(toFindIndex);/*置屏蔽门信息为安全侧*/

		m_OcToCiOrginDataArr[toFindIndex].PowerAState = (UINT8)0xff;
		m_OcToCiOrginDataArr[toFindIndex].PowerBState = (UINT8)0xff;
		m_OcToCiOrginDataArr[toFindIndex].OCDevFaultState = (UINT8)0xff;
		m_OcToCiOrginDataArr[toFindIndex].FanState = (UINT8)0xff;

		for (ii = 0u; ii < m_OcToCiOrginDataArr[toFindIndex].OCBoardSwapSysNum; ii++)
		{
			m_OcToCiOrginDataArr[toFindIndex].SwapSysBoardId[ii] = 0U;
		}
		m_OcToCiOrginDataArr[toFindIndex].OCBoardSwapSysNum = 0U;

		CommonMemSet(m_OcToCiOrginDataArr[toFindIndex].szPlusBox, (UINT32)(MAX_OC_PLUS_BOX_NUM)*(sizeof(OcPlusBox)), 0U, (UINT32)(MAX_OC_PLUS_BOX_NUM*(sizeof(OcPlusBox))));
		m_OcToCiOrginDataArr[toFindIndex].chPbNum = 0U;

		SetAllCleFarePCBButKeepSta(m_OcToCiOrginDataArr[toFindIndex].OcId, QK_PSD_BUTTON_STATE_UP);
	}
}

/*
* 功能描述： 解析Oc到CI的单帧数据到缓存
* 参数说明： const UINT8* dataBuf, 数据缓冲区
*            const UINT16 dataLength, 数据长度
* 返回值  ： 0: 数据解析失败
*			 1: 数据解析成功      
*/
UINT8 ParseOcToCiDataFrame(const UINT8* dataBuf, const UINT16 dataLength,const UINT8 systemId)
{
	UINT8 retVal = CI_ERROR;
	UINT8 localCiId = 0u;					/*联锁ID*/
	
	UINT16 ii = 0u;       /*索引管理*/
	UINT8 j = 0u;
	UINT8 k = 0U;
	UINT8 tmpDeviceType = 0u; /*设备类型 1B*/
	UINT8 tmpSwitchNum = 0U;/*道岔数量*/
	UINT8 tmpSignalNum = 0U;/*道岔数量*/
	UINT16 tmpDeviceId = 0u; /*设备Id 2B*/
	UINT8 tmpDeviceState = 0u; /*设备状态 1B*/
	UINT8 tmpSwitchBoardNum = 0U; /*道岔板卡数量*/
	UINT8 switchBoardCheck = CI_ERROR; /*道岔状态检查*/
	UINT8 tmpBoardAddr1 = 0u;/*1系板卡地址 1B*/
	UINT8 tmpBoardState1 = 0u; /*1系板卡状态 2B*/

	UINT8 tmpBoardAddr2 = 0u;	/*板卡地址*/
	UINT8 tmpBoardState2 = 0u;	/*板卡状态 正常0x0000 错误发错误码*/
	UINT8 tmpBoardCollData[18] = {0u};	/*采集数据*/
	
	UINT16 ocName = 0u; /*与ci通信的oc Name 0x46*/
	UINT8 headRet = HLHT_HEAD_ERROR;

	UINT8* sourceId = NULL;		/*源ID*/
	UINT32 curntCycleNo = 0u;				/*当前周期号*/
	HLHTGALInfoStruct hlhtGalHead= {0u};
	INT32 ocInfoRemainValidity = 0;

	UINT16 appInfoType = 0u;						 /*应用信息类型*/
	OcToCiOriginDataStruct * pTmpOcToCiData = NULL;
	UINT8 toUpdateOcIndex = 0u;
	UINT8 findFlag = 0u;
	UINT16 tmpGdId = 0u;/*临时变量：临时轨道Id*/
	UINT16 curBoardNum = 0u; /*当前板子数量*/
	UINT16 curBoardSwapSysNum = 0U;/*切系板卡数量*/
	UINT8 curPsdNum = 0u;	/*PSD数量*/
	UINT32 psdId = 0u;      /*PSD 编号*/
	UINT16 psdIndexId = 0u; /*PSD 编号ID*/
	UINT8 funcRet = 0u;		/*PSD编号查询id函数返回值*/

	UINT32 galOcDataVer = 0U;
	UINT8 chPbIndex = 0u;
	UINT8 chSwitch = 0u;
	UINT8 chZzjStateIndex = 0u;/*道岔对应转辙机状态索引*/
	UINT8 chOcType = GetLocalOcPattern(); /*获取OC数据结构类型*/
	UINT8 ocInterfaceFlag = 0u;	/*与OC接口标识*/

	for (j=0u;j<m_OcToCiOrginDataNum;j++)
	{
		if (m_OcToCiOrginDataArr[j].OcId == systemId)
		{
			toUpdateOcIndex = j;
			findFlag = 1u;
			break;
		}
		toUpdateOcIndex = m_OcToCiOrginDataNum;/*如果没找到，那么更新索引为OcToCiDataNum*/
	}
	debug_infor_printf((const)"parsepackoc toUpdateOcIndex:%d  m_OcToCiOrginDataNum:%d  systemId:%d",toUpdateOcIndex,m_OcToCiOrginDataNum,systemId);
	pTmpOcToCiData = &(m_OcToCiOrginDataArr[toUpdateOcIndex]);

	if ((NULL != dataBuf) && (dataLength > 0u))
	{/*校验OC到ci的数据有效性*/
		retVal = CheckOc2CiDataLenValid(dataBuf,dataLength);
	}
	else
	{
		retVal = CI_ERROR;
	}
	

	if (CI_SUCCESS == retVal)
	{
		/* 获取OC型号（0xaa:200，0x55:100） */
		chSwitch = GetCiFunctionSwitchConfig(FUNC_OC_100_OR_200);
		ocInterfaceFlag = GetCiFunctionSwitchConfig(FUNC_OC_INTERFACE_CONF);
		sourceId = GetCiTransmitSpecifySysDevBuf(CI_SYSTEM_TYPE_OC);/*获取与本联锁通信的OC的ID*/
		
		ii+=4u;/*跳4个字节，以后oc处理*/
		/*解析通用消息包头*/
		hlhtGalHead.devInterInfoType = ShortFromChar(&dataBuf[ii]);
		ii += 2u;
		hlhtGalHead.sourceId = LongFromChar(&dataBuf[ii]);
		ii += 4u;
		hlhtGalHead.destId = LongFromChar(&dataBuf[ii]);
		ii += 4u;
		hlhtGalHead.emapVerCrc = LongFromChar(&dataBuf[ii]);
		ii += 4u;
		hlhtGalHead.crntOwnMsgSN = LongFromChar(&dataBuf[ii]);
		ii += 4u;
		hlhtGalHead.comPeriod = ShortFromChar(&dataBuf[ii]);
		ii += 2u;
		hlhtGalHead.recvOppMsgSN = LongFromChar(&dataBuf[ii]);
		ii += 4u;
		hlhtGalHead.preOwnMsgSN = LongFromChar(&dataBuf[ii]);
		ii += 4u;
		hlhtGalHead.prtclVer = dataBuf[ii++];
		hlhtGalHead.totalDataLen = ShortFromChar(&dataBuf[ii]);
		ii += 2u;

		curntCycleNo = Get2oo2CurCycleNum();

		ocName = (CI_SYSTEM_TYPE_OC) * 256U + systemId;
		localCiId = GetSystemParaLocalCiId();	/*获取联锁ID*/

		galOcDataVer = GetCiTranOcDataCheckVer(localCiId, ocName); /*获取OC系统数据版本号*/
		if (hlhtGalHead.emapVerCrc == galOcDataVer)
		{
			headRet = HLHT_HEAD_SUCCESS;
		}
		else
		{
			headRet = HLHT_HEAD_ERROR;
		}
#if 0
		headRet = HLHTRecvCommonPacketHeadCheck(ocName, ciName, CI_OC_INTERFACE_INFOTYPE, CI_OC_PRTCL_VER, &hlhtGalHead, &errCode, 0, CI_SYSTEM_TYPE_OC);
#endif
		if (HLHT_HEAD_SUCCESS == headRet)
		{
#if 0
			ocInfoRemainValidity = HLHTCommonMsgRemainingValidity(GetCiAndOcTransmitBadEnsureCnt(),curntCycleNo,
				GetSystemParaAppCycleTime(),hlhtGalHead.recvOppMsgSN,hlhtGalHead.crntOwnMsgSN,hlhtGalHead.preOwnMsgSN,hlhtGalHead.comPeriod);
#endif
			ocInfoRemainValidity = 1;
			if (ocInfoRemainValidity > 0)
			{
				/*解析应用数据*/
				ii+=2u;/*应用层长度，2B*/

				appInfoType = ShortFromChar(&dataBuf[ii]);/*应用信息类型，2B*/
				ii += 2u;

				ii+=2u; /*预留，2B*/
				
				pTmpOcToCiData->OcId = systemId; /*oc id赋值*/

				if (OC_CI_STATE_INFO == appInfoType)/*OC给CI的状态信息 0x8802*/
				{
					/*by cgh 20230831 增加转辙机状态接口*/
					/*fan 20241120 适配4牵引 OC3.0 接口 支持OC数据结构配置中较新数据结构*/
					if ((FUNC_SWITCH_ON == chSwitch)&&(DATA_TYPE_NEW == chOcType))
					{			
						/*************解析设备[道岔]***********/
						tmpDeviceType = CI_DEVICE_TYPE_SWITCH;
						tmpSwitchNum = dataBuf[ii++];/*道岔数量*/
						for (j = 0u;j<tmpSwitchNum;j++) /*设备解析*/
						{
							tmpDeviceId = ShortFromChar(&dataBuf[ii]); /*设备Id 2B*/
							ii+=2u;
							tmpDeviceState = dataBuf[ii++]; /*设备状态 1B*/
							pTmpOcToCiData->OcDevices[j].chSwitchIncldeZzjNum = dataBuf[ii++];
							if (MAX_OC_SWITCH_INCLUDE_ZZJ_NUM >= pTmpOcToCiData->OcDevices[j].chSwitchIncldeZzjNum)
							{
								for (chZzjStateIndex = 0U; chZzjStateIndex < pTmpOcToCiData->OcDevices[j].chSwitchIncldeZzjNum; chZzjStateIndex++)
								{
									/*转辙机状态*/
									pTmpOcToCiData->OcDevices[j].szSwitchIncldeZzjState[chZzjStateIndex] = dataBuf[ii++];
								}
							}
							else
							{
								retVal = CI_ERROR;
								pTmpOcToCiData->OcDevices[j].chSwitchIncldeZzjNum = 0U;
								pTmpOcToCiData->OcDevices[j].szSwitchIncldeZzjState[0U] = OC_SWITCH_POSITION_SIKAI;
							}

							if (CI_SUCCESS == retVal)
							{
								tmpSwitchBoardNum = dataBuf[ii++];/*板卡数量*/

								if ((j < MAX_OC_DEVICE_NUM) && (tmpSwitchBoardNum <= MAX_OC_SWITCH_INCLUDE_BOARD_NUM))
								{
									pTmpOcToCiData->OcDevices[j].OcId = systemId;/*每个设备的oc id*/
																				 /*板卡地址状态赋值*/
									pTmpOcToCiData->OcDevices[j].BoardNum = tmpSwitchBoardNum; /*板卡数量*/
									switchBoardCheck = CI_ERROR;
									for (k = 0U; k < tmpSwitchBoardNum; k++)
									{
										pTmpOcToCiData->OcDevices[j].BoardAddr[k] = dataBuf[ii++];/*板卡地址 1B*/
										pTmpOcToCiData->OcDevices[j].BoardState[k] = dataBuf[ii++];/*板卡状态 1B*/
										if (0U == pTmpOcToCiData->OcDevices[j].BoardState[k])
										{
											switchBoardCheck = CI_SUCCESS; /*存在正常板卡*/
										}
									}
									pTmpOcToCiData->OcDevices[j].DeviceType = tmpDeviceType; /*设备类型 1B*/
									pTmpOcToCiData->OcDevices[j].DeviceId = tmpDeviceId; /*设备Id 2B*/
									pTmpOcToCiData->OcDevices[j].DeviceState = tmpDeviceState; /*设备状态 1B*/

									if (CI_SUCCESS == switchBoardCheck) /*0为正常 存在正常板卡*/
									{
										pTmpOcToCiData->OcDevices[j].DeviceState = tmpDeviceState; /*设备状态 1B*/
									}
									else
									{
										/*发送ats报警*/

									}
								}
								else
								{
									/*设备（信号机、道岔）超出索引，给出调试警告信息*/
									retVal = CI_ERROR;
									debug_infor_printf((const)"devId'index %d exceed macro %d  boardNum%d, max:%d \n", tmpDeviceId, MAX_OC_DEVICE_NUM, tmpSwitchBoardNum, MAX_OC_SWITCH_INCLUDE_BOARD_NUM);
								}
							}
						}
				
						
						/*************解析设备[信号机]***********/
						if (CI_SUCCESS == retVal)
						{
							tmpDeviceType = CI_DEVICE_TYPE_SIGNAL;
							tmpSignalNum = dataBuf[ii++];/*信号机数量*/

							pTmpOcToCiData->OcDeviceNum = tmpSignalNum + tmpSwitchNum;
							for (j = tmpSwitchNum; j < pTmpOcToCiData->OcDeviceNum; j++) /*设备解析*/
							{
								tmpDeviceId = ShortFromChar(&dataBuf[ii]); /*设备Id 2B*/
								ii += 2u;
								tmpDeviceState = dataBuf[ii++]; /*设备状态 1B*/

								tmpBoardAddr1 = dataBuf[ii++];/*板卡地址 1B*/
								tmpBoardState1 = dataBuf[ii++]; /*板卡状态 1B*/

								tmpBoardAddr2 = dataBuf[ii++];/*板卡地址 1B*/
								tmpBoardState2 = dataBuf[ii++]; /*板卡状态 1B*/
								if (j < MAX_OC_DEVICE_NUM)
								{
									pTmpOcToCiData->OcDevices[j].OcId = systemId;/*每个设备的oc id*/
																				 /*板卡地址状态赋值*/
									pTmpOcToCiData->OcDevices[j].BoardNum = 2U; /*板卡数量*/
									pTmpOcToCiData->OcDevices[j].chSwitchIncldeZzjNum = 0U;
									pTmpOcToCiData->OcDevices[j].BoardAddr[0] = tmpBoardAddr1;/*板卡地址 1B*/
									pTmpOcToCiData->OcDevices[j].BoardState[0] = tmpBoardState1; /*板卡状态 1B*/
									pTmpOcToCiData->OcDevices[j].BoardAddr[1] = tmpBoardAddr2;/*板卡地址 1B*/
									pTmpOcToCiData->OcDevices[j].BoardState[1] = tmpBoardState2; /*板卡状态 1B*/
									pTmpOcToCiData->OcDevices[j].chSwitchIncldeZzjNum = 0U;
									pTmpOcToCiData->OcDevices[j].DeviceType = tmpDeviceType; /*设备类型 1B*/
									pTmpOcToCiData->OcDevices[j].DeviceId = tmpDeviceId; /*设备Id 2B*/
									pTmpOcToCiData->OcDevices[j].DeviceState = tmpDeviceState; /*设备状态 1B*/

									if ((0u == tmpBoardState1) || (0u == tmpBoardState2)) /*0为正常 其它异常*/
									{
										pTmpOcToCiData->OcDevices[j].DeviceState = tmpDeviceState; /*设备状态 1B*/
									}
									else
									{
										/*发送ats报警*/

									}
								}
								else
								{
									/*设备（信号机、道岔）超出索引，给出调试警告信息*/
									retVal = CI_ERROR;
									debug_infor_printf((const)"devId'index %d exceed macro %d.\n", tmpDeviceId, MAX_OC_DEVICE_NUM);
								}
							}
						}

					}
					/*OC-100 以及OC数据结构24对应OC  无适配4牵引 设备数据种道岔&信号机合并 固定设备板卡数2*/
					else
					{
						/*OC100 以及 OC数据结构24*/
						/*************解析设备[信号机、道岔]***********/
						pTmpOcToCiData->OcDeviceNum = ShortFromChar(&dataBuf[ii]);/*设备数量*/
						ii += 2u;
						for (j = 0u; j<pTmpOcToCiData->OcDeviceNum; j++) /*设备解析*/
						{
							tmpDeviceType = dataBuf[ii++]; /*设备类型 1B*/
							tmpDeviceId = ShortFromChar(&dataBuf[ii]); /*设备Id 2B*/
							ii += 2u;
							tmpDeviceState = dataBuf[ii++]; /*设备状态 1B*/

							if (FUNC_SWITCH_ON == chSwitch)
							{
								/*道岔对应转辙机数目，设备类型为信号机时,此个数为0*/
								pTmpOcToCiData->OcDevices[j].chSwitchIncldeZzjNum = dataBuf[ii++];
								for (chZzjStateIndex = 0U; chZzjStateIndex < pTmpOcToCiData->OcDevices[j].chSwitchIncldeZzjNum; chZzjStateIndex++)
								{
									/*转辙机状态*/
									pTmpOcToCiData->OcDevices[j].szSwitchIncldeZzjState[chZzjStateIndex] = dataBuf[ii++];
								}
							}
							else
							{
								/* 100无此接口 */
							}
							tmpBoardAddr1 = dataBuf[ii++];/*板卡地址 1B*/
							tmpBoardState1 = dataBuf[ii++]; /*板卡状态 1B*/

							tmpBoardAddr2 = dataBuf[ii++];/*板卡地址 1B*/
							tmpBoardState2 = dataBuf[ii++]; /*板卡状态 1B*/
							if (j< MAX_OC_DEVICE_NUM)
							{
								pTmpOcToCiData->OcDevices[j].OcId = systemId;/*每个设备的oc id*/
																			 /*板卡地址状态赋值*/
								pTmpOcToCiData->OcDevices[j].BoardNum = 2U; /*板卡数量固定2*/
								pTmpOcToCiData->OcDevices[j].BoardAddr[0] = tmpBoardAddr1;/*板卡地址 1B*/
								pTmpOcToCiData->OcDevices[j].BoardState[0] = tmpBoardState1; /*板卡状态 1B*/
								pTmpOcToCiData->OcDevices[j].BoardAddr[1] = tmpBoardAddr2;/*板卡地址 1B*/
								pTmpOcToCiData->OcDevices[j].BoardState[1] = tmpBoardState2; /*板卡状态 1B*/

								pTmpOcToCiData->OcDevices[j].DeviceType = tmpDeviceType; /*设备类型 1B*/
								pTmpOcToCiData->OcDevices[j].DeviceId = tmpDeviceId; /*设备Id 2B*/
								pTmpOcToCiData->OcDevices[j].DeviceState = tmpDeviceState; /*设备状态 1B*/

								if ((0u == tmpBoardState1) || (0u == tmpBoardState2)) /*0为正常 其它异常*/
								{
									pTmpOcToCiData->OcDevices[j].DeviceState = tmpDeviceState; /*设备状态 1B*/
								}
								else
								{
									/*发送ats报警*/

								}
							}
							else
							{
								/*设备（信号机、道岔）超出索引，给出调试警告信息*/
								retVal = CI_ERROR;
								debug_infor_printf((const)"devId'index %d exceed macro %d.\n", tmpDeviceId, MAX_OC_DEVICE_NUM);
							}
						}
					}
					

					/*************解析轨道区段***********/
					if (CI_SUCCESS == retVal)
					{
						pTmpOcToCiData->OcGdNum = ShortFromChar(&dataBuf[ii]);/*轨道区段数量*/
						ii += 2u;
						if (Max_OC_GD_NUM >= pTmpOcToCiData->OcGdNum)
						{
							for (j = 0u; j < pTmpOcToCiData->OcGdNum; j++)/*解析轨道区段*/
							{
								pTmpOcToCiData->OcId = systemId;/*OC编号赋值*/

								tmpGdId = ShortFromChar(&dataBuf[ii]);/*轨道区段id*/

								pTmpOcToCiData->OcGdDevices[j].OcId = systemId;
								pTmpOcToCiData->OcGdDevices[j].GdDeviceId = ShortFromChar(&dataBuf[ii]);/*轨道区段id*/
								ii += 2u;
								pTmpOcToCiData->OcGdDevices[j].BoardAddr1 = dataBuf[ii++];
								pTmpOcToCiData->OcGdDevices[j].BoardState1 = dataBuf[ii++];
								pTmpOcToCiData->OcGdDevices[j].GdState1 = dataBuf[ii++];

								pTmpOcToCiData->OcGdDevices[j].BoardAddr2 = dataBuf[ii++];
								pTmpOcToCiData->OcGdDevices[j].BoardState2 = dataBuf[ii++];
								pTmpOcToCiData->OcGdDevices[j].GdState2 = dataBuf[ii++];
							}
						}
						else
						{
							retVal = CI_ERROR;
							/*轨道板超出索引，给出调试警告信息*/
							debug_infor_printf((const)"devId'index %d exceed macro %d.\n", pTmpOcToCiData->OcGdNum, Max_OC_GD_NUM);
						}
					}
					/*************解析DI板卡***********/
					if (CI_SUCCESS == retVal)
					{
						pTmpOcToCiData->OcDIBoardDataNum = ShortFromChar(&dataBuf[ii]);/*板卡个数*/
						ii += 2u;
						if (MAX_OC_DI_BOARD_NUM >= pTmpOcToCiData->OcDIBoardDataNum)
						{
							for (j = 0u; j < pTmpOcToCiData->OcDIBoardDataNum; j++) /*解析板卡*/
							{
								tmpBoardAddr2 = dataBuf[ii++]; /*板卡地址*/
								tmpBoardState2 = dataBuf[ii++]; /*板卡状态*/

								(void)memcpy(tmpBoardCollData, &dataBuf[ii], 18); /*板卡采集数据*/ /*改成18个字节了，需要修改*/
								ii += 18u;

								pTmpOcToCiData->OcDIBoardDatas[j].BoardAddr = tmpBoardAddr2;
								pTmpOcToCiData->OcDIBoardDatas[j].BoardState = tmpBoardState2;
								if (tmpBoardState2 == 0u) /*板卡正常*/
								{
									(void)memcpy(pTmpOcToCiData->OcDIBoardDatas[j].BoardCollData, tmpBoardCollData, 18);

								}
								else /*板卡故障*/
								{
									(void)memset(pTmpOcToCiData->OcDIBoardDatas[j].BoardCollData, 0xaa, 18);
									/*发送ats报警*/
								}							
							}
						}
						else
						{
							/*DI板卡超出索引，给出调试警告信息*/
							retVal = CI_ERROR;
							debug_infor_printf((const)"OcDIBoardDatas'index %d exceed macro %d.\n", pTmpOcToCiData->OcDIBoardDataNum, MAX_OC_DI_BOARD_NUM);
						}
					}

					/************解析DO板卡**********/
					if (CI_SUCCESS == retVal)
					{
						pTmpOcToCiData->OcDOBoardNum = ShortFromChar(&dataBuf[ii]);/*DO板卡数量*/
						ii += 2u;
						if (MAX_OC_DO_BOARD_NUM >=pTmpOcToCiData->OcDOBoardNum)
						{
							for (j = 0u; j < pTmpOcToCiData->OcDOBoardNum; j++)
							{
								pTmpOcToCiData->OcDOBoardDatas[j].DoBoardAddr = dataBuf[ii++];
								pTmpOcToCiData->OcDOBoardDatas[j].DoBoardState = dataBuf[ii++];
							}
						}
						else
						{
							retVal = CI_ERROR;
							/*DO板卡超出索引，给出调试警告信息*/
							debug_infor_printf((const)"OcDOBoardDatas'index %d exceed macro %d.\n", pTmpOcToCiData->OcDOBoardNum, MAX_OC_DO_BOARD_NUM);
						}
					}

					/*************解析SI板卡***********/
					if (CI_SUCCESS == retVal)
					{
						curBoardNum = pTmpOcToCiData->OcDIBoardDataNum;
						pTmpOcToCiData->OcDIBoardDataNum += ShortFromChar(&dataBuf[ii]);/*SI板卡数量*/
						ii += 2u;
						if (MAX_OC_DI_BOARD_NUM >= pTmpOcToCiData->OcDIBoardDataNum)
						{
							for (j = (UINT8)(curBoardNum); j < pTmpOcToCiData->OcDIBoardDataNum; j++) /*解析板卡*/
							{
								tmpBoardAddr2 = dataBuf[ii++]; /*板卡地址*/
								tmpBoardState2 = dataBuf[ii++]; /*板卡状态*/

								(void)memcpy(tmpBoardCollData, &dataBuf[ii], 12); /*板卡采集数据*/ /*改成12个字节了，需要修改*/
								ii += 12u;

								pTmpOcToCiData->OcDIBoardDatas[j].BoardAddr = tmpBoardAddr2;
								pTmpOcToCiData->OcDIBoardDatas[j].BoardState = tmpBoardState2;
								if (tmpBoardState2 == 0u) /*板卡正常*/
								{
									(void)memcpy(pTmpOcToCiData->OcDIBoardDatas[j].BoardCollData, tmpBoardCollData, 12);
								}
								else /*板卡故障*/
								{
									(void)memset(pTmpOcToCiData->OcDIBoardDatas[j].BoardCollData, 0xaa, 12);
									/*发送ats报警*/
								}
							}
						}
						else
						{
							/*SI板卡超出索引，给出调试警告信息*/
							retVal = CI_ERROR;
							debug_infor_printf((const)"OcSIBoardDatas'index %d exceed macro %d\n.", pTmpOcToCiData->OcDIBoardDataNum, MAX_OC_DI_BOARD_NUM);
						}
					}
					/************解析SO板卡**********/
					curBoardNum = pTmpOcToCiData->OcDOBoardNum;
					pTmpOcToCiData->OcDOBoardNum += ShortFromChar(&dataBuf[ii]);/*DO板卡数量*/
					ii += 2u;
					if (MAX_OC_DO_BOARD_NUM >=pTmpOcToCiData->OcDOBoardNum)
					{
						for (j = (UINT8)(curBoardNum); j < pTmpOcToCiData->OcDOBoardNum; j++)
						{
							pTmpOcToCiData->OcDOBoardDatas[j].DoBoardAddr = dataBuf[ii++];
							pTmpOcToCiData->OcDOBoardDatas[j].DoBoardState = dataBuf[ii++];
						}
					}
					else
					{
						retVal = CI_ERROR;
						/*SO板卡超出索引，给出调试警告信息*/
						debug_infor_printf((const)"OcSOBoardDatas'index %d exceed macro %d.\n", pTmpOcToCiData->OcDOBoardNum, MAX_OC_DO_BOARD_NUM);
					}

					/*************解析SOR板卡  仅适配OC-200且较新OC***********/
					if ((CI_SUCCESS == retVal) && (FUNC_SWITCH_ON == chSwitch)&& (DATA_TYPE_NEW == chOcType))
					{
						pTmpOcToCiData->OcSORBoardNum = dataBuf[ii++];/*Sor板卡数量*/
						if (MAX_OC_SOR_BOARD_NUM >= pTmpOcToCiData->OcSORBoardNum)
						{
							for (j = 0U; j < pTmpOcToCiData->OcSORBoardNum; j++) /*解析板卡*/
							{
								tmpBoardAddr2 = dataBuf[ii++]; /*板卡地址*/
								tmpBoardState2 = dataBuf[ii++]; /*板卡状态*/

								(void)memcpy(tmpBoardCollData, &dataBuf[ii], 5); /*输出继电器板回采数据*/
								ii += 5u;

								pTmpOcToCiData->OcSORBoardDatas[j].BoardAddr = tmpBoardAddr2;
								pTmpOcToCiData->OcSORBoardDatas[j].BoardState = tmpBoardState2;
								if (tmpBoardState2 == 0u) /*板卡正常*/
								{
									(void)memcpy(pTmpOcToCiData->OcSORBoardDatas[j].BoardCollData, tmpBoardCollData, 5U);
								}
								else /*板卡故障*/
								{
									(void)memset(pTmpOcToCiData->OcSORBoardDatas[j].BoardCollData, 0xaaU, 5U);
									/*发送ats报警*/
								}
							}
						}
						else
						{
							/*Sor板卡超出索引，给出调试警告信息*/
							retVal = CI_ERROR;
							debug_infor_printf((const)"OcSorBoardDatas'index %d exceed macro %d.\n", pTmpOcToCiData->OcSORBoardNum, MAX_OC_SOR_BOARD_NUM);
						}
					}

					/*************解析OC电源状态、执行电插箱***********/
					if (CI_SUCCESS == retVal)
					{
						pTmpOcToCiData->PowerAState = dataBuf[ii++];
						pTmpOcToCiData->PowerBState = dataBuf[ii++];
						pTmpOcToCiData->OCDevFaultState = dataBuf[ii++];
						pTmpOcToCiData->FanState = dataBuf[ii++];

						if (FUNC_SWITCH_ON == chSwitch)
						{
							/* 执行电插箱信息 */
							pTmpOcToCiData->chPbNum = dataBuf[ii++];
							if (pTmpOcToCiData->chPbNum <= MAX_OC_PLUS_BOX_NUM)
							{
								for (chPbIndex = 0u; chPbIndex < pTmpOcToCiData->chPbNum; chPbIndex++)
								{
									/* 执行电插箱ID */
									pTmpOcToCiData->szPlusBox[chPbIndex].chPbId = dataBuf[ii++];
									/* 类型 */
									pTmpOcToCiData->szPlusBox[chPbIndex].chPbType = dataBuf[ii++];
									/* 空开状态 */
									pTmpOcToCiData->szPlusBox[chPbIndex].chAsState = dataBuf[ii++];
								}
							}
							else
							{
								/*执行电插箱数超出索引，给出调试警告信息*/
								retVal = CI_ERROR;
								debug_infor_printf((const)"OcPbNumDatas'index %d exceed macro %d.\n", pTmpOcToCiData->chPbNum, MAX_OC_PLUS_BOX_NUM);
							}
						}
						else
						{
							/* 100无执行电插箱 */
						}
					}
					/*************解析切系板卡***********/
					if (CI_SUCCESS == retVal)
					{
#if 1
						pTmpOcToCiData->OCBoardSwapSysNum = ShortFromChar(&dataBuf[ii]); /*OC切系板卡数量*/
						ii += 2U;
						curBoardSwapSysNum = pTmpOcToCiData->OCBoardSwapSysNum;
						if (MAX_OC_DEVICE_NUM >= curBoardSwapSysNum)
						{
							for (j = 0U; j < curBoardSwapSysNum; j++)
							{
								pTmpOcToCiData->SwapSysBoardId[j] = dataBuf[ii++];/*OC切系板卡ID*/
							}
						}
						else
						{
							/*切系数超出索引，给出调试警告信息*/
							retVal = CI_ERROR;
							debug_infor_printf((const)"OcSwapSysBoardNum'index %d exceed macro %d.\n", curBoardSwapSysNum, MAX_OC_DEVICE_NUM);
						}
					}

					if (OC200_VER3_2 == ocInterfaceFlag)
					{/*OC200 3.2,无屏蔽门无应急盘*/
						/*不处理*/
					}
					else if (OC200_VER3_2_AFTER == ocInterfaceFlag)
					{/*OC200 3.2之后的版本，只有应急盘*/
						/*************解析OC应急控状态信息***********/
						if (CI_SUCCESS == retVal)
						{
							pTmpOcToCiData->chHaveYjk = dataBuf[ii++];
							if (OC_HAVE_YJK == pTmpOcToCiData->chHaveYjk)
							{/*具备应急控*/
								pTmpOcToCiData->chControlMode = dataBuf[ii++];
								pTmpOcToCiData->chOcYjpComm = dataBuf[ii++];
							}
							else
							{/*不具备应急控*/
							}
						}
					}
					else if (OC300_VER1_0_1_ANDAFTER == ocInterfaceFlag)
					{/*OC300 1.0.1之后的版本，有屏蔽门和应急盘*/
						if (CI_SUCCESS == retVal)
						{
							/*************解析屏蔽门信息***********/
							/*屏蔽门数量*/
							pTmpOcToCiData->OCPsdNum = dataBuf[ii++];
							curPsdNum = pTmpOcToCiData->OCPsdNum;
							if (0u != curPsdNum)
							{
								/*驱动电源状态*/
								pTmpOcToCiData->DrvPowerState = dataBuf[ii++];
								/*控制电源状态*/
								pTmpOcToCiData->CtlPowerState = dataBuf[ii++];
								/*边缘控制器1状态*/
								pTmpOcToCiData->EdgeCtllerState1 = dataBuf[ii++];
								/*边缘控制器2状态*/
								pTmpOcToCiData->EdgeCtllerState2 = dataBuf[ii++];



								if (PSD_SUM_MAX >= curPsdNum)
								{
									for (j = 0u; j < curPsdNum; j++)
									{
										psdId = LongFromChar(&dataBuf[ii]);  /*获取屏蔽门ID*/
										ii += 4u;
										/*PSD编号*/
										funcRet = dquQueryInDevIndex(QFUN_IDMAP_PSD_ID, psdId, &psdIndexId);
										if (CI_SUCCESS == funcRet)
										{
											pTmpOcToCiData->PsdInfo[j].wPsdId = psdIndexId;
											/*开门故障状态*/
											pTmpOcToCiData->PsdInfo[j].OpenErrState = dataBuf[ii++];
											/*关门故障状态*/
											pTmpOcToCiData->PsdInfo[j].CloseErrState = dataBuf[ii++];
											/*开关门状态*/
											pTmpOcToCiData->PsdInfo[j].OpenOrCloseState = dataBuf[ii++];
											/*互锁解除状态*/
											pTmpOcToCiData->PsdInfo[j].InterlockRelState = dataBuf[ii++];
											/*单扇门故障隔离信息高四位*/
											pTmpOcToCiData->PsdInfo[j].psdFaultQStataOne = LongFromChar(&dataBuf[ii]);
											ii += 4u;
											/*单扇门故障隔离信息低四位*/
											pTmpOcToCiData->PsdInfo[j].psdFaultQStataTwo = LongFromChar(&dataBuf[ii]);
											ii += 4u;
											/*单扇门开关状态高四位*/
											pTmpOcToCiData->PsdInfo[j].psdDoorsStateOne = LongFromChar(&dataBuf[ii]);
											ii += 4u;
											/*单扇门开关状态低四位*/
											pTmpOcToCiData->PsdInfo[j].psdDoorsStateTwo = LongFromChar(&dataBuf[ii]);
											ii += 4u;
											/*单扇门被隔离信息高四位*/
											pTmpOcToCiData->PsdInfo[j].psdDoorIStateOne = LongFromChar(&dataBuf[ii]);
											ii += 4u;
											/*单扇门被隔离信息低四位*/
											pTmpOcToCiData->PsdInfo[j].psdDoorIStateTwo = LongFromChar(&dataBuf[ii]);
											ii += 4u;
											/*障碍物报警状态*/
											pTmpOcToCiData->PsdInfo[j].psdAlarmState = dataBuf[ii++];
										}
										else
										{
											/*本屏蔽门解析错误*/
											ii += 29u;
											retVal = CI_ERROR;
											break;
										}
									}
								}
								else
								{
									/*屏蔽门数量超出索引，给出调试警告信息*/
									retVal = CI_ERROR;
									debug_infor_printf((const)"OcPscNum'index %d exceed macro %d.\n", curPsdNum, PSD_SUM_MAX);
								}
							}

						}
						/*************解析OC应急控状态信息***********/
						if (CI_SUCCESS == retVal)
						{
							pTmpOcToCiData->chHaveYjk = dataBuf[ii++];
							if (OC_HAVE_YJK == pTmpOcToCiData->chHaveYjk)
							{/*具备应急控*/
								pTmpOcToCiData->chControlMode = dataBuf[ii++];
								pTmpOcToCiData->chOcYjpComm = dataBuf[ii++];
							}
							else
							{/*不具备应急控*/
							}
						}
					}
					
#endif
#if 0
					(void)memcpy(pTmpOcToCiData->OcSystemState,&dataBuf[ii],16);/*OC子系统状态*/
					ii+=16;
#endif					
				}
				else
				{
					retVal = CI_ERROR;
				}

				if (CI_SUCCESS == retVal)
				{
					if (ii > dataLength)
					{
						retVal = CI_ERROR;
					}
				}

				if (CI_SUCCESS == retVal)
				{
					/*数据经过校验，需要存储通用报文上下文*/
					SetHLHTHeadCtxComPeriod(CI_SYSTEM_TYPE_OC, systemId, hlhtGalHead.comPeriod);
					SetHLHTHeadCtxSrcCrntSN(CI_SYSTEM_TYPE_OC, systemId, hlhtGalHead.crntOwnMsgSN);
					SetHLHTHeadCtxSrcOppSN(CI_SYSTEM_TYPE_OC, systemId, hlhtGalHead.recvOppMsgSN);
					SetHLHTHeadCtxSrcOwnSN(CI_SYSTEM_TYPE_OC, systemId, hlhtGalHead.preOwnMsgSN);
					SetHLHTHeadCtxCiRcvSN(CI_SYSTEM_TYPE_OC, systemId, curntCycleNo);

					/*解析通过 更新通信周期*/
					pTmpOcToCiData->ComStartCycle = Get2oo2CurCycleNum();/*保存收到OC数据时的通信开始周期*/
					debug_infor_printf((const)"\nId:%d OC_COM:%d\n", pTmpOcToCiData->OcId, pTmpOcToCiData->ComStartCycle);
					
					if(findFlag ==0u) /*如果需要更新的oc索引没找到，则认为这包数据是新的oc数据,需要增加oc总数量*/
					{
						m_OcToCiOrginDataNum++;
					}
				}

			}


		}
		else if (HLHT_HEAD_INIT == headRet)
		{
			if (curntCycleNo > 0u)
			{
				SetHLHTHeadCtxComPeriod(CI_SYSTEM_TYPE_OC, systemId, hlhtGalHead.comPeriod);
				SetHLHTHeadCtxSrcCrntSN(CI_SYSTEM_TYPE_OC, systemId, hlhtGalHead.crntOwnMsgSN);
				SetHLHTHeadCtxSrcOppSN(CI_SYSTEM_TYPE_OC, systemId, hlhtGalHead.recvOppMsgSN);
				SetHLHTHeadCtxSrcOwnSN(CI_SYSTEM_TYPE_OC, systemId, hlhtGalHead.preOwnMsgSN);
				SetHLHTHeadCtxCiRcvSN(CI_SYSTEM_TYPE_OC, systemId, curntCycleNo);
			}
		}
		else
		{
			/*给ATS或现地反馈CI-OC数据版本校验失败信息*/
			SetCiSendCmdBackInfoData(CI_BACK_DATA_VER_CHECK_FAIL, CI_SYSTEM_TYPE_OC, systemId, 0U, 0U);
			retVal = CI_ERROR;
		}
	}
	

	if (CI_SUCCESS == retVal)
	{
		if (SetCiTransmitRecvDataCycNum(GetSystemParaLocalCiId(), CI_SYSTEM_TYPE_OC, systemId, Get2oo2CurCycleNum()) == CI_ERROR)
		{/*更新周期失败*/

		}
		else
		{/*更新周期成功*/

			/*更新与OC通信状态：判断与OC是否通信中断*/
			if (UpdateCiTransmitState(GetSystemParaLocalCiId(), CI_SYSTEM_TYPE_OC, systemId) == CI_ERROR)
			{
				/*更新通信状态失败*/
			}
			else
			{
				/*更新通信状态成功*/
			}
		}

	}
	else if ((CI_ERROR == retVal)|| (CI_CHECK_LEN_ERROR == retVal) /*|| (0 == galHeadSaved)*/)
	{
		/*清除通用报文头*/
		ClearHlhtHeadCtx(CI_SYSTEM_TYPE_OC, systemId);
	}
	else
	{
		/*不做处理*/
	}



	return retVal;
}



/*
* 功能描述： 初始化OC设备
* 参数说明： void
* 返回值  ： void      
*/
void InitOcDevices(void)
{
	InitOcSignals();

	InitOcSwitchs();

	InitOcGds();

	(void)InitOcsBoardsIsScatter();
}

/*
* 功能描述： 通过信号机id获取索引
* 参数说明： void
* 返回值  ： void      
*/
INT16 GetIndexBySignalId(UINT16 sigId)
{
	INT16 retIndex = -1;

	UINT16 i =0u;

	for (i=0u;i<m_SignalNum;i++)
	{
		if (m_Signals[i].DeviceId == sigId)
		{
			retIndex = (INT16)i;
			break;
		}
	}

	return retIndex;
}

/*
* 功能描述： 通过道岔id获取索引
* 参数说明： void
* 返回值  ： void      
*/
INT16 GetIndexBySwitchId(UINT16 swId)
{
	INT16 retIndex = -1;

	UINT16 i =0u;

	for (i=0u;i<m_SwitchNum;i++)
	{
		if (m_Switches[i].DeviceId == swId)
		{
			retIndex = (INT16)i;
			break;
		}
	}

	return retIndex;
}

/*
* 功能描述： 通过轨道id获取索引
* 参数说明： void
* 返回值  ： void      
*/
INT16 GetIndexByGdId(UINT16 gdId)
{
	INT16 retIndex = -1;

	UINT16 i =0u;

	for (i=0u;i<m_GdNum;i++)
	{
		if (m_Gds[i].GdDeviceId == gdId)
		{
			retIndex = (INT16)i;
			break;
		}
	}

	return retIndex;
}

/*
* 功能描述： 初始化OC信号机
* 参数说明： void
* 返回值  ： void      
*/
void InitOcSignals(void)
{
	UINT16 i = 0u;
	UINT8 k = 0U;
	SignalConfigDataStruct *pSig = NULL;
	UINT8 localCi = 0u;
	localCi =GetSystemParaLocalCiId();
	pSig = GetSignalConfigData();
	m_SignalNum = 0u;
	for (i=0u;i<SIGNAL_SUM_MAX;i++)
	{
		if ((CI_SIGNAL_MAX == m_SignalNum) || (NULL == pSig))
		 {
			 /*超出索引，给出调试警告信息*/
			 debug_infor_printf((const)"InitOcSignals():error");
			 break;
		 }
		 if ((0u < pSig[i].SignalId) &&(0u < pSig[i].BelongOcId)&&(localCi == pSig[i].BelongCiId))
		 {
			 m_Signals[m_SignalNum].DeviceId = pSig[i].SignalId;
			 m_Signals[m_SignalNum].DeviceType = OC_DEVICE_TYPE_SIGNAL;
			 m_Signals[m_SignalNum].DeviceState = OC_SIGNAL_SHOWCOLOR_RED_BREAK;
			 m_Signals[m_SignalNum].BoardNum = 0U;
			 for (k = 0U; k < MAX_OC_SWITCH_INCLUDE_BOARD_NUM; k++)
			 {
				 m_Signals[m_SignalNum].BoardState[k] = 0xffU;
				 m_Signals[m_SignalNum].BoardAddr[k] = 0U;
			 }
			 m_Signals[m_SignalNum].OcId = pSig[i].BelongOcId;
			 m_SignalNum++;
		 }
	}
}

/*
* 功能描述： 初始化OC道岔
* 参数说明： void
* 返回值  ： void      
*/
void InitOcSwitchs(void)
{
	
	UINT16 i = 0u;
	UINT8 k = 0U;
	SwitchConfigDataStruct *pSwitch = NULL;
	UINT8 localCi = 0u;
	localCi =GetSystemParaLocalCiId();
	m_SwitchNum = 0u;
	pSwitch = GetSwitchConfigData();
	for (i=0u;i<SWITCH_SUM_MAX;i++)
	{
		if ((CI_SWITCH_MAX == m_SwitchNum) || (NULL == pSwitch))
		{
			/*超出索引，给出调试警告信息*/
			debug_infor_printf((const)"InitOcSwitchs():error");
			break;
		}
		if ((0u < pSwitch[i].SwitchId) && (0u < pSwitch[i].BelongOcId)&&(localCi == pSwitch[i].BelongCiId))
		{
			m_Switches[m_SwitchNum].DeviceId = pSwitch[i].SwitchId;
			m_Switches[m_SwitchNum].DeviceType = OC_DEVICE_TYPE_SWITCH;
			m_Switches[m_SwitchNum].DeviceState = OC_SWITCH_POSITION_SIKAI;
			m_Switches[m_SwitchNum].BoardNum = 0U;
			for (k = 0U; k < MAX_OC_SWITCH_INCLUDE_BOARD_NUM; k++)
			{
				m_Switches[m_SwitchNum].BoardState[k] = 0xffU;
				m_Switches[m_SwitchNum].BoardAddr[k] = 0U;
			}
			m_Switches[m_SwitchNum].OcId = pSwitch[i].BelongOcId;
			m_SwitchNum++;
		}
	}
}

/*
* 功能描述： 初始化OC轨道
* 参数说明： void
* 返回值  ： void      
*/
void InitOcGds(void)
{
	
	UINT16 i = 0u;
	PhysicalSectionConfigDataStruct *pPhy = NULL;
	UINT8 localCi = 0u;
	localCi =GetSystemParaLocalCiId();
	m_GdNum = 0u;
	pPhy = GetPhySecConfigData();
	for (i=0u;i<PHYSICAL_SECTION_SUM_MAX;i++)
	{
		if ((CI_GD_MAX == m_GdNum) || (NULL == pPhy))
		{
			/*超出索引，给出调试警告信息*/
			debug_infor_printf((const)"InitOcGds():error");
			break;
		}
		if ((0u < pPhy[i].PhysicalSectionId) && (0u < pPhy[i].BelongOcId)&&(localCi == pPhy[i].BelongCiId))
		{
			m_Gds[m_GdNum].GdDeviceId = pPhy[i].PhysicalSectionId;
			m_Gds[m_GdNum].GdState1 = OC_GD_STATE_FAULT;
			m_Gds[m_GdNum].GdState2 = OC_GD_STATE_FAULT;
			m_Gds[m_GdNum].GdMergeState = OC_GD_STATE_FAULT;
			m_Gds[m_GdNum].BoardState1 = 0xffu;
			m_Gds[m_GdNum].BoardState2 = 0xffu;
			m_Gds[m_GdNum].BoardAddr1 = 0u;
			m_Gds[m_GdNum].BoardAddr2 = 0u;
			m_Gds[m_GdNum].OcId = pPhy[i].BelongOcId;
			m_GdNum++;
		}
	}
}

/*
* 功能描述： 把解析的OC设备数据转换为OC 信号机和 OC 道岔设备数据
* 参数说明： void
* 返回值  ： void      
*/
void ConvertOcOriginDataToOcSigSwDev(void)
{
	UINT8 i=0U;
	UINT16 j= 0U;
	UINT8 k = 0U;
	INT16 ind = -1;
	OcDeviceStruct *pOcDevice = NULL;
	OcGdDevice *pGdDevice = NULL;
	UINT8 flagRecvInvalidData = 0u;/*非法设备类型标志*/
	for (i=0U;i<m_OcToCiOrginDataNum;i++)/*遍历OC*/
	{
		if (Get2oo2CurCycleNum() - m_OcToCiOrginDataArr[i].ComStartCycle <=GetCiAndOcTransmitBadEnsureCnt())
		{/*CI与OC通信未超时*/
			flagRecvInvalidData = 0U;/*by cgh 20230703 YF0083-773 与RC通信的一个OC连续设备类型错误，整个RC集中区设备状态导向安全测*/
			for (j=0U;j<m_OcToCiOrginDataArr[i].OcDeviceNum;j++) /*遍历OC的每一个设备*/
			{
				pOcDevice = &(m_OcToCiOrginDataArr[i].OcDevices[j]); 
				if (pOcDevice !=NULL)
				{
					if (pOcDevice->DeviceType == OC_DEVICE_TYPE_SIGNAL)
					{/*信号机*/
						ind = GetIndexBySignalId(pOcDevice->DeviceId);
						if ((ind >=0) && (OC_DEVICE_TYPE_SIGNAL == pOcDevice->DeviceType))
						{
							if ((m_Signals[ind].OcId == pOcDevice->OcId) &&
								(m_Signals[ind].DeviceId == pOcDevice->DeviceId))
							{
								m_Signals[ind].DeviceState = pOcDevice->DeviceState;
								m_Signals[ind].DeviceType = pOcDevice->DeviceType;
								m_Signals[ind].BoardNum = pOcDevice->BoardNum;
								m_Signals[ind].BoardAddr[0] = pOcDevice->BoardAddr[0];
								m_Signals[ind].BoardState[0] = pOcDevice->BoardState[0];
								m_Signals[ind].BoardAddr[1] = pOcDevice->BoardAddr[1];
								m_Signals[ind].BoardState[1] = pOcDevice->BoardState[1];
							}
							else
							{
							}
						}
						else
						{
						}
						

					}
					else if (pOcDevice->DeviceType == OC_DEVICE_TYPE_SWITCH)
					{/*道岔*/
						ind = GetIndexBySwitchId(pOcDevice->DeviceId);
						if ((ind >=0) && (OC_DEVICE_TYPE_SWITCH == pOcDevice->DeviceType))
						{
							if ((m_Switches[ind].OcId == pOcDevice->OcId) &&
								(m_Switches[ind].DeviceId == pOcDevice->DeviceId))
							{
								m_Switches[ind].DeviceState = pOcDevice->DeviceState;
								m_Switches[ind].DeviceType = pOcDevice->DeviceType;
								m_Switches[ind].BoardNum = pOcDevice->BoardNum;
								for (k = 0U; k <  m_Switches[ind].BoardNum; k++)
								{
									m_Switches[ind].BoardAddr[k] = pOcDevice->BoardAddr[k];
									m_Switches[ind].BoardState[k] = pOcDevice->BoardState[k];
								}
							}
							else
							{
							}

						}
						else
						{
						}
						
					}
					else
					{/*收到设备类型非法，既非信号机，又非道岔*/
						flagRecvInvalidData = 1u;
						
					}
				}
				else
				{
				}
			}

			for (j=0U;j<m_OcToCiOrginDataArr[i].OcGdNum;j++)
			{
				pGdDevice = &(m_OcToCiOrginDataArr[i].OcGdDevices[j]);

				ind = GetIndexByGdId(pGdDevice->GdDeviceId);
				if (ind >=0 )
				{
					if ((m_Gds[ind].OcId == pGdDevice->OcId) &&
						(m_Gds[ind].GdDeviceId == pGdDevice->GdDeviceId))
					{
						m_Gds[ind].BoardAddr1 = pGdDevice->BoardAddr1;
						m_Gds[ind].BoardAddr2 = pGdDevice->BoardAddr2;
						m_Gds[ind].BoardState1 = pGdDevice->BoardState1;
						m_Gds[ind].BoardState2 = pGdDevice->BoardState2;
						m_Gds[ind].GdState1 = pGdDevice->GdState1;
						m_Gds[ind].GdState2 = pGdDevice->GdState2;
					}
					else
					{
					}
				}
				else
				{
				}

			}

			if (1u == flagRecvInvalidData)
			{/*如果收到非法设备类型数据*/
				m_OcToCiOrginDataArr[i].RecvErrorDevTypeCycle++;
			}
			else if (0u == flagRecvInvalidData)
			{/*收到正常帧，把错误周期数清零*/
				m_OcToCiOrginDataArr[i].RecvErrorDevTypeCycle = 0;
			}
			else
			{
				/*无操作*/
			}
		}
		else
		{
		}
	}
}


/*
* 功能描述： 把解析的OC板卡数据转换为OC点位数据
* 参数说明： void
* 返回值  ： void      
*/
void ConvertOcOriginDataToPtData(void)
{
	UINT8 i=0U;
	UINT16 j= 0U;
	INT16 k=0;
	UINT8 boardNum = 0u;
	UINT8 byteRealy = 0u;
	UINT8 lowByte = 0u;
	UINT8 highByte = 0u;
	UINT8 boardAddr =0u;
	UINT8 cBoardState = RELAY_BOARD_FAULT_YES;
	UINT8  chLocalCiId = GetSystemParaLocalCiId();

	for (i=0U;i<m_OcToCiOrginDataNum;i++)/*遍历Oc*/
	{
		OcToCiOriginDataStruct *pOcOriginData = m_OcToCiOrginDataArr + i;
		if (GetCiIdByOcId(pOcOriginData->OcId) == chLocalCiId)
		{
			if (Get2oo2CurCycleNum() - pOcOriginData->ComStartCycle <= GetCiAndOcTransmitBadEnsureCnt())/*CI与OC通信未超时*/
			{
				m_OcConvertedPtDataArr[pOcOriginData->OcId].OcBoardNum = 0u;
				/*遍历一个OC的所有DI板卡*/
				for (j=0U;j<pOcOriginData->OcDIBoardDataNum;j++)
				{
				    boardAddr = pOcOriginData->OcDIBoardDatas[j].BoardAddr;/*板卡地址*/
					cBoardState = pOcOriginData->OcDIBoardDatas[j].BoardState;  /*板卡状态*/
					boardNum = (UINT8)m_OcConvertedPtDataArr[pOcOriginData->OcId].OcBoardNum;/*板卡数量*/
					
				
					m_OcConvertedPtDataArr[pOcOriginData->OcId].OcId = pOcOriginData->OcId;
					InsertOcId(pOcOriginData->OcId);/*插入oc id*/
					m_OcConvertedPtDataArr[pOcOriginData->OcId].BoardDatas[boardNum].BoardAddress = boardAddr;/*板卡地址赋值*/

					if (0U == cBoardState)
					{
						m_OcConvertedPtDataArr[pOcOriginData->OcId].BoardDatas[boardNum].BoardState = RELAY_BOARD_FAULT_NO;  /*板卡状态正常*/
					}
					else
					{
						m_OcConvertedPtDataArr[pOcOriginData->OcId].BoardDatas[boardNum].BoardState = RELAY_BOARD_FAULT_YES;  /*板卡状态故障*/
					}

					for (k=0;k<18;k++)/*一个板卡18个字节，1~40位，1~36位有效*/
					{
						byteRealy = pOcOriginData->OcDIBoardDatas[j].BoardCollData[k];

						lowByte = byteRealy & 0x0fu;/*字节低4位*/
						highByte = (byteRealy>>4)&0x0fu;/*字节高4位*/

						if (OC_RELAY_UP == (lowByte ) )/*5:吸起*/
						{
							m_OcConvertedPtDataArr[pOcOriginData->OcId].BoardDatas[boardNum].PosValueBuf[k*2] = RELAY_STATE_UP;
						}
						else if (OC_RELAY_DOWN == (lowByte ) )/*0xa:落下*/
						{
							m_OcConvertedPtDataArr[pOcOriginData->OcId].BoardDatas[boardNum].PosValueBuf[k*2] = RELAY_STATE_DOWN;
						}
						else
						{
							m_OcConvertedPtDataArr[pOcOriginData->OcId].BoardDatas[boardNum].PosValueBuf[k*2] = RELAY_STATE_DOWN;
						}

						if (OC_RELAY_UP == (highByte ) )/*5:吸起*/
						{
							m_OcConvertedPtDataArr[pOcOriginData->OcId].BoardDatas[boardNum].PosValueBuf[k*2+1] = RELAY_STATE_UP;
						}
						else if (OC_RELAY_DOWN == (highByte ) )/*0xa:落下*/
						{
							m_OcConvertedPtDataArr[pOcOriginData->OcId].BoardDatas[boardNum].PosValueBuf[k*2+1] = RELAY_STATE_DOWN;
						}
						else
						{
							m_OcConvertedPtDataArr[pOcOriginData->OcId].BoardDatas[boardNum].PosValueBuf[k*2+1] = RELAY_STATE_DOWN;
						}
#if 0
						for (ii=0;ii<8;ii++)
						{
							if (((byteRealy>>ii) & 0x1) == 0x1)
							{
								m_OcConvertedPtDataArr[pOcOriginData->OcId].BoardDatas[boardNum].PosValueBuf[k*8+ii] = RELAY_STATE_UP;
							}
							else
							{
								m_OcConvertedPtDataArr[pOcOriginData->OcId].BoardDatas[boardNum].PosValueBuf[k*8+ii] = RELAY_STATE_DOWN;
							}
						}
#endif
					}
					m_OcConvertedPtDataArr[pOcOriginData->OcId].OcBoardNum++;
				
				}

				/*遍历SOR板卡*/
				for (j = 0U; j < pOcOriginData->OcSORBoardNum; j++)
				{
					boardAddr = pOcOriginData->OcSORBoardDatas[j].BoardAddr;/*板卡地址*/
					cBoardState = pOcOriginData->OcSORBoardDatas[j].BoardState;  /*板卡状态*/
					boardNum = (UINT8)m_OcConvertedPtDataArr[pOcOriginData->OcId].OcBoardNum;/*已有板卡数量*/

					m_OcConvertedPtDataArr[pOcOriginData->OcId].OcId = pOcOriginData->OcId;
					InsertOcId(pOcOriginData->OcId);/*插入oc id*/
					m_OcConvertedPtDataArr[pOcOriginData->OcId].BoardDatas[boardNum].BoardAddress = boardAddr;/*板卡地址赋值*/

					if (0U == cBoardState)
					{
						m_OcConvertedPtDataArr[pOcOriginData->OcId].BoardDatas[boardNum].BoardState = RELAY_BOARD_FAULT_NO;  /*板卡状态正常*/
					}
					else
					{
						m_OcConvertedPtDataArr[pOcOriginData->OcId].BoardDatas[boardNum].BoardState = RELAY_BOARD_FAULT_YES;  /*板卡状态故障*/
					}

					for (k = 0; k<5; k++)/*SOR板卡回采数据5个字节，10路采集*/
					{
						byteRealy = pOcOriginData->OcSORBoardDatas[j].BoardCollData[k];

						lowByte = byteRealy & 0x0fu;/*字节低4位*/
						highByte = (byteRealy >> 4) & 0x0fu;/*字节高4位*/

						if (OC_RELAY_UP == (lowByte))/*5:吸起*/
						{
							m_OcConvertedPtDataArr[pOcOriginData->OcId].BoardDatas[boardNum].PosValueBuf[k * 2] = RELAY_STATE_UP;
						}
						else if (OC_RELAY_DOWN == (lowByte))/*0xa:落下*/
						{
							m_OcConvertedPtDataArr[pOcOriginData->OcId].BoardDatas[boardNum].PosValueBuf[k * 2] = RELAY_STATE_DOWN;
						}
						else
						{
							m_OcConvertedPtDataArr[pOcOriginData->OcId].BoardDatas[boardNum].PosValueBuf[k * 2] = RELAY_STATE_DOWN;
						}

						if (OC_RELAY_UP == (highByte))/*5:吸起*/
						{
							m_OcConvertedPtDataArr[pOcOriginData->OcId].BoardDatas[boardNum].PosValueBuf[k * 2 + 1] = RELAY_STATE_UP;
						}
						else if (OC_RELAY_DOWN == (highByte))/*0xa:落下*/
						{
							m_OcConvertedPtDataArr[pOcOriginData->OcId].BoardDatas[boardNum].PosValueBuf[k * 2 + 1] = RELAY_STATE_DOWN;
						}
						else
						{
							m_OcConvertedPtDataArr[pOcOriginData->OcId].BoardDatas[boardNum].PosValueBuf[k * 2 + 1] = RELAY_STATE_DOWN;
						}
#if 0
						for (ii = 0; ii<8; ii++)
						{
							if (((byteRealy >> ii) & 0x1) == 0x1)
							{
								m_OcConvertedPtDataArr[pOcOriginData->OcId].BoardDatas[boardNum].PosValueBuf[k * 8 + ii] = RELAY_STATE_UP;
							}
							else
							{
								m_OcConvertedPtDataArr[pOcOriginData->OcId].BoardDatas[boardNum].PosValueBuf[k * 8 + ii] = RELAY_STATE_DOWN;
							}
						}
#endif
					}
					m_OcConvertedPtDataArr[pOcOriginData->OcId].OcBoardNum++;
				}
			}
		}
		else
		{
			/*ocId不属于本联锁，不处理*/
		}
	}
}

UINT8 InitOcsBoardsIsScatter(void)
{
	UINT8 rtn = 0u; /*返回值*/
	UINT8 *pData = NULL; /*读出的数据*/
	UINT32 dataLen = 0u; /*数据长度*/
	UINT8 readRtn = 0u; /**/
	UINT32 rowNum = 0u; /*数据行数*/
	UINT32 i = 0u; /*用于循环*/
	UINT32 offset = 0u;	/*数据偏移量*/
	UINT16 boardId = 0u; /*板卡ID*/
	UINT16 ocId = 0u; /*OC ID*/
	UINT8 boardType = 0u; /*板卡类型*/
	UINT16 jj = 0U;
	UINT8 cLocalCiId = 0U;
	UINT8 cOcBelongCiId = 0U;
	UINT16 wRelayCurSum = 0U;
	UINT16 wRelayId = 0U;
	UINT16 wRelayBelongOCId = 0U;
	UINT16 wRelayAForeBoardId = 0U;  /*A系前采板卡ID*/
	UINT16 wRelayABackBoardId = 0U;  /*A系后采板卡ID*/
	UINT16 wRelayBForeBoardId = 0U;  /*A系前采板卡ID*/
	UINT16 wRelayBBackBoardId = 0U;  /*A系后采板卡ID*/

	readRtn = dquGetConfigData((const)DataPath, OC_DATA_TYPE, OC_IN_OUT_TYPE_ID, &pData, &dataLen);
	if (1u == readRtn) /*读取成功*/
	{
		if (0u < dataLen) /*有数据*/
		{
			rowNum = dataLen / OC_IN_OUT_TYPE_LEN; /*计算表格中数据的个数*/
			if ((BOARD_SUM_MAX*OC_SUM_MAX) >= rowNum)
			{
				cLocalCiId = GetSystemParaLocalCiId();
				wRelayCurSum = GetRelayCurSum();
				for (i = 0u; i < rowNum; i++)
				{
					boardId = ShortFromChar(&pData[offset]); /*板卡ID*/
					offset += 2u;
					ocId = ShortFromChar(&pData[offset]); /*OC ID*/
					offset += 2u;
					boardType = pData[offset]; /*板卡类型*/
					offset += 1u;
					
					if ((BOARD_SUM_MAX > boardId) && (OC_SUM_MAX > ocId) && (0x3cU == boardType))
					{
						ocsBoardsIsScatter[ocId][boardId][0] = 1u;/*零散输出继电器板*/
					}
					else if ((BOARD_SUM_MAX > boardId) && (OC_SUM_MAX > ocId) && (0xc8U == boardType))
					{
						ocsBoardsIsScatter[ocId][boardId][0] = 2u; /*安全输出继电器板*/
					}
					else if ((BOARD_SUM_MAX > boardId) && (OC_SUM_MAX > ocId))
					{
						ocsBoardsIsScatter[ocId][boardId][0] = 0u;
					}
					else
					{
						rtn = 0U;
					}
					
					cOcBelongCiId = (UINT8)GetCiIdByOcId(ocId);
					
					if (cOcBelongCiId == cLocalCiId)
					{
						for (jj = 0U; jj < wRelayCurSum; jj++)
						{
							wRelayId = GetRelayId(jj);
							wRelayBelongOCId = GetRelayBelongOCId(wRelayId);
							if (wRelayBelongOCId == ocId)
							{
								wRelayAForeBoardId = GetRelayForeNodeCollAddrA(wRelayId);
								wRelayABackBoardId = GetRelayBackNodeCollAddrA(wRelayId);
								wRelayBForeBoardId = GetRelayForeNodeCollAddrB(wRelayId);
								wRelayBBackBoardId = GetRelayBackNodeCollAddrB(wRelayId);
								if ((boardId == wRelayAForeBoardId) || (boardId == wRelayABackBoardId) || (boardId == wRelayBForeBoardId) || (boardId == wRelayBBackBoardId))
								{
									SetRelayBoardType(wRelayId, boardType);
								}
								else
								{
									/*不处理*/
								}
							}
							else
							{
								/*不处理*/
							}
						}
					}
					else
					{
						/*不处理*/
					}
				}
				if (offset == dataLen) /*处理正确*/
				{
					rtn = 1u;
				}
			}
		}
	}

	return rtn;
}


/*
* 功能描述：为指定OC->CI的结构设置缺省值(安全值)
* 参数说明： index , OC id对应的数组下标
* 返回值  ： 无
*/
void SetOcToCiDefaultDataStru(UINT8 index)
{
	UINT8 curPsdNum = 0U;/*OC->CI的屏蔽门数量*/
	UINT8 j = 0u;

	if (OC_SUM_MAX <= index)
	{
		/*不处理*/
	}
	else
	{
		curPsdNum = m_OcToCiOrginDataArr[index].OCPsdNum;
		m_OcToCiOrginDataArr[index].DrvPowerState = PSD_DRIVE_POWER_ERROR;/*驱动电源状态*/
		m_OcToCiOrginDataArr[index].CtlPowerState = PSD_CONTROL_POWER_ERROR;/*控制电源状态*/
		m_OcToCiOrginDataArr[index].EdgeCtllerState1 = PSD_EDGE_CONTROLLER_ERROR;/*边缘控制器1状态*/
		m_OcToCiOrginDataArr[index].EdgeCtllerState2 = PSD_EDGE_CONTROLLER_ERROR;/*边缘控制器2状态*/
		for (j = 0U; j < curPsdNum; j++)
		{
			m_OcToCiOrginDataArr[index].PsdInfo[j].OpenErrState = PSD_OPEN_CLOSE_ERROR;/*开门故障状态*/
			m_OcToCiOrginDataArr[index].PsdInfo[j].CloseErrState = PSD_OPEN_CLOSE_ERROR;/*关门故障状态*/
			m_OcToCiOrginDataArr[index].PsdInfo[j].OpenOrCloseState = PSD_STATE_OPEN_VIETNAM;/*开关门状态*/
			m_OcToCiOrginDataArr[index].PsdInfo[j].InterlockRelState = PSD_MUTUALLOCK_REMOVE_NO;/*互锁解除状态*/
			m_OcToCiOrginDataArr[index].PsdInfo[j].psdFaultQStataOne = UINT32_MAX;/*单扇门故障隔离信息*/
			m_OcToCiOrginDataArr[index].PsdInfo[j].psdFaultQStataTwo = UINT32_MAX;
			m_OcToCiOrginDataArr[index].PsdInfo[j].psdDoorsStateOne = UINT32_MAX;/*单扇门开关状态*/
			m_OcToCiOrginDataArr[index].PsdInfo[j].psdDoorsStateTwo = UINT32_MAX;
			m_OcToCiOrginDataArr[index].PsdInfo[j].psdDoorIStateOne = UINT32_MAX;/*单扇门被隔离信息*/
			m_OcToCiOrginDataArr[index].PsdInfo[j].psdDoorIStateTwo = UINT32_MAX;
			m_OcToCiOrginDataArr[index].PsdInfo[j].psdAlarmState = PSD_ALARM_OBS_YES;/*障碍物报警状态*/
		}
	}

}

/*
* 功能描述：获取要发送给OC的控权切换命令
* 参数说明： 无
* 返回值  ： 控权切换命令
*/
UINT16 GetKqChangeCommand(void)
{
	UINT16 ii = 0u;
	UINT16 command = CHANGE_NO_COMMAND;

	for (ii = 0u; ii < m_OcToCiOrginDataNum; ii++)
	{
		if (OC_CTLMODE_YJK == m_OcToCiOrginDataArr[ii].chControlMode)
		{
			/*处于应急控的OC*/
			if (CI_AND_OTHER_TRANSMIT_BAD == m_OcToCiOrginDataArr[ii].chOcYjpComm)
			{
				/*并且OC与应急盘通信中断*/
			}
			else
			{
				break;
			}
		}
		else
		{	
			/*是机控,继续遍历*/
		}
	}

	if((0 != ii)&& (ii == m_OcToCiOrginDataNum))
	{/*所有处于应急控的OC与应急盘中断，或OC是机控*/
		command = CHANGE_JK_COMMAND;
	}
	else
	{
		/*不处理*/
	}

	return command;
}


/*
* 功能描述： 获取点位采集容忍起始周期
* 参数说明： const UINT16 ocId, OC ID
*			 const UINT8 boardNum, 板卡ID
*			 const UINT8 pointNum，点位ID
* 返回值  ： UINT32 采集容忍起始周期
*/
UINT32 GetPointTolerateCycNum(const UINT16 ocId, const UINT8 boardNum, const UINT8 pointNum)
{
	UINT32 retVal = CI_ERROR;

	if ((OC_SUM_MAX > ocId) && (Oc_Max_Board_Num > boardNum) && (OC_COLL_BOARD_POS_NUM > pointNum))
	{
		retVal = m_OcConvertedPtDataArr[ocId].BoardDatas[boardNum].TolerateCycNum[pointNum];
	}
	else
	{/*不处理*/
	}

	return retVal;
}

/*
* 功能描述： 设置道岔采集容忍起始周期
* 参数说明： const UINT16 ocId, OC ID
*			 const UINT8 boardNum, 板卡ID
*			 const UINT8 pointNum，点位ID
*            const UINT32 cycNum 周期号
* 返回值  ： 无
*/
void SetPointTolerateCycNum(const UINT16 ocId, const UINT8 boardNum, const UINT8 pointNum, const UINT32 cycNum)
{
	if ((OC_SUM_MAX > ocId) && (Oc_Max_Board_Num > boardNum) && (OC_COLL_BOARD_POS_NUM > pointNum))
	{
		m_OcConvertedPtDataArr[ocId].BoardDatas[boardNum].TolerateCycNum[pointNum] = cycNum;
	}
	else
	{/*不处理*/
	}
}


















