/********************************************************
*                                                                                                            
* 文 件 名： ParsePackPSCData.c   
* 版权说明： 北京交控科技有限公司 
* 创建时间： 2014-12-25
* 作    者： 联锁组
* 功能描述： PSD数据解析头文件  
* 函数包括：
* 使用注意：
* 修改记录：   
*
********************************************************/ 



#include "ParsePackPSCData.h"
#include "CommonMemory.h"
#include "../QueryFiles/dquCIInterFace.h"
#include "../PSC/PSCConfigDataManage.h"

/*按车站编号映射
  即stationId == 1,则映射到pscToCiDataStru[1]中
*/
PSCToCiDataStruct PscToCiDataStru[PSC_TO_CI_SUM_MAX] = {0u};

/*屏蔽门在PlatformToCiDataStruct结构中的位置:Psd映射为行，Psd所处车站映射为第一列，所处PsdToCiDataStruct位置映射为第2列
  即屏蔽门1在platformToCiDataStru中的位置为:所属车站为PsdPlatformIndex[1][0] ,在屏蔽门的结构中位置为PsdPlatformIndex[1][1]
*/
UINT8 PscIndex[PSD_SUM_MAX][2] = {0u}; 


/*
* 功能描述： 站台门控制器数据结构初始化
* 参数说明： void    
* 返回值  ： 0:解析失败
*			 1:解析成功      
*/
UINT8 InitialPscToCiData(void)
{
	UINT16 ii = 0u;
	UINT16 jj = 0u;
	UINT16 psdId = 0u;
	UINT8 pscId = 0u;
	UINT8 deviceSum =0u;/*通信设备总数*/
	UINT8* deviceIdBuf = NULL;/*通信设备ID数组*/
	UINT8 psdSum = (UINT8)PSC_INCLUDE_PSD_MAX_SUM;
	UINT8 retVal = CI_SUCCESS;
	PscConfigDataStruct *pPSC = NULL;
	deviceSum = (UINT8)GetPscCurSum();     /*获取通信PSC设备总数*/
	pPSC = GetPscConfigData();/*不会返回NULL*/
	if (0u < deviceSum)
	{/*参数有效性判断*/
		for (ii = 0u; ii < deviceSum; ii++)
		{/*遍历与本CI通信的站台门系统*/
			pscId = (UINT8)(pPSC[ii].PscId);

			if(PSC_TO_CI_SUM_MAX <= pscId)
			{/*PSC系统ID合法*/
				retVal = CI_ERROR;
				break;
			}
			for (jj = 0u; jj < pPSC[ii].psdSum; jj++)
			{/*遍历与本CI通信的站台门系统*/
				/*初始化PscToCiDataStru*/
				PscToCiDataStru[pscId].pscId = pscId;
				psdId = pPSC[ii].psdIdBuff[jj];
				PscToCiDataStru[pscId].psdDataStr[jj].psdId = psdId;
				PscToCiDataStru[pscId].psdDataStr[jj].psdState = PSD_STATE_INVALID_HLHT;
				PscToCiDataStru[pscId].psdDataStr[jj].psdMLockState = PSD_MUTUALLOCK_REMOVE_DEFAULT;
				PscToCiDataStru[pscId].psdDataStr[jj].psdFaultQStataOne = 0xffffffffu;
				PscToCiDataStru[pscId].psdDataStr[jj].psdFaultQStataTwo = 0xffffffffu;
				PscToCiDataStru[pscId].psdDataStr[jj].psdDoorsStateOne = 0xffffffffu;
				PscToCiDataStru[pscId].psdDataStr[jj].psdDoorsStateTwo = 0xffffffffu;
				PscToCiDataStru[pscId].psdDataStr[jj].psdDoorIStateOne = 0xffffffffu;
				PscToCiDataStru[pscId].psdDataStr[jj].psdDoorIStateTwo = 0xffffffffu;
				PscToCiDataStru[pscId].psdDataStr[jj].psdAtsMlockState = PSD_MUTUALLOCK_REMOVE_NO;

				PscToCiDataStru[pscId].psdSum = (UINT8)(pPSC[ii].psdSum);
				/*初始化PsdPlatformIndex*/
				PscIndex[psdId][0] = pscId;
				PscIndex[psdId][1] = (UINT8)jj;

			}
		}
	}
		
	return retVal;
}

/*
* 功能描述： 解析处理PSC单帧数据
* 参数说明： const UINT8* dataBuf, 数据缓冲区
*            const UINT16 dataLength, 数据长度
*            const UINT8 systemId, 源设备ID
* 返回值  ： 0: 数据解析失败
*			 1: 数据解析成功      
*/
UINT8 ParsePscToCiDataFrame(const UINT8* dataBuf, const UINT16 dataLength, const UINT8 systemId)
{
	UINT8 retVal = CI_SUCCESS;
	UINT8 localCiId = GetSystemParaLocalCiId();  /*本地联锁ID*/
	UINT16 appInfoType = 0u;					     /*应用信息类型*/   
	UINT32 psdId = 0u;                           /*PSD 编号*/
	UINT16 psdIndexId = 0u;                      /*PSD 编号ID*/
	UINT8 psdSum = 0u;
	UINT16 ii = 0u;
	UINT8 jj = 0u;
	UINT8 rowIndex  = 0u;
	UINT8 colIndex  = 0u;
	UINT8 fucRetun = 0u;
	UINT32 curCycleNum = 0u;
	UINT8 setCycNum = 0u;
	UINT8 updateCycNum = 0u;

	curCycleNum = Get2oo2CurCycleNum();			/*获取当前周期号*/

	if (CI_PSC_INTERFACE_INFOTYPE != ShortFromChar(&dataBuf[ii]))
	{/*不是站台门控制器发送的数据*/
		retVal = CI_ERROR;
	}
	ii += 2u;
	ii += 2u;/*跳过应用报文长度2字节*/
	if(CI_SUCCESS == retVal)
	{
		/*更新通信周期*/
		setCycNum = SetCiTransmitRecvDataCycNum(localCiId, CI_SYSTEM_TYPE_PSC, systemId, curCycleNum);
		if (CI_ERROR == setCycNum)
		{/*更新周期失败*/
			retVal = CI_ERROR;
		}
	}

	if(CI_SUCCESS == retVal)
	{
		updateCycNum = UpdateCiTransmitState(localCiId, CI_SYSTEM_TYPE_PSC, systemId);
		if(CI_ERROR == updateCycNum)
		{
			retVal = CI_ERROR;
		}
	}

	if(CI_SUCCESS == retVal) 
	{	
		if (systemId < PSC_TO_CI_SUM_MAX)
		{
			/*解析应用数据*/
			appInfoType = ShortFromChar(&dataBuf[ii]);/*CI与PSC通信的应用层信信息*/
			ii += 2u;
			PscToCiDataStru[systemId].appInfoType = appInfoType;
			PscToCiDataStru[systemId].pscId = systemId;

			ii += 2u;/*跳过两个预留字节*/

			if (PSC_CI_INFO_TYPE_PSD_STATE == appInfoType)
			{
				PscToCiDataStru[systemId].devType_PSC_A_WORK_STATE = dataBuf[ii];                                                                     /*获取屏蔽门数量*/
				ii += 1u;         /*PSC A系工作状态表示灯*/
				PscToCiDataStru[systemId].devType_PSC_B_WORK_STATE = dataBuf[ii];                                                                     /*获取屏蔽门数量*/
				ii += 1u;             /*PSC B系工作状态表示灯*/
				PscToCiDataStru[systemId].devType_PSC_SINGLE_COMM_STATE = dataBuf[ii];                                                                     /*获取屏蔽门数量*/
				ii += 1u;       /*PSC 单个通信板故障状态表示灯*/
				PscToCiDataStru[systemId].devType_PSC_FSIO_FAULT_STATE = dataBuf[ii];                                                                     /*获取屏蔽门数量*/
				ii += 1u;          /*PSC FSIO故障状态表示灯*/
				PscToCiDataStru[systemId].devType_PSC_DRIVE_POWER_STATE = dataBuf[ii];                                                                     /*获取屏蔽门数量*/
				ii += 1u;         /*PSC 驱动电源状态表示灯*/
				PscToCiDataStru[systemId].devType_PSC_CONTROL_POWER_STATE = dataBuf[ii];                                                                     /*获取屏蔽门数量*/
				ii += 1u;      /*PSC 控制电源状态表示灯*/
				PscToCiDataStru[systemId].devType_PSC_Q_IM_1_STATE = dataBuf[ii];                                                                     /*获取屏蔽门数量*/
				ii += 1u;              /*PSC 接口模块1的状态表示灯*/
				PscToCiDataStru[systemId].devType_PSC_Q_IM_2_STATE = dataBuf[ii];                                                                     /*获取屏蔽门数量*/
				ii += 1u;              /*PSC 接口模块2的状态表示灯*/
				PscToCiDataStru[systemId].devType_PSC_OPEN_FAULT_STATE_UP = dataBuf[ii];                                                                     /*获取屏蔽门数量*/
				ii += 1u;       /*PSC 上行开门故障状态表示灯*/
				PscToCiDataStru[systemId].devType_PSC_CLOSE_FAULT_STATE_UP = dataBuf[ii];                                                                     /*获取屏蔽门数量*/
				ii += 1u;      /*PSC 上行关门故障状态表示灯*/
				PscToCiDataStru[systemId].devType_PSC_OPEN_FAULT_STATE_DOWN = dataBuf[ii];                                                                     /*获取屏蔽门数量*/
				ii += 1u;     /*PSC 下行开门故障状态表示灯*/
				PscToCiDataStru[systemId].devType_PSC_CLOSE_FAULT_STATE_DOWN = dataBuf[ii];                                                                     /*获取屏蔽门数量*/
				ii += 1u;    /*PSC 下行关门故障状态表示灯*/

				psdSum = dataBuf[ii];  
				PscToCiDataStru[systemId].psdSum = psdSum;                                                                                         /*获取屏蔽门数量*/
				ii += 1u;

				for(jj = 0u;jj < psdSum;jj++)
				{
					psdId = LongFromChar(&dataBuf[ii]);  /*获取屏蔽门ID*/
					ii += 4u;

					fucRetun = dquQueryInDevIndex(QFUN_IDMAP_PSD_ID, psdId, &psdIndexId);

					if (fucRetun > 0u)
					{
						rowIndex = PscIndex[psdIndexId][0];/*获取映射点:屏蔽门所属的站台屏蔽门系统ID*/
						colIndex = PscIndex[psdIndexId][1];/*获取映射点:在所属站台屏蔽门系统结构体中，此屏蔽门所处的索引号*/

						PscToCiDataStru[rowIndex].psdDataStr[colIndex].psdId = psdIndexId;

						PscToCiDataStru[rowIndex].psdDataStr[colIndex].psdState = dataBuf[ii++];/*PSD状态*/

						PscToCiDataStru[rowIndex].psdDataStr[colIndex].psdMLockState = dataBuf[ii++];/*互锁解除状态*/
						/*故障隔离状态1*/
						PscToCiDataStru[rowIndex].psdDataStr[colIndex].psdFaultQStataOne = LongFromChar(&dataBuf[ii]);
						ii += 4u;
						/*故障隔离状态2*/
						PscToCiDataStru[rowIndex].psdDataStr[colIndex].psdFaultQStataTwo = LongFromChar(&dataBuf[ii]);
						ii += 4u;
						/*每扇门状态1*/
						PscToCiDataStru[rowIndex].psdDataStr[colIndex].psdDoorsStateOne = LongFromChar(&dataBuf[ii]);
						ii += 4u;
						/*每扇门状态2*/
						PscToCiDataStru[rowIndex].psdDataStr[colIndex].psdDoorsStateTwo = LongFromChar(&dataBuf[ii]);
						ii += 4u;
						/*每扇门被隔离状态1*/
						PscToCiDataStru[rowIndex].psdDataStr[colIndex].psdDoorIStateOne = LongFromChar(&dataBuf[ii]);
						ii += 4u;
					    /*每扇门被隔离状态2*/
						PscToCiDataStru[rowIndex].psdDataStr[colIndex].psdDoorIStateTwo = LongFromChar(&dataBuf[ii]);
						ii += 4u;

					}
					/*本站台门解析错误，跳过对应字节*/
					else
					{
						ii += 26u;
					}
				}
			}
			retVal = CI_SUCCESS;
		} 
		else
		{
			retVal = CI_ERROR;
		}
	}

	return retVal;
}

/*
* 功能描述： 组PSC数据
* 参数说明： UINT8 deviceId, 目标设备ID     
* 返回值  ： 0:组数据失败
*			 1:组数据成功      
*/
UINT8 PackCiToPscData(UINT8 deviceId)
{
	UINT8 localCi = GetSystemParaLocalCiId();                    /*本地联锁ID*/
	UINT8 CiToPscDataBuffer[PSC_TO_CI_DATA_LEN_MAX] = {0u};       /*CI到PSC组帧数组*/
	UINT16 devCurSum = 0u;  /*设备总数*/
	UINT16 devId = 0u; /*设备ID*/
	UINT8 devType = 0u; /*设备类型*/
	UINT16 ii = 0u;
	UINT16 jj = 0u;
	UINT8 indicatorState = 0u;
	UINT8 retVal = 0u;
	UINT16 temDatalen = 0u;
	UINT16 temDataLenIndex = 0u;
	UINT16 dstDevId = 0u;
	UINT8 outnetSafeSendRtn = 0u;

	
	/*通用协议帧头*/
	ii += 2u;
	CiToPscDataBuffer[ii++] = CI_SYSTEM_TYPE_PSC;		              /*目的逻辑类型*/
	CiToPscDataBuffer[ii++] = deviceId;	                              /*目的逻辑ID*/	
	CiToPscDataBuffer[ii++] = 0u;                                      /*预留2Byte*/
	CiToPscDataBuffer[ii++] = 0u;
	/*开始组应用数据帧*/
	ShortToChar(CI_PSC_INTERFACE_INFOTYPE,&CiToPscDataBuffer[ii]);    /*接口信息类型*/
	ii += 2u;
	temDataLenIndex = ii;                                             /*记录总长度索引位置*/
	ii += 2u;

	/*以下为应用层数据*/
	ShortToChar(CI_PSC_INFO_TYPE_PSD_STATE, &CiToPscDataBuffer[ii]);
	ii += 2u;
	/*预留两个字节*/
	ii += 2u;

	devCurSum = GetIndicatorCurSum(); /*获取指示器当前总数*/
		
	for (jj = 0u; jj < devCurSum; jj++)
	{
		devId = GetIndicatorId(jj); /*获取指示器ID*/
		devType = GetIndicatorType(devId); /*获取设备类型*/

		/*###【指示灯】###*/
		if (INDICATOR_TYPE_POWER_SCREEN == devType)
		{
			indicatorState = GetIndicatorState(devId); /*表示灯报警灯状态*/
			if ((INDICATOR_SHOW_YES != indicatorState) && (INDICATOR_SHOW_NO != indicatorState))
			{
				CiToPscDataBuffer[ii++] = ALARM_STATE_DEFAULT; /*设置电源屏报警默认值*/
			}
			else
			{
				if (INDICATOR_SHOW_YES != indicatorState)
				{ /*继电器吸起表示灯无效*/
					CiToPscDataBuffer[ii++] = ALARM_STATE_NO; /*设置电源屏报警无效*/
				}
				else
				{
					CiToPscDataBuffer[ii++] = ALARM_STATE_YES; /*设置电源屏报警有效*/
				}
			}
			
			indicatorState = 0u;/*清除电源屏报警状态*/
		}
		else if (INDICATOR_TYPE_EXPRESS_MAINP == devType)
		{/*主电源指示灯*/
			indicatorState = GetIndicatorState(devId); /*表示灯报警灯状态*/
			if ((INDICATOR_SHOW_YES != indicatorState) && (INDICATOR_SHOW_NO != indicatorState))
			{
				CiToPscDataBuffer[ii++] = ALARM_STATE_DEFAULT; /*设置电源屏报警默认值*/
			}
			else
			{
				if (INDICATOR_SHOW_YES != indicatorState)
				{/*继电器吸起表示灯无效*/
					CiToPscDataBuffer[ii++] = ALARM_STATE_NO; /*设置电源屏报警无效*/
				}
				else
				{
					CiToPscDataBuffer[ii++] = ALARM_STATE_YES; /*设置电源屏报警有效*/
				}
			}
			indicatorState = 0u;/*清除电源屏报警状态*/
		}
		else if (INDICATOR_TYPE_EXPRESS_BACKP == devType)
		{/*副电源指示灯*/
			indicatorState = GetIndicatorState(devId); /*表示灯报警灯状态*/
			if ((INDICATOR_SHOW_YES != indicatorState) && (INDICATOR_SHOW_NO != indicatorState))
			{
				CiToPscDataBuffer[ii++] = ALARM_STATE_DEFAULT; /*设置电源屏报警默认值*/
			}
			else
			{
				if (INDICATOR_SHOW_YES != indicatorState)
				{/*继电器吸起表示灯无效*/
					CiToPscDataBuffer[ii++] = ALARM_STATE_NO; /*设置电源屏报警无效*/
				}
				else
				{
				    CiToPscDataBuffer[ii++] = ALARM_STATE_YES; /*设置电源屏报警有效*/
				}
			}
			indicatorState = 0u;/*清除电源屏报警状态*/
		}
		else
		{/*其他指示灯*/

		}
	}
	/*减去通用帧头以及总长度自身2字节*/
	temDatalen = ii - 2U - temDataLenIndex;

	/*写入应用层报文总长度*/
	ShortToChar(temDatalen,&CiToPscDataBuffer[temDataLenIndex]);

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

/*
* 功能描述： 获取Psc-CI的结构体数据
* 参数说明： void    
* 返回值  ： Psc-CI结构体数组指针      
*/
PSCToCiDataStruct* GetPscToCiDataStru(void)
{
	return PscToCiDataStru;
}

/*
* 功能描述：为指定PSD->CI的结构设置缺省值(安全值) 
* 参数说明： platformId:PSD系统的ID
* 返回值  ： 0:失败
*			 1:成功     
*/
UINT8 SetPscToCiDefaultDataStru(UINT8 pscId)
{
	UINT8 retVal = 0u;
	UINT8 ii;
	UINT8 psdVirArr = 0u;

	if(PSC_TO_CI_SUM_MAX <= pscId)
	{
		retVal = CI_ERROR;
	}
	else
	{
		PscToCiDataStru[pscId].devType_PSC_A_WORK_STATE = ALARM_STATE_DEFAULT;
		/*PSC A系工作状态表示灯*/
		PscToCiDataStru[pscId].devType_PSC_B_WORK_STATE = ALARM_STATE_DEFAULT;
		/*PSC B系工作状态表示灯*/
		PscToCiDataStru[pscId].devType_PSC_SINGLE_COMM_STATE = ALARM_STATE_YES;
		/*PSC 单个通信板故障状态表示灯*/
		PscToCiDataStru[pscId].devType_PSC_FSIO_FAULT_STATE = ALARM_STATE_YES;
		/*PSC FSIO故障状态表示灯*/
		PscToCiDataStru[pscId].devType_PSC_DRIVE_POWER_STATE = ALARM_STATE_YES;
		/*PSC 驱动电源状态表示灯*/
		PscToCiDataStru[pscId].devType_PSC_CONTROL_POWER_STATE = ALARM_STATE_YES; 
		/*PSC 控制电源状态表示灯*/
		PscToCiDataStru[pscId].devType_PSC_Q_IM_1_STATE = ALARM_STATE_YES; 
		/*PSC 接口模块1的状态表示灯*/
		PscToCiDataStru[pscId].devType_PSC_Q_IM_2_STATE = ALARM_STATE_YES; 
		/*PSC 接口模块2的状态表示灯*/
		PscToCiDataStru[pscId].devType_PSC_OPEN_FAULT_STATE_UP = ALARM_STATE_YES; 
		/*PSC 上行开门故障状态表示灯*/
		PscToCiDataStru[pscId].devType_PSC_CLOSE_FAULT_STATE_UP = ALARM_STATE_YES; 
		/*PSC 上行关门故障状态表示灯*/
		PscToCiDataStru[pscId].devType_PSC_OPEN_FAULT_STATE_DOWN = ALARM_STATE_YES;  
		/*PSC 下行开门故障状态表示灯*/
		PscToCiDataStru[pscId].devType_PSC_CLOSE_FAULT_STATE_DOWN = ALARM_STATE_YES;  

		for(ii = 0u;ii < PscToCiDataStru[pscId].psdSum;ii++)
		{
			psdVirArr = GetPsdVirtualAttribute(PscToCiDataStru[pscId].psdDataStr[ii].psdId);
			if (PSD_VIRTUAL_ATTR_YES != psdVirArr)
			{/*非虚拟屏蔽门才设置*/
				PscToCiDataStru[pscId].psdDataStr[ii].psdState = PSD_STATE_INVALID_HLHT;
				PscToCiDataStru[pscId].psdDataStr[ii].psdMLockState = PSD_MUTUALLOCK_REMOVE_DEFAULT;
				/*每扇门在与PSC通信中断时，填写默认值*/
				PscToCiDataStru[pscId].psdDataStr[ii].psdFaultQStataOne = 0xffffffffu;
				PscToCiDataStru[pscId].psdDataStr[ii].psdFaultQStataTwo = 0xffffffffu;
				PscToCiDataStru[pscId].psdDataStr[ii].psdDoorsStateOne = 0xffffffffu;
                PscToCiDataStru[pscId].psdDataStr[ii].psdDoorsStateTwo = 0xffffffffu;
                PscToCiDataStru[pscId].psdDataStr[ii].psdDoorIStateOne = 0xffffffffu;
				PscToCiDataStru[pscId].psdDataStr[ii].psdDoorIStateTwo = 0xffffffffu;
			}
		}
		retVal = CI_SUCCESS;
	}
	return retVal;
}
