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


#include "ParsePackITEData.h"


IteToCiDataStruct IteToCiDataStru[ITE_TO_CI_SUM_MAX] = { 0U };  /*与联锁通信的ITE信息*/
UINT8 IteToCiSum = 0U;  /*与联锁通信的ITE数目*/


/*
* 功能描述：获取与CI通信的ITE通信结构体数组
* 参数说明：void
* 返 回 值：NULL 获取失败
*           非NULL 与CI通信的ITE通信结构体数组
* Created By LQ 2024.06.06
*/
IteToCiDataStruct* GetIteToCiDataStru(void)
{
	IteToCiDataStruct* pRetVal = NULL;

	if (0U != IteToCiSum)
	{
		pRetVal = IteToCiDataStru;
	}
	else
	{
		pRetVal = NULL;  /*无与CI通信的ITE，返回NULL*/
	}

	return pRetVal;
}

/*
* 功能描述：获取与CI通信的ITE通信结构体总数
* 参数说明：无
* 返 回 值：与CI通信的ITE通信结构体总数
* Created By LQ 2024.06.06
*/
UINT8 GetIteToCiSum(void)
{
	return IteToCiSum;
}

/*
* 功能描述：解析处理ITE数据
* 参数说明：const UINT8* dataBuf 数据缓冲区
*           const UINT16 dataLength 数据长度
*           const UINT8 systemId 源设备ID
*           const UINT16 logId ITE互联互通ID（1端或2端标识）
* 返回值  ：CI_ERROR 0 数据解析失败
*			CI_SUCCESS 1 数据解析成功
* Created By LQ 2024.06.05
*/
UINT8 ParseIteToCiData(const UINT8* dataBuf, const UINT16 dataLength, const UINT8 systemId, const UINT16 logId)
{
	UINT8 ii = 0U;
	UINT8 retVal = CI_ERROR;
	UINT8 cGalHeadSavedFlag = CI_ERROR;
	IteToCiDataStruct parseCheckIte = { 0 };
	UINT8 chFind = CI_ERROR;

	if (IteToCiSum < ITE_TO_CI_SUM_MAX)
	{
		retVal = ParseIteToCiDataFrame(dataBuf, dataLength, systemId, &parseCheckIte, &cGalHeadSavedFlag, logId);
		
		if (CI_SUCCESS == retVal)
		{
			/*遍历所有通信的ITE，查找ITE通信结构体中是否已存在当前ITE*/
			for (ii = 0u; ii < IteToCiSum; ii++)
			{				
				if ((IteToCiDataStru[ii].wIteId == parseCheckIte.wIteId) && (IteToCiDataStru[ii].wIteLogId == parseCheckIte.wIteLogId))
				{
					/*目标ITE已存在于通信结构体中，将解析出的数据拷入之前存储的地址*/
					(void)CommonMemSet(&(IteToCiDataStru[ii]), (UINT32)sizeof(IteToCiDataStruct), 0U, (UINT32)sizeof(IteToCiDataStruct));  /*清内存，防止脏数据*/
					(void)CommonMemCpy(&(IteToCiDataStru[ii]), (UINT32)sizeof(IteToCiDataStruct), &parseCheckIte, (UINT32)sizeof(IteToCiDataStruct));
					chFind = CI_SUCCESS;
					break;
				}
				else
				{
					/*继续查找*/
				}
			}
			if (CI_ERROR == chFind)
			{
				/*未找到 新建立通信 进行存储*/
				(void)CommonMemCpy(&(IteToCiDataStru[IteToCiSum]), (UINT32)sizeof(IteToCiDataStruct), &parseCheckIte, (UINT32)sizeof(IteToCiDataStruct));
				IteToCiSum++;
			}
			else
			{
				; /*已存在并更新*/
			}
		}
		else
		{
			(void)CommonMemSet(&(IteToCiDataStru[IteToCiSum]), (UINT32)sizeof(IteToCiDataStruct), 0U, (UINT32)sizeof(IteToCiDataStruct));  /*删除最新一个*/

			/*如果通用头已经保存了，则不执行清除通用头操作，否则，出错后也将清除通用头*/
			if (CI_ERROR == cGalHeadSavedFlag)
			{
				ClearIteHlhtHeadCtx(systemId, logId);
			}
			else
			{
				/*不处理*/
			}

			retVal = CI_ERROR;  /*返回0失败*/
		}
	}
	else
	{
		/*通信数量超限，返回0失败*/
	}

	return retVal;
}


/*
* 功能描述：解析处理ITE单帧数据
* 参数说明：const UINT8* dataBuf, 数据缓冲区
*           const UINT16 dataLength, 数据长度
*           const UINT8 systemId, 源设备ID
*           VobcToCiDataStru vobcToci数据结构体指针
*			UINT8* saveGalHead,通用报文头是否保留,1:保留，0:不保留
*           const UINT16 logId，互联互通4IP VOBC的1端或2端标识
* 返回值  ：CI_ERROR 0 数据解析失败
*			CI_SUCCESS 1 数据解析成功
* Created By LQ 2024.06.05
*/
UINT8 ParseIteToCiDataFrame(const UINT8* pDataBuf, const UINT16 dataLength, const UINT8 systemId, IteToCiDataStruct* pstIteToCiDataStru, UINT8* pSaveGalHead, const UINT16 logId)
{
	UINT8 chRetVal = CI_ERROR;
	UINT16 wIteName = 0U;  /*ITE设备名称：类型+ID*/
	UINT8 cLocalCiId = 0U;  /*本联锁ID*/
	UINT16 wCiName = 0U;  /*联锁设备名称：类型+ID*/
	HLHTGALInfoStruct strHlhtGalHead = { 0U };  /*互联互通包头*/
	UINT16 ii = 0U;  /*索引管理*/
	UINT32 dwCurCycNum = 0U;  /*当前周期号*/
	UINT8 cHeadGalCheckRet = HLHT_HEAD_ERROR;  /*互联互通包头检查结果*/
	UINT32 dwErrorCode = 0U;
	INT32 dwIteInfoRemainValidiy = 0;  /*消息时效性*/
	UINT32 dwTransBadCycCount = 0U;  /*判断通信中断周期数*/
	UINT32 dwAppCycle = 0U;  /*应用周期*/
	UINT16 wApplyDataLenth = 0U;  /*应用数据长度*/
	UINT16 wAppInfoType = 0U;  /*应用信息类型*/
	UINT8 cTrainDir = 0U;  /*列车运行方向*/

	if ((NULL != pDataBuf) && (NULL != pstIteToCiDataStru) && (NULL != pSaveGalHead) && (ITE_TO_CI_DATA_LEN_MAX >= dataLength) && (0U != systemId) && (0U != logId))
	{
		chRetVal = CI_SUCCESS;

		wIteName = (CI_SYSTEM_TYPE_ITE) * 256U + systemId;
		cLocalCiId = GetSystemParaLocalCiId();
		wCiName = (CI_SYSTEM_TYPE_CI) * 256U + cLocalCiId;

		/*解析通用消息包头*/
		strHlhtGalHead.devInterInfoType = ShortFromChar(&pDataBuf[ii]);
		ii += 2U;
		strHlhtGalHead.sourceId = LongFromChar(&pDataBuf[ii]);
		ii += 4U;
		strHlhtGalHead.destId = LongFromChar(&pDataBuf[ii]);
		ii += 4U;
		strHlhtGalHead.emapVerCrc = LongFromChar(&pDataBuf[ii]);
		ii += 4U;
		strHlhtGalHead.crntOwnMsgSN = LongFromChar(&pDataBuf[ii]);
		ii += 4U;
		strHlhtGalHead.comPeriod = ShortFromChar(&pDataBuf[ii]);
		ii += 2U;
		strHlhtGalHead.recvOppMsgSN = LongFromChar(&pDataBuf[ii]);

		ii += 4U;
		strHlhtGalHead.preOwnMsgSN = LongFromChar(&pDataBuf[ii]);
		ii += 4U;
		strHlhtGalHead.prtclVer = pDataBuf[ii++];
		strHlhtGalHead.totalDataLen = ShortFromChar(&pDataBuf[ii]);
		ii += 2U;

		pstIteToCiDataStru->wIteLogId = logId;  /*存储ITE的逻辑ID，1端或2端*/
		dwCurCycNum = Get2oo2CurCycleNum();
		cHeadGalCheckRet = HLHTRecvCommonPacketHeadCheck(wIteName, wCiName, ITE_CI_INTERFACE_INFOTYPE, CI_ITE_PRTCL_VER, &strHlhtGalHead, &dwErrorCode, logId, CI_SYSTEM_TYPE_ITE);

		debug_infor_printf((const)"\nITE %d GAL Check Result:%d errCode:%d", systemId, cHeadGalCheckRet, dwErrorCode);	/*0x55正确，0xaa错误，0x33初始通信帧*/		

		if (HLHT_HEAD_SUCCESS == cHeadGalCheckRet)
		{
			/*计算消息的时效性*/
			dwTransBadCycCount = GetCiAndVobcTransBadEnsureTime();
			dwAppCycle = GetSystemParaAppCycleTime();
			dwIteInfoRemainValidiy = HLHTCommonMsgRemainingValidity(dwTransBadCycCount, dwCurCycNum, dwAppCycle, strHlhtGalHead.recvOppMsgSN, strHlhtGalHead.crntOwnMsgSN, strHlhtGalHead.preOwnMsgSN, strHlhtGalHead.comPeriod);

			if (dwIteInfoRemainValidiy > 0)
			{
				pstIteToCiDataStru->dwComStartCycCount = dwCurCycNum;  /*记录通信起始周期*/

				/*解析应用数据*/
				wApplyDataLenth = ShortFromChar(&pDataBuf[ii]);  /*应用层数据长度*/
				ii += 2U;

				wAppInfoType = ShortFromChar(&pDataBuf[ii]);  /*应用信息类型*/
				ii += 2U;
				
				pstIteToCiDataStru->wIteId = systemId;

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

				if (ITE_CI_INFO_TYPE_POSITION == wAppInfoType)
				{
					pstIteToCiDataStru->wTrainHeadLinkId = ShortFromChar(&pDataBuf[ii]);  /*解析车头所处link ID*/
					ii += 2U;

					pstIteToCiDataStru->dwTrainHeadLinkOffset = LongFromChar(&pDataBuf[ii]);    /*解析车头所处link的偏移量*/
					ii += 4U;

					pstIteToCiDataStru->wTrainTailLinkId = ShortFromChar(&pDataBuf[ii]);  /*解析车尾所处link ID*/
					ii += 2U;

					pstIteToCiDataStru->dwTrainTailLinkOffset = LongFromChar(&pDataBuf[ii]);    /*解析车尾所处link的偏移量*/
					ii += 4U;

					cTrainDir = pDataBuf[ii];  /*解析列车方向*/
					ii++;

					pstIteToCiDataStru->cTrainDir = cTrainDir;

					pstIteToCiDataStru->wForWardOffset = ShortFromChar(&pDataBuf[ii]);  /*解析位置向前方向的误差*/
					ii += 2U;

					pstIteToCiDataStru->wBackOffset = ShortFromChar(&pDataBuf[ii]);  /*解析位置向后方向的误差*/
					ii += 2U;				
				}
				else
				{
					chRetVal = CI_ERROR;  /*应用信息类型非法，返回0失败*/
				}

				if (CI_SUCCESS == chRetVal)
				{
					/*校验数据长度 发送两次长度，内层长度比外层少记录长度的两字节 */
					if ((strHlhtGalHead.totalDataLen != ii - 31U) || (wApplyDataLenth != ii - 33U))
					{
						/* 31为应用数据帧头长度 */
						chRetVal = CI_ERROR;
						debug_infor_printf((const)"\nstrHlhtGalHead.totalDataLen :%d ii %d wApplyDataLenth %d", strHlhtGalHead.totalDataLen, ii, wApplyDataLenth);	/*0x55正确，0xaa错误，0x33初始通信帧*/

					}
					else
					{
						/*继续处理*/
					}
				}
				else
				{
					chRetVal = CI_ERROR;  /*返回0失败*/
				}

				if (CI_SUCCESS == chRetVal)
				{
					SetIteHLHTHeadCtx(systemId, logId, &strHlhtGalHead);  /*数据经过校验，存储通用报文头上下文*/
					*pSaveGalHead = CI_SUCCESS;
				}
				else
				{
					/*不处理*/
				}
			}
			else
			{
				chRetVal = CI_ERROR;  /*超时，返回0失败*/
			}
		}
		else if (HLHT_HEAD_INIT == cHeadGalCheckRet)
		{
			if (dwCurCycNum > 0U)
			{
				SetIteHLHTHeadCtx(systemId, logId, &strHlhtGalHead);  /*存储通用报文头上下文*/
				*pSaveGalHead = CI_SUCCESS;
			}
			else
			{
				/*不处理*/
			}

			chRetVal = CI_ERROR;  /*返回0失败*/
		}
		else
		{
			chRetVal = CI_ERROR;  /*返回0失败*/
		}
	}
	else
	{
		chRetVal = CI_ERROR;  /*入参非法，返回0失败*/
	}

	return chRetVal;
}

/*
* 功能描述：组CI到ITE数据
* 参数说明：void
* 返 回 值：CI_ERROR 0 组包失败
*			CI_SUCCESS 1 组包成功
* Created By LQ 2024.06.06
*/
UINT8 PackCiToIteData(void)
{
	UINT8 retVal = CI_SUCCESS;
	UINT8 ii = 0U;
	UINT8 cInitIteNum = 0U;
	UINT8 szInitIteIdBuf[ITE_TO_CI_SUM_MAX] = { 0U };  /*初始通信状态的ITEID数组*/
	UINT8 szInitIteLogIdBuf[ITE_TO_CI_SUM_MAX] = { 0U };  /*初始通信状态的ITE逻辑ID数组*/
	UINT8 cPackHeartFlag = CI_ERROR;

	/*向正常通信的ITE组包*/
	debug_infor_printf((const)"\nPackCiToIteData IteToCiSum = %d\n", IteToCiSum);  /*打印与CI通信的ITE数目*/
	for (ii = 0U; (ii < IteToCiSum) && (ii < ITE_TO_CI_SUM_MAX); ii++)
	{
		debug_infor_printf((const)"\nITE ID[%d]-ITE LogID[%d]", IteToCiDataStru[ii].wIteId, IteToCiDataStru[ii].wIteLogId);
		retVal &= PackCiToIteDataFrame((UINT8)IteToCiDataStru[ii].wIteId, IteToCiDataStru[ii].wIteLogId);
	}

	/*向初始通信的ITE组包*/
	cPackHeartFlag = GetIteHlhtInitHeadDevs(&cInitIteNum, szInitIteIdBuf, szInitIteLogIdBuf);
	if (CI_SUCCESS == cPackHeartFlag)
	{
		for (ii = 0U; ii < cInitIteNum; ii++)
		{
			debug_infor_printf((const)"\nPackCiToIteData HeartFrame To ITE[%d]", szInitIteIdBuf[ii]);  /*打印与CI初始通信的ITE*/
			retVal &= PackCiToIteDataFrame(szInitIteIdBuf[ii], szInitIteLogIdBuf[ii]);			
		}
	}
	else
	{
		/*不组包*/
	}

	return retVal;
}

/*
* 功能描述：组CI到ITE单帧数据
* 参数说明：const UINT8 iteId 目标ITE ID
*           const UINT16 iteLogId 目标ITE的逻辑ID（1端或2端）
* 返 回 值：0:组数据失败
*			1:组数据成功
*/
UINT8 PackCiToIteDataFrame(const UINT8 iteId, const UINT16 iteLogId)
{
	UINT8 cRetVal = CI_ERROR;
	UINT8 cFuncRet = CI_ERROR;
	UINT8 cLocalCiId = 0U;  /*本地联锁ID*/
	UINT32 dwCiEtcsId = 0U;  /*联锁互联互通ID*/
	UINT32 dwIteEtcsId = 0U;  /*ITE互联互通ID*/
	UINT32 dwEmapCheckVer = 0U;  /*电子地图校验版本号*/
	HLHTHeadContextStru* pstrHlhtHeadCtx = NULL;  /*ITE互联互通报文头上下文数据*/
	UINT32 dwCurCycNum = 0U;
	UINT32 dwAppCycTime = 0U;  /*应用周期*/	
	UINT16 ii = 0U;
	UINT8 szCiToIteDataBuf[ITE_TO_CI_DATA_LEN_MAX] = { 0U };  /*CI到ITE组包数组*/
	UINT16 wGalLenIndex = 0U;
	UINT16 wAppLenIndex = 0U;
	UINT16 wGalLen = 0U;  /*通用报文头中的应用层报文长度*/
	UINT16 wAppLen = 0U;  /*应用层报文长度*/
	UINT16 wDstDevId = 0U;  /*ITE编号（带0x19）*/
	UINT8 cOutnetSafeSendRtn = 0U;  /*发送结果*/
	
	if ((0U < iteId) && (ITE_SUM_MAX > iteId) && (0U < iteLogId) && (VOBC_INC_ITE_SUM_MAX >= iteLogId))
	{
		/*首先获取组包时所需的信息，获取成功才继续组包*/
		cLocalCiId = GetSystemParaLocalCiId();		
		cFuncRet = dquDevName2HlhtId(((UINT16)CI_SYSTEM_TYPE_CI * 256U + cLocalCiId), 0U, &dwCiEtcsId);
		cFuncRet &= dquDevName2HlhtId(((UINT16)CI_SYSTEM_TYPE_ITE * 256U) + iteId, iteLogId, &dwIteEtcsId);
		cFuncRet &= GetCiEmapCheckVer(cLocalCiId, &dwEmapCheckVer, CI_SYSTEM_TYPE_ITE);
		pstrHlhtHeadCtx = GetIteHLHTHeadCtx(iteId, iteLogId);  /*获取指定ITE互联互通报文头上下文数据*/

		if ((CI_SUCCESS == cFuncRet) && (NULL != pstrHlhtHeadCtx))
		{
			cRetVal = CI_SUCCESS;	

			/*开始组包*/
			ShortToChar(ITE_CI_INTERFACE_INFOTYPE, &szCiToIteDataBuf[ii]);  /*接口信息类型*/
			ii += 2U;

			LongToChar(dwCiEtcsId, &szCiToIteDataBuf[ii]);  /*发送方标识信息*/
			ii += 4U;

			LongToChar(dwIteEtcsId, &szCiToIteDataBuf[ii]);  /*接收方标识信息*/
			ii += 4U;

			LongToChar(dwEmapCheckVer, &szCiToIteDataBuf[ii]);  /*电子地图版本校验信息*/
			ii += 4U;

			dwCurCycNum = Get2oo2CurCycleNum();
			LongToChar(dwCurCycNum, &szCiToIteDataBuf[ii]);  /*本方消息序列号*/
			ii += 4U;

			dwAppCycTime = GetSystemParaAppCycleTime();
			ShortToChar((UINT16)dwAppCycTime, &szCiToIteDataBuf[ii]);  /*设备通讯周期*/
			ii += 2U;
			
			LongToChar(pstrHlhtHeadCtx->sourceCrntOwnMsgSN, &szCiToIteDataBuf[ii]);  /*对方消息序列号：收到对方上一条消息中的对方消息序列号*/
			ii += 4U;

			LongToChar(pstrHlhtHeadCtx->ciPreRecvOwnSn, &szCiToIteDataBuf[ii]);  /*收到上一条消息时本方序列号*/
			ii += 4U;

			szCiToIteDataBuf[ii] = CI_ITE_PRTCL_VER;  /*CI_ITE接口协议版本号*/
			ii++;

			wGalLenIndex = ii;  /*通用报文头中的应用层报文总长度*/
			ii += 2U;

			/*以下为应用层数据*/
			wAppLenIndex = ii;  /*应用层报文长度*/
			ii += 2U;

			ShortToChar(CI_ITE_INFO_TYPE_HEART, &szCiToIteDataBuf[ii]);  /*报文类型，两字节*/
			ii += 2U;

			ii += 2U;  /*预留两个字节*/

		    /*通用报文头中应用层报文总长度*/
			wGalLen = ii - (wGalLenIndex + 2U);
			ShortToChar(wGalLen, &szCiToIteDataBuf[wGalLenIndex]);

			/*应用层数据的报文长度 */
			wAppLen = ii - (wAppLenIndex + 2U);
			ShortToChar(wAppLen, &szCiToIteDataBuf[wAppLenIndex]);

			wDstDevId = (UINT16)(CI_SYSTEM_TYPE_ITE << 8U) | ((UINT16)iteId);
			cOutnetSafeSendRtn = OutnetSafeSend(wDstDevId, iteLogId, &szCiToIteDataBuf[0U], ii);
			if (1U == cOutnetSafeSendRtn)
			{ 
				/*写队列成功*/
#ifdef LOGPRINT/*日志打印宏*/                 
#ifdef PLATFORM_2OO2/*2oo2平台打印*/
				debug_infor_printf((const)"\nITE_SEND:%d", ii);
				debug_out_array(0xAA, szCiToIteDataBuf, ii);
#endif/*平台打印结束*/
#endif
				cRetVal = CI_SUCCESS;
			}
			else
			{
				cRetVal = CI_ERROR;  /*写队列失败*/
			}
		}
		else
		{
			cRetVal = CI_ERROR;  /*获取数据失败，不处理，返回0失败*/
		}
	}
	else
	{
		cRetVal = CI_ERROR;  /*入参非法，不处理，返回0失败*/
	}

	return cRetVal;
}

/*
* 功能描述：从ITE发送给CI的信息结构体数组中，删除指定位置及之后的数据
* 参数说明：const UINT8 index ITE发送给CI的信息结构体数组的位置索引
* 返 回 值：无
* Created By LQ 2024.06.05
*/
void RemoveIteToCiMsgAt(const UINT8 index)
{
	UINT8 ii = 0U;

	if (index < IteToCiSum)
	{
		for (ii = index; ii < IteToCiSum; ii++)
		{
			(void)CommonMemSet(&(IteToCiDataStru[ii]), (UINT32)sizeof(IteToCiDataStruct), 0U, (UINT32)sizeof(IteToCiDataStruct));
		}

		IteToCiSum = index;
	}
	else
	{
		/*索引超限，不处理*/
	}
}