/********************************************************
*                                                                                                            
* 文 件 名： ParsePackTmcData.c   
* 版权说明： 北京交控科技有限公司 
* 创建时间： 2022-06-15
* 作    者： 联锁组
* 功能描述： TMC解析组包
* 修改记录：   
*
********************************************************/ 

#include "ParsePackTmcData.h"
#include "../QueryFiles/dquCIInterFace.h"
#include "../HLHTMsgHead/HLHTHeadContexManage.h"
#include "../HLHTMsgHead/HLHTCommonDataPacketHead.h"
#include "SystemParameterManage.h"

/* 输入缓冲 */
static TmcToTiocDataStruct g_TmcToTiocDataStru = { 0u };



/*
* 功能描述： 解析临时限速信息
* 参数说明： const UINT8* dataBuf, 数据缓冲区
*            const UINT16 dataLength, 数据长度
*            const UINT8 systemId, 源设备ID 暂时不用 预留
* 返回值  ： 0: 数据解析失败
*			 1: 数据解析成功
*/
static UINT8 ParseTsrData(UINT8* dataBuf, UINT16 dataLen);

/*
* 功能描述： 组TMC临时限速数据
* 参数说明：UINT8* TiocToTmcDataBuffer 数据地址
* 返回值  ： 0:组数据失败
*			 其他:整包数据长度
*/
static UINT16 PackToTmcTsrData(UINT8* TiocToTmcDataBuffer);

/*
* 功能描述： 组TMC临时雨雪模式数据
* 参数说明：UINT8* TiocToTmcDataBuffer 数据地址
* 返回值  ： 0:组数据失败
*			 其他:整包数据长度
*/
static UINT16 PackToTmcSnowData(UINT8* TiocToTmcDataBuffer);

/*
* 功能描述： 组TMC全线免筛数据
* 参数说明：UINT8* TiocToTmcDataBuffer 数据地址
* 返回值  ： 0:组数据失败
*			 其他:整包数据长度
*/
static UINT16 PackToTmcWLScreenData(UINT8* TiocToTmcDataBuffer);

/*
* 功能描述： 解析全线雨雪模式信息
* 参数说明： const UINT8* dataBuf, 数据缓冲区
*            const UINT16 dataLength, 数据长度
*            const UINT8 systemId, 源设备ID 暂时不用 预留
* 返回值  ： 0: 数据解析失败
*			 1: 数据解析成功
*/
static UINT8 ParseSnowData(UINT8* dataBuf, UINT16 dataLen);

/*
* 功能描述： 解析全线免筛信息
* 参数说明： const UINT8* dataBuf, 数据缓冲区
*            const UINT16 dataLength, 数据长度
*            const UINT8 systemId, 源设备ID 暂时不用 预留
* 返回值  ： 0: 数据解析失败
*			 1: 数据解析成功
*/
static UINT8 ParseWLSData(UINT8* dataBuf, UINT16 dataLen);

/*
* 功能描述：解析ITE切除信息
* 参数说明：const UINT8* dataBuf, 数据缓冲区
*           const UINT16 dataLength, 数据长度
* 返 回 值：CI_ERROR 0 数据解析失败
*			CI_SUCCESS 1 数据解析成功
* Created By LQ 2024.07.12
*/
static UINT8 ParseIteCutData(UINT8* dataBuf, UINT16 dataLen);

/*
* 功能描述：组ITE切除信息
* 参数说明：UINT8* TiocToTmcDataBuffer 数据地址
* 返 回 值：0 组数据失败
*			其他 整包数据长度
* Created By LQ 2024.07.12
*/
static UINT16 PackToTmcIteCutData(UINT8* TiocToTmcDataBuffer);

/*
* 功能描述：解析全线通信车信息
* 参数说明：const UINT8* dataBuf, 数据缓冲区
*           const UINT16 dataLength, 数据长度
* 返 回 值：CI_ERROR 0 数据解析失败
*			CI_SUCCESS 1 数据解析成功
* Created By LQ 2024.07.12
*/
static UINT8 ParseLineCTData(UINT8* dataBuf, UINT16 dataLen);

/*
* 功能描述：组TMC全线通信车数据
* 参数说明：UINT8* TiocToTmcDataBuffer 数据地址
* 返 回 值：0 组数据失败
*			其他 整包数据长度
* Created By LQ 2024.07.14
*/
static UINT16 PackToTmcLineCTData(UINT8* TiocToTmcDataBuffer);

/*
* 功能描述： 解析Tmc单帧数据
* 参数说明： const UINT8* dataBuf, 数据缓冲区
*            const UINT16 dataLength, 数据长度
*            const UINT8 systemId, 源设备ID 暂时不用 预留
* 返回值  ： 0: 数据解析失败
*			 1: 数据解析成功      
*/
UINT8 ParseTmcToTiocDataFrame(UINT8* dataBuf, UINT16 dataLength, UINT8 systemId)
{
	UINT8* sourceId = NULL;		/*源ID*/
	UINT16 ii = 0u;
	UINT8 retVal = CI_ERROR;
	UINT8 galHeadSaved = 0u;	/*通用头是否已保存标志，1保存；0未保存*/
	UINT32 curntCycleNo = 0u;				/*当前周期号*/
	UINT32 errCode = 0u;
	UINT16 wTmcName = 0u;						/*ZC设备名称：类型+ID*/
	UINT16 wTiocName = 0u;						/*联锁设备名称：类型+ID*/
	UINT8 localCiId = 0u;					/*联锁ID*/
	UINT8 headRet = HLHT_HEAD_ERROR;/*互联互通检查结果*/			
	INT32 InfoRemainValidity = 0;
	UINT8 cTiocTmcPrtclVersion = TIOC_TMC_PRTCL_VER;	/* 接口协议版本号 */
	UINT8 cFunRetVal = CI_ERROR;
	UINT16 wMsgLen = 0u;
	UINT16 wMsgCheckLen = 0u;			/* 用于解析校验的数据长度 */
	UINT16 wMsgType = 0u;
	UINT16 wTmpDataLen = 0u;
	UINT32 TiocAndTmcTransmitBadEnsureTime = 0u;     /*TIOC与TMC通信中断确认时间*/
	UINT32 SystemParaAppCycleTime = 0u;             /*联锁应用周期*/
	UINT8 cTiocId = 0u;
	HLHTGALInfoStruct hlhtGalHead = { 0u };
	UINT32 dwParseStep = 0U;

	localCiId = GetSystemParaLocalCiId();	/*获取联锁ID*/
	wTmcName = (CI_SYSTEM_TYPE_TMC)*256U + systemId;
	wTiocName = (CI_SYSTEM_TYPE_CI)*256U + localCiId;
	curntCycleNo = Get2oo2CurCycleNum();

	/* 清空接收数据 */
	ClearTmcToTiocData();

	if ((NULL != dataBuf) && (dataLength > 0u))
	{
		/*解析通用消息包头*/
		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;

		headRet = HLHTRecvCommonPacketHeadCheck(wTmcName, wTiocName, TIOC_TMC_INTERFACE_INFOTYPE, TIOC_TMC_PRTCL_VER, &hlhtGalHead, &errCode, 0u, CI_SYSTEM_TYPE_TMC);
		

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

		if (HLHT_HEAD_SUCCESS==headRet)
		{/*GAL消息包头校验通过*/
			/*计算消息的时效性*/
			TiocAndTmcTransmitBadEnsureTime = GetTiocAndTmcTransBadEnsureTime();
			SystemParaAppCycleTime = GetSystemParaAppCycleTime();
			InfoRemainValidity = HLHTCommonMsgRemainingValidity(TiocAndTmcTransmitBadEnsureTime, curntCycleNo, SystemParaAppCycleTime, hlhtGalHead.recvOppMsgSN, hlhtGalHead.crntOwnMsgSN, hlhtGalHead.preOwnMsgSN, hlhtGalHead.comPeriod);

			if (0 < InfoRemainValidity )
			{/*报文有效，继续解析*/

				if (0u == hlhtGalHead.totalDataLen)
				{
					/* 仅有GAL头信息 */
					retVal = CI_ERROR;
				}
				else if (2u > hlhtGalHead.totalDataLen)
				{
					/* 数据长度错误,返回失败 */
					retVal = CI_ERROR;
				}
				else
				{
					retVal = CI_SUCCESS;
					while (wTmpDataLen < hlhtGalHead.totalDataLen)
					{
						/* 一条应用数据长度 */
						wMsgLen = ShortFromChar(&dataBuf[ii]); 
						ii += 2u;
						wTmpDataLen += 2U;
						wTmpDataLen += wMsgLen;

						if (0u == wMsgLen)
						{
							; /* 无处理，继续解析下一包 */
						}
						else if(5u > wMsgLen)
						{
							/* 单包长度不对 */
							retVal = CI_ERROR;
						}
						else
						{
							/* 获取报文类型 */
							wMsgType = ShortFromChar(&dataBuf[ii]);
							ii += 2u;

							/* 跳过预留 */
							ii += 2u;

							wMsgCheckLen = wMsgLen - 4u;
							switch (wMsgType)
							{
							case TMC_TO_TIOC_TSR_MSG:
								/* 解析TMC临时限速信息 */
								retVal = ParseTsrData(&dataBuf[ii], wMsgCheckLen);
								dwParseStep |= 0x10000U;
								debug_infor_printf((const)"\n ParseTsrData:%d", retVal);	
								break;
							case TMC_TO_TIOC_SNOW_MSG:
								/*解析全线雨雪模式信息*/
								retVal = ParseSnowData(&dataBuf[ii], wMsgCheckLen);
								dwParseStep |= 0x01000U;
								debug_infor_printf((const)"\n ParseSnowData:%d", retVal);
								break;
							case TMC_TO_TIOC_WLS_MSG:
								/* 解析免筛信息 */
								retVal = ParseWLSData(&dataBuf[ii], wMsgCheckLen);
								dwParseStep |= 0x00100U;
								debug_infor_printf((const)"\n ParseWLSData:%d", retVal);
								break;
							case TMC_TO_TIOC_ITELINECUT_MSG:
								/* 解析ITE全线切除信息 */
								retVal = ParseIteCutData(&dataBuf[ii], wMsgCheckLen);
								dwParseStep |= 0x00010U;
								debug_infor_printf((const)"\n ParseIteCutData:%d", retVal);
								break;
							case TMC_TO_TIOC_LINECT_MSG:
								/* 解析全线通信车信息 */
								retVal = ParseLineCTData(&dataBuf[ii], wMsgCheckLen);
								dwParseStep |= 0x00001U;
								debug_infor_printf((const)"\n ParseLineCTData:%d", retVal);
								break;
							default:
								retVal = CI_ERROR;
								break;
							}

							if (CI_SUCCESS == retVal)
							{
								/* 解析成功，跳过该数据包 */
								ii += wMsgCheckLen;
							}
							else
							{
								; /*do nothing*/
							}
						}

						if (CI_ERROR == retVal)
						{
							break;
						}
						else
						{
							;  /*do nothing*/
						}
					}

					/*校验TMC发送的帧是否完整，每加一帧、位得加1*/
					if ((CI_SUCCESS == retVal) && (0x11111U != dwParseStep))
					{
						debug_infor_printf((const)"\nParseTmcToTiocDataFrame Error: ParseStep Is 0x%05x\n", dwParseStep);
						retVal = CI_ERROR;  /*缺少某帧，解析失败*/
					}
					else
					{
						/*不处理*/
					}
				}

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

					galHeadSaved = 1;
				}
				else
				{
					; /*do nothing*/
				}
			}
			else
			{
				
				debug_infor_printf((const)"\n InfoRemainValidity:%d", InfoRemainValidity); /*报文无效 do nothing*/
			}
		}
		else if (HLHT_HEAD_INIT ==headRet)
		{
			if (curntCycleNo > 0u)/*判断序号大于0，因为把0当做无效序号*/
			{
				SetHLHTHeadCtxComPeriod(CI_SYSTEM_TYPE_TMC, systemId, hlhtGalHead.comPeriod);
				SetHLHTHeadCtxSrcCrntSN(CI_SYSTEM_TYPE_TMC, systemId, hlhtGalHead.crntOwnMsgSN);
				SetHLHTHeadCtxSrcOppSN(CI_SYSTEM_TYPE_TMC, systemId, hlhtGalHead.recvOppMsgSN);
				SetHLHTHeadCtxSrcOwnSN(CI_SYSTEM_TYPE_TMC, systemId, hlhtGalHead.preOwnMsgSN);
				SetHLHTHeadCtxCiRcvSN(CI_SYSTEM_TYPE_TMC, systemId, curntCycleNo);
				SetHLHTHeadCtxCiRcvLogId(CI_SYSTEM_TYPE_TMC, systemId, 0u);

				galHeadSaved = 1;
			}
			else
			{
				;  /*do nothing*/
			}

			retVal = CI_ERROR;
		}
		else
		{
			
			/*给ATS或现地反馈TMC-CI数据版本校验失败信息*/
			if (GAL_COMPARE_EMAP_VER_COMP_ERR == (errCode & GAL_COMPARE_EMAP_VER_COMP_ERR))
			{/*记录通信故障码*/
				SetErrorData(EFUNC_PARSE_TMC2CI_DATA, CI_SYSTEM_TYPE_TMC, 0U, ETYPE_COMM_WITH_TMC, CI_BACK_DATA_VER_CHECK_FAIL, ESEND_LEVEL_ATS);
			}
			else
			{
				; /*不记录*/
			}
			retVal = CI_ERROR;
		}
	}
	else
	{
		retVal = CI_ERROR;
	}

	if ((CI_ERROR == retVal) || (0u == galHeadSaved))
	{
		/*清除通用报文头*/
		ClearHlhtHeadCtx(CI_SYSTEM_TYPE_TMC, systemId);
	}
	else
	{
		;  /*do nothing*/
	}

	/* 通用信息头校验通过，更新通信周期 */
	if (1u == galHeadSaved)
	{
		cTiocId = GetSystemParaLocalCiId();   /*获取本机联锁ID*/
		sourceId = GetCiTransmitSpecifySysDevBuf(CI_SYSTEM_TYPE_TMC);/*获取与本TIOC通信的TMC的ID，目前一个联锁最多只与一个TMC通信*/
		if (NULL == sourceId)
		{
			cFunRetVal = CI_ERROR;
		}
		else
		{
			cFunRetVal = SetCiTransmitRecvDataCycNum(cTiocId, CI_SYSTEM_TYPE_TMC, sourceId[0], Get2oo2CurCycleNum());
		}

		if (CI_ERROR == cFunRetVal)
		{/*更新周期失败*/

		}
		else
		{/*更新周期成功*/
			cFunRetVal = UpdateCiTransmitState(cTiocId, CI_SYSTEM_TYPE_TMC, sourceId[0]);

			/*更新与TMC通信状态：判断与TMC是否通信中断*/
			if (CI_ERROR == cFunRetVal)
			{
				/*更新通信状态失败,无处理*/
			}
			else
			{
				/*更新通信状态成功*/
			}
		}
	}
	else
	{
		;  /*do nothing*/
	}

	if (CI_ERROR == retVal)
	{
		/* 清除收到的应用信息 */
		ClearTmcToTiocData();
	}
	else
	{
		;  /*do nothing*/
	}

	return retVal;
}

/*
* 功能描述： 解析临时限速信息
* 参数说明： const UINT8* dataBuf, 数据缓冲区
*            const UINT16 dataLength, 数据长度
*            const UINT8 systemId, 源设备ID 暂时不用 预留
* 返回值  ： 0: 数据解析失败
*			 1: 数据解析成功
*/
static UINT8 ParseTsrData(UINT8* dataBuf, UINT16 dataLen)
{
	UINT8 cRetVal = CI_ERROR;
	UINT8 cFunRetVal = 0u; /* 返回结果 */
	UINT16 ii = 0u;
	UINT8 jj = 0u;
	UINT8 kk = 0u;
	TsrDataStruct* pTmpTsrInfo = NULL;
	UINT8 cTiocId = 0u;
	UINT8 cDevTiocId = 0u;
	UINT16 tsrMaxCmdSum = 0u;
	UINT16 tsrMaxSecSum = 0u;

	if (NULL == dataBuf)
	{
		cRetVal = CI_ERROR;
	}
	else
	{
		tsrMaxCmdSum = GetTsrMaxCmdSum();
		tsrMaxSecSum = GetTsrMaxSecSum();
		cRetVal = CI_SUCCESS;
	}

	/* 临时限速有效标志位 */
	if (CI_SUCCESS == cRetVal)
	{
		g_TmcToTiocDataStru.tsrInputInfoStru.cTsrValidFlag = dataBuf[ii];
		ii++;
		if ((0x55U == g_TmcToTiocDataStru.tsrInputInfoStru.cTsrValidFlag) || (0xAAU == g_TmcToTiocDataStru.tsrInputInfoStru.cTsrValidFlag))
		{
			cRetVal = CI_SUCCESS;
		}
		else
		{
			cRetVal = CI_ERROR;
		}
	}
	else
	{
		; /*校验失败 do nothing*/
	}

	/* 全线临时限速信息 */
	if (CI_SUCCESS == cRetVal)
	{
		g_TmcToTiocDataStru.tsrInputInfoStru.cAllLineTsrState = dataBuf[ii];
		ii++;

		g_TmcToTiocDataStru.tsrInputInfoStru.cAllLineTsrSpeed = dataBuf[ii];
		ii++;

		if (((0x55U == g_TmcToTiocDataStru.tsrInputInfoStru.cAllLineTsrState) && (0u == g_TmcToTiocDataStru.tsrInputInfoStru.cAllLineTsrSpeed))
			||((0xAAU == g_TmcToTiocDataStru.tsrInputInfoStru.cAllLineTsrState) && (0u < g_TmcToTiocDataStru.tsrInputInfoStru.cAllLineTsrSpeed)))
		{
			cRetVal = CI_SUCCESS;
		}
		else
		{
			cRetVal = CI_ERROR;
		}
	}
	else
	{
		; /*do nothing*/
	}

	/* 解析临时限速数量 */
	if (CI_SUCCESS == cRetVal)
	{
		g_TmcToTiocDataStru.tsrInputInfoStru.cTsrSum = dataBuf[ii];
		ii++;
		if ((TSR_MAX_SUM < g_TmcToTiocDataStru.tsrInputInfoStru.cTsrSum) || (tsrMaxCmdSum < g_TmcToTiocDataStru.tsrInputInfoStru.cTsrSum))
		{
			cRetVal = CI_ERROR;
		}
		else
		{
			;  /* do nothing */
		}
		//防护临时限速信息有效标志为无效，但临时限速数量不为0的情况
		if ((0U != g_TmcToTiocDataStru.tsrInputInfoStru.cTsrSum) && (0xAAU == g_TmcToTiocDataStru.tsrInputInfoStru.cTsrValidFlag))
		{
			cRetVal = CI_ERROR;
		}
		else
		{
			; /* do nothing */
		}
	}
	else
	{
		; /* do nothing */
	}

	/* 解析临时限速数量 */
	if (CI_SUCCESS == cRetVal)
	{
		cTiocId = GetSystemParaLocalCiId();	/*获取联锁ID*/

		for (jj = 0u; jj < g_TmcToTiocDataStru.tsrInputInfoStru.cTsrSum;jj++)
		{
			/* 限速值 */
			g_TmcToTiocDataStru.tsrInputInfoStru.szTsrInfo[jj].cSpeed = dataBuf[ii];
			ii++;
			if ((0u == g_TmcToTiocDataStru.tsrInputInfoStru.szTsrInfo[jj].cSpeed)
				|| (UINT8_MAX == g_TmcToTiocDataStru.tsrInputInfoStru.szTsrInfo[jj].cSpeed))
			{
				cRetVal = CI_ERROR;
			}
			else
			{
				; /* do nothing */
			}

			/* 限速区段数量 */
			if (CI_SUCCESS == cRetVal)
			{
				g_TmcToTiocDataStru.tsrInputInfoStru.szTsrInfo[jj].cLogSecSum = dataBuf[ii];
				ii++;
				if ((TSR_SEC_MAX_SUM < g_TmcToTiocDataStru.tsrInputInfoStru.szTsrInfo[jj].cLogSecSum)
					||(0u == g_TmcToTiocDataStru.tsrInputInfoStru.szTsrInfo[jj].cLogSecSum)
					||(tsrMaxSecSum < g_TmcToTiocDataStru.tsrInputInfoStru.szTsrInfo[jj].cLogSecSum))
				{
					cRetVal = CI_ERROR;
				}
				else
				{
					; /* do nothing */
				}
			}
			else
			{
				; /* do nothing */
			}

			/* 限速区段ID */
			if (CI_SUCCESS == cRetVal)
			{
				pTmpTsrInfo = &g_TmcToTiocDataStru.tsrInputInfoStru.szTsrInfo[jj];
				for (kk = 0u; kk < pTmpTsrInfo->cLogSecSum;kk++)
				{
					pTmpTsrInfo->szLogSecId[kk] = ShortFromChar(&dataBuf[ii]);
					ii += 2u;

					if ((0u == pTmpTsrInfo->szLogSecId[kk]) || (UINT16_MAX == pTmpTsrInfo->szLogSecId[kk]))
					{
						cRetVal = CI_ERROR;
					}
					else
					{
						cDevTiocId = GetLogSecBelongCiId(pTmpTsrInfo->szLogSecId[kk]);

						if ((0u != cTiocId) && (cDevTiocId == cTiocId))
						{
							; /* 是本TIOC的逻辑区段 */
						}
						else
						{
							cRetVal = CI_ERROR;
						}
					}

					if (CI_ERROR == cRetVal)
					{
						break;
					}
					else
					{
						; /* do nothing */
					}
				}

			}
			else
			{
				; /* do nothing */
			}

			if (CI_ERROR == cRetVal)
			{
				break;
			}
			else
			{
				;  /* do nothing */
			}
		}
	}
	else
	{
		;  /* do nothing */
	}

	if (dataLen != ii)
	{
		cRetVal = CI_ERROR;
	}
	else
	{
		; /* do nothing */
	}

	return cRetVal;
}

/*
* 功能描述： 解析全线雨雪模式信息
* 参数说明： const UINT8* dataBuf, 数据缓冲区
*            const UINT16 dataLength, 数据长度
*            const UINT8 systemId, 源设备ID 暂时不用 预留
* 返回值  ： 0: 数据解析失败
*			 1: 数据解析成功
*/
static UINT8 ParseSnowData(UINT8* dataBuf, UINT16 dataLen)
{
	UINT8 cRetVal = CI_ERROR;
	UINT16 ii = 0u;
	UINT8 jj = 0U;
	UINT16 wPlatFormId = 0U;  /*站台互联互通ID*/
	UINT8 cPlatFormNum = 0U;  /*站台数量*/
	UINT8 cTmepNum = 0U;
	UINT8 cPlatFormBelongCiId = 0U;  /*站台关联Link所属CI*/
	UINT8 cLocalCiId = 0U;
	UINT8 cSnowLevel = 0U;  /*湿轨等级*/

	if (NULL == dataBuf)
	{
		cRetVal = CI_ERROR;
	}
	else
	{
		cRetVal = CI_SUCCESS;
	}

	/*解析全线雨雪/湿轨信息*/
	if (CI_SUCCESS == cRetVal)
	{
		g_TmcToTiocDataStru.cSnowValidFlag = dataBuf[ii];  /*全线雨雪/湿轨模式*/
		ii++;
		if ((CI_ALL_SNOW_VALID == g_TmcToTiocDataStru.cSnowValidFlag) || (CI_ALL_SNOW_UNVALID == g_TmcToTiocDataStru.cSnowValidFlag))
		{
			cSnowLevel = dataBuf[ii];  /*全线湿轨等级*/
			ii++;
			if ((CI_SNOW_LEVEL_DEFAULT == cSnowLevel) || (CI_SNOW_LEVEL_ONE == cSnowLevel) || (CI_SNOW_LEVEL_TWO == cSnowLevel))
			{
				g_TmcToTiocDataStru.cSnowLevel = cSnowLevel;
			}
			else
			{
				cRetVal = CI_ERROR;
			}
		}
		else
		{
			cRetVal = CI_ERROR;
		}
	}

	/*解析区间雨雪站台信息*/
	if (CI_SUCCESS == cRetVal)
	{
		cPlatFormNum = dataBuf[ii];  /*解析区间雨雪站台数量*/
		ii++;
		
		if (ALL_AREA_SNOW_SUM_MAX >= cPlatFormNum)
		{
			cLocalCiId = GetSystemParaLocalCiId();
			for (jj = 0U; jj < cPlatFormNum; jj++)
			{
				wPlatFormId = ShortFromChar(&dataBuf[ii]);  /*解析区间雨雪站台ID*/
				ii += 2U;
				cSnowLevel = dataBuf[ii];  /*区间湿轨等级*/
				ii++;

				if ((0U < wPlatFormId) && (UINT16_MAX > wPlatFormId)
					&& (CI_SNOW_LEVEL_DEFAULT == cSnowLevel) || (CI_SNOW_LEVEL_ONE == cSnowLevel) || (CI_SNOW_LEVEL_TWO == cSnowLevel))
				{
					cPlatFormBelongCiId = GetAreaSnowPlatFormBelongCiId(wPlatFormId);  /*获取区间雨雪站台所属控区*/
					if ((cLocalCiId == cPlatFormBelongCiId) && (0U != cLocalCiId))
					{
						if (LOCAL_AREA_SNOW_SUM_MAX > cTmepNum)
						{
							g_TmcToTiocDataStru.szAreaSnowInfo[cTmepNum].wAreaId = wPlatFormId;
							g_TmcToTiocDataStru.szAreaSnowInfo[cTmepNum].cAreaSnowLevel = cSnowLevel;
							cTmepNum++;
						}
						else
						{
							cRetVal = CI_ERROR;  /*本控区区间雨雪站台数量超限，停止遍历，返回失败*/
							break;
						}
					}
					else
					{
						/*非本控区站台，不保存*/
					}
				}
				else
				{
					/*雨雪模式编号ID非法或区间湿轨等级非法，返回失败*/
					cRetVal = CI_ERROR;
				}
			}

			g_TmcToTiocDataStru.cAreaSnowPlatFormNum = cTmepNum;
		}
		else
		{
			cRetVal = CI_ERROR;  /*区间雨雪站台数量超限，返回失败*/
		}
	}
	else
	{
		/*解析失败，返回失败*/
	}

	if (dataLen != ii)
	{
		cRetVal = CI_ERROR;
	}
	return cRetVal;
}

/*
* 功能描述： 解析全线免筛信息
* 参数说明： const UINT8* dataBuf, 数据缓冲区
*            const UINT16 dataLength, 数据长度
*            const UINT8 systemId, 源设备ID 暂时不用 预留
* 返回值  ： 0: 数据解析失败
*			 1: 数据解析成功
*/
static UINT8 ParseWLSData(UINT8* dataBuf, UINT16 dataLen)
{
	UINT8 cRetVal = CI_ERROR;
	UINT16 ii = 0u;
	UINT8 jj = 0u;
	WLScreenReciveStruct g_WLScreenReciveStruc = { 0u };
	
	

	if (NULL == dataBuf)
	{
		cRetVal = CI_ERROR;
	}
	else
	{
		cRetVal = CI_SUCCESS;
	}

	/* 免筛序列号 */
	if (CI_SUCCESS == cRetVal)
	{
		g_WLScreenReciveStruc.recvSeq = LongFromChar(&dataBuf[ii]);  /*免筛序列号*/
		ii += 4u;
		/*全线免筛标志*/
		g_WLScreenReciveStruc.WLScreenVaildFlag = dataBuf[ii];
		ii++;
		if ((0x55u == g_WLScreenReciveStruc.WLScreenVaildFlag) || (0xAAu == g_WLScreenReciveStruc.WLScreenVaildFlag))
		{
			cRetVal = CI_SUCCESS;
		}
		else
		{
			cRetVal = CI_ERROR;
		}
	}

	

	/* 正线范围内受控车信息*/
	if (CI_SUCCESS == cRetVal)
	{
		g_WLScreenReciveStruc.WLTrainCnt = dataBuf[ii];
		ii++;
		for (jj = 0u; jj < g_WLScreenReciveStruc.WLTrainCnt; jj++)
		{
			g_WLScreenReciveStruc.WLTrainID[jj] = ShortFromChar(&dataBuf[ii]);
			ii += 2u;

			if ((0u == g_WLScreenReciveStruc.WLTrainID[jj]) || (UINT8_MAX <= g_WLScreenReciveStruc.WLTrainID[jj]))
			{
				cRetVal = CI_ERROR;
			}
			else
			{
				;
			}
			if (CI_ERROR == cRetVal)
			{
				break;
			}
		}
	}

	if (dataLen != ii)
	{
		cRetVal = CI_ERROR;
	}
	
	if (CI_SUCCESS == cRetVal)
	{
		wls_RefreshWLSInfoFromTMC(&g_WLScreenReciveStruc);
	}
		
	return cRetVal;
}

/*
* 功能描述： 组TMC数据
* 参数说明：UINT8 deviceId TMC编号   
* 返回值  ： 0:组数据失败
*			 1:组数据成功      
*/
UINT8 PackTiocToTmcData( UINT8 deviceId)
{
	UINT8 localCi = 0u; /*本地联锁ID*/
    UINT8 TiocToTmcDataBuffer[TIOC_TO_TMC_DATA_LEN_MAX] = {0u};/*CI到ZC组帧数组*/
	UINT16 ii = 0u;
	UINT32 cTiocEtcsId = 0u;/*TIOC互联互通编号*/
	UINT32 cTmcEtcsId = 0u;	/*TMC互联互通编号*/
	UINT32 emapCheckVer = 0u;	/*共用数据校验信息*/
	UINT8 retVal = CI_ERROR;
	UINT16 dstDevId = 0;
	UINT8 outnetSafeSendRtn = 0u;
	UINT32 curCycleNum = 0u;	/*联锁应用周期号*/
	UINT32 appCycleTime = 0u;	/*联锁应用周期*/
	UINT16 wAppDataLenIndex = 0u;	/* 应用数据长度位置 */
	UINT16 wAppDataLen = 0u;	/* 应用数据长度 */
	UINT16 wMagLen = 0u;	/* 单包数据长度 */

	UINT32 dwHlhtHSrcSN = 0u;
	UINT32 dwHlhtHRcvSN = 0u;
	UINT8 cStep = 0u;
	UINT8 cStepRetVal = CI_ERROR;

	curCycleNum = Get2oo2CurCycleNum();
	appCycleTime = GetSystemParaAppCycleTime();
	localCi = GetSystemParaLocalCiId(); /*获取本地联锁ID*/

	/* 获取GAL头信息 */
	retVal = dquDevName2HlhtId((CI_SYSTEM_TYPE_CI * 256U) + localCi, 0U, &cTiocEtcsId);
	retVal &= dquDevName2HlhtId((CI_SYSTEM_TYPE_TMC * 256U) + deviceId, 0U, &cTmcEtcsId);
	retVal &= GetCiEmapCheckVer(localCi, &emapCheckVer, CI_SYSTEM_TYPE_TMC);
	dwHlhtHSrcSN = GetHLHTHeadCtxSrcCrntSN(CI_SYSTEM_TYPE_TMC, deviceId);
	dwHlhtHRcvSN = GetHLHTHeadCtxCiRcvSN(CI_SYSTEM_TYPE_TMC, deviceId);

	if (CI_SUCCESS == retVal)
	{
		/*组GAL包头*/
		ShortToChar(TIOC_TMC_INTERFACE_INFOTYPE, &TiocToTmcDataBuffer[ii]);/*接口信息类型*/
		ii += 2u;
		LongToChar(cTiocEtcsId, &TiocToTmcDataBuffer[ii]);/*发送方标识信息*/
		ii += 4u;
		LongToChar(cTmcEtcsId, &TiocToTmcDataBuffer[ii]);/*接收方标识信息*/
		ii += 4u;
		LongToChar(emapCheckVer, &TiocToTmcDataBuffer[ii]);/*电子地图版本校验信息*/
		ii += 4u;
		LongToChar(curCycleNum, &TiocToTmcDataBuffer[ii]);/*本方消息序列号*/
		ii += 4u;
		ShortToChar((UINT16)appCycleTime, &TiocToTmcDataBuffer[ii]);/*设备通讯周期*/
		ii += 2u;
		LongToChar(dwHlhtHSrcSN, &TiocToTmcDataBuffer[ii]);/*对方消息序列号：recvOppMsgSN记录收到对方上一条消息中的对方消息序列号*/
		ii += 4u;
		LongToChar(dwHlhtHRcvSN, &TiocToTmcDataBuffer[ii]);/*收到上一条消息时本方序列号*/
		ii += 4u;

		TiocToTmcDataBuffer[ii++] = TIOC_TMC_PRTCL_VER;/*CI_TMC接口协议版本号*/

													   /* 应用数据长度 */
		wAppDataLenIndex = ii;
		ii += 2u;

		cStepRetVal = CI_SUCCESS;
		while (CI_ERROR != cStepRetVal)
		{
			wMagLen = 0u;
			switch (cStep)
			{
			case 0u:
				wMagLen = PackToTmcTsrData(&TiocToTmcDataBuffer[ii]);
				break;
			case 1u:
				wMagLen = PackToTmcSnowData(&TiocToTmcDataBuffer[ii]);
				break;
			case 2u:
				wMagLen = PackToTmcWLScreenData(&TiocToTmcDataBuffer[ii]);
				break;
			case 3u:
				wMagLen = PackToTmcIteCutData(&TiocToTmcDataBuffer[ii]);
				break;
			case 4U:
				wMagLen = PackToTmcLineCTData(&TiocToTmcDataBuffer[ii]);
				break;
			default:
				cStepRetVal = CI_ERROR;
				break;
			}

			cStep++;

			if (CI_ERROR == cStepRetVal)
			{
				/* 组包完成 */
				cStepRetVal = CI_ERROR;
			}
			else if(0u != wMagLen)
			{
				/* 长度有效 */
				ii += wMagLen;
			}
			else
			{
				/* 长度无效 */
				cStepRetVal = CI_ERROR;
				retVal = CI_ERROR;
			}
		}

		/* 填充数据长度 */
		if (CI_SUCCESS == retVal)
		{
			wAppDataLen = ii - wAppDataLenIndex;
			wAppDataLen -= 2u;
			/* 组应用数据长度 */
			ShortToChar(wAppDataLen, &TiocToTmcDataBuffer[wAppDataLenIndex]);
		}

	}


	/* 写入发送队列 */
	if (CI_SUCCESS == retVal)
	{
		dstDevId = ((UINT16)(CI_SYSTEM_TYPE_TMC << 8u) | ((UINT16)deviceId));
		outnetSafeSendRtn = OutnetSafeSend(dstDevId, 0u, TiocToTmcDataBuffer, ii);
		if (1u == outnetSafeSendRtn)
		{ /*写队列成功*/
#ifdef LOGPRINT/*日志打印宏*/			
#ifdef PLATFORM_2OO2/*2oo2平台打印*/
			debug_infor_printf((const)"\nTMC_SEND:%d", ii);
			debug_out_array(0xAA, TiocToTmcDataBuffer, ii);
#endif/*平台打印结束*/

#endif
			retVal = CI_SUCCESS;
		}
		else
		{
			/*写队列失败*/
			retVal = CI_ERROR;
		}
	}

	return retVal;
}

/*
* 功能描述：清除TMC输入数据
*/
void ClearTmcToTiocData(void)
{
	UINT8 cFunRetVal = 0u; /* 返回结果 */
	cFunRetVal = CommonMemSet(&g_TmcToTiocDataStru, (UINT32)sizeof(g_TmcToTiocDataStru), 0u , (UINT32)sizeof(g_TmcToTiocDataStru));

	if (0u == cFunRetVal)
	{
		; /* 设置内存异常 */
	}
	else
	{
		; /* 设置成功，无处理 */
	}
}

/*
* 功能描述：获取TMC输入数据
* 返回值：接收TMC数据
*/
TmcToTiocDataStruct* GetTmcToTiocData(void)
{
	return &g_TmcToTiocDataStru;
}


/*
* 功能描述： 组TMC临时限速数据
* 参数说明：UINT8* TiocToTmcDataBuffer 数据地址
* 返回值  ： 0:组数据失败
*			 其他:整包数据长度
*/
static UINT16 PackToTmcTsrData(UINT8* TiocToTmcDataBuffer)
{
	UINT16 ii = 0u;
	UINT8 jj = 0u;
	UINT8 kk = 0u;
	UINT16 wMagLen = 0u;
	UINT16 wMagLenIndex = 0u;
	UINT16 wRetVal = 0u;
	UINT8 startLockFlag = 0u;
	UINT8 cTsrSum = 0u;			/* 临时限速数量 */
	UINT8 cTsrSecSum = 0u;		/* 限速区段 */
	UINT8 cFunRetVal = CI_ERROR;
	UINT8 cAllLineTsrState = CI_ALL_LINE_TSR_UNVALID;
	UINT8 cAllLineTsrSpeed = 0u;
	TsrDataStruct* pTsrData = NULL;

	cTsrSum = GetTsrSum();
	pTsrData = GetTsrData();
	startLockFlag = GetStartLockFlag();
	cAllLineTsrState = GetAllLineTsrState();
	cAllLineTsrSpeed = GetAllLineTsrSpeed();

	if ((NULL != TiocToTmcDataBuffer) && (NULL != pTsrData))
	{
		cFunRetVal = CI_SUCCESS;

		wMagLenIndex = ii;
		ii += 2u;

		ShortToChar(TIOC_TO_TMC_TSR_MSG, &TiocToTmcDataBuffer[ii]);/* 报文类型 */
		ii += 2u;

		/* 预留2字节 */
		ii += 2u;

		/* 临时限速有效标志位 */
		if (CI_START_LOCK_YES != startLockFlag)
		{
			/* 上电解锁成功 */
			TiocToTmcDataBuffer[ii++] = 0x55u;/* 临时限速有效 */

			/* 全线临时限速信息 */
			if (CI_ALL_LINE_TSR_VALID == cAllLineTsrState)
			{
				TiocToTmcDataBuffer[ii++] = 0xAAu;
			}
			else if (CI_ALL_LINE_TSR_UNVALID == cAllLineTsrState)
			{
				TiocToTmcDataBuffer[ii++] = 0x55u;
			}
			else
			{
				cFunRetVal = CI_ERROR;
			}
			TiocToTmcDataBuffer[ii++] = cAllLineTsrSpeed;

			/* 普通临时限速信息 */
			if (TSR_MAX_SUM < cTsrSum)
			{
				cFunRetVal = CI_ERROR;
			}

			if (CI_SUCCESS == cFunRetVal)
			{
				TiocToTmcDataBuffer[ii++] = cTsrSum;/* 限速数量 */

				for (jj = 0u; jj < cTsrSum; jj++)
				{
					TiocToTmcDataBuffer[ii++] = pTsrData[jj].cSpeed;/* 限速速度 */

					cTsrSecSum = pTsrData[jj].cLogSecSum;

					if ((0u == cTsrSecSum) || (TSR_SEC_MAX_SUM < cTsrSecSum))
					{
						cFunRetVal = CI_ERROR;
					}
					else
					{
						TiocToTmcDataBuffer[ii++] = cTsrSecSum;/* 限速区段数量 */

						for (kk = 0u; kk < cTsrSecSum; kk++)
						{
							/* 组逻辑区段ID */
							if ((0u == pTsrData[jj].szLogSecId[kk]) || (UINT16_MAX == pTsrData[jj].szLogSecId[kk]))
							{
								cFunRetVal = CI_ERROR;
							}
							else
							{
								ShortToChar(pTsrData[jj].szLogSecId[kk], &TiocToTmcDataBuffer[ii]);
								ii += 2u;
							}

							if (CI_ERROR == cFunRetVal)
							{
								break;
							}
							else
							{
							}
						}
					}

					if (CI_ERROR == cFunRetVal)
					{
						break;
					}
					else
					{
					}
				}
			}
		}
		else
		{
			TiocToTmcDataBuffer[ii++] = 0xAAu;/* 临时限速无效 */

			TiocToTmcDataBuffer[ii++] = 0x55u;/* 未设置全线临时限速 */

			TiocToTmcDataBuffer[ii++] = 0u;/* 未设置全线临时限速 */

			TiocToTmcDataBuffer[ii++] = 0u;/* 限速数量发0 */
		}
	}
	else
	{
		; /* 返回失败 */
	}

	if (CI_SUCCESS == cFunRetVal)
	{
		/* 填写数据长度 */
		wMagLen = ii - wMagLenIndex;
		wRetVal = wMagLen;
		wMagLen -= 2u;

		ShortToChar(wMagLen, &TiocToTmcDataBuffer[wMagLenIndex]);
	}

	return wRetVal;
}


/*
* 功能描述： 组TMC临时雨雪模式数据
* 参数说明：UINT8* TiocToTmcDataBuffer 数据地址
* 返回值  ： 0:组数据失败
*			 其他:整包数据长度
*/
static UINT16 PackToTmcSnowData(UINT8* TiocToTmcDataBuffer)
{
	UINT16 ii = 0u;
	UINT8 jj = 0U;
	UINT16 wMagLen = 0u;
	UINT16 wMagLenIndex = 0u;
	UINT16 wRetVal = 0u;
	UINT8 snowModelFlag = 0u;    /*全线雨雪模式标志*/
	UINT8 cFunRetVal = CI_ERROR;
	UINT8 cAreaSnowNum = 0U;  /*本地区间雨雪站台数量*/
	AreaSnowInfoStruct* pAreaSnowData = NULL;  /*本地区间雨雪信息数组*/
	UINT8 cSnowLevel = 0U;  /*湿轨级别*/

	snowModelFlag = GetAllSnowModel();

	if (NULL != TiocToTmcDataBuffer)
	{
		cFunRetVal = CI_SUCCESS;

		wMagLenIndex = ii;
		ii += 2u;

		ShortToChar(TIOC_TO_TMC_SNOW_MSG, &TiocToTmcDataBuffer[ii]); /* 报文类型 */
		ii += 2u;

		/* 预留2字节 */
		ii += 2u;

		/*全线雨雪模式命令有效标志*/
		if (CI_ALL_SNOW_VALID == snowModelFlag)
		{
			TiocToTmcDataBuffer[ii++] = 0x55u; /* 全线雨雪模式命令有效 */
		}
		else if (CI_ALL_SNOW_UNVALID == snowModelFlag)
		{
			TiocToTmcDataBuffer[ii++] = 0xAAu; /* 全线雨雪模式命令无效 */
		}
		else
		{
			cFunRetVal = CI_ERROR;  /*全线湿轨状态错误，返回失败*/
		}

		cSnowLevel = GetAllSnowLevel();
		if ((CI_SNOW_LEVEL_DEFAULT == cSnowLevel) || (CI_SNOW_LEVEL_ONE == cSnowLevel)|| (CI_SNOW_LEVEL_TWO == cSnowLevel))
		{
			TiocToTmcDataBuffer[ii] = cSnowLevel;  /*组全线湿轨级别*/
			ii++;
		}
		else
		{
			cFunRetVal = CI_ERROR;  /*全线湿轨级别错误，返回失败*/
		}


		/*组区间雨雪状态信息*/
		cAreaSnowNum = GetLocalAreaSnowNum();
		pAreaSnowData = GetLocalAreaSnow();

		if (LOCAL_AREA_SNOW_SUM_MAX >= cAreaSnowNum)
		{
			TiocToTmcDataBuffer[ii] = cAreaSnowNum;  /*组区间雨雪站台数量*/
			ii++;

			for (jj = 0U; jj < cAreaSnowNum; jj++)
			{
				if ((0U < pAreaSnowData[jj].wAreaId) && (UINT16_MAX > pAreaSnowData[jj].wAreaId)
					&& ((CI_SNOW_LEVEL_DEFAULT == pAreaSnowData[jj].cAreaSnowLevel) || (CI_SNOW_LEVEL_ONE == pAreaSnowData[jj].cAreaSnowLevel) || (CI_SNOW_LEVEL_TWO == pAreaSnowData[jj].cAreaSnowLevel)))
				{
					ShortToChar(pAreaSnowData[jj].wAreaId, &TiocToTmcDataBuffer[ii]);  /*组区间ID*/
					ii += 2U;
					TiocToTmcDataBuffer[ii] = pAreaSnowData[jj].cAreaSnowLevel;  /*组区间湿轨级别*/
					ii++;
				}
				else
				{
					cFunRetVal = CI_ERROR;  /*区间信息非法，返回失败*/
					break;
				}
			}
		}
		else
		{
			cFunRetVal = CI_ERROR;  /*区间雨雪数量超限，返回失败*/
		}
	}
	else
	{
		;  /*返回失败*/
	}
	if (CI_SUCCESS == cFunRetVal)
	{
		/* 填写数据长度 */
		wMagLen = ii - wMagLenIndex;
		wRetVal = wMagLen;
		wMagLen -= 2u;

		ShortToChar(wMagLen, &TiocToTmcDataBuffer[wMagLenIndex]);
	}
	return wRetVal;
}

/*
* 功能描述： 组TMC全线免筛数据
* 参数说明：UINT8* TiocToTmcDataBuffer 数据地址
* 返回值  ： 0:组数据失败
*			 其他:整包数据长度
*/
static UINT16 PackToTmcWLScreenData(UINT8* TiocToTmcDataBuffer)
{
	UINT16 ii = 0u;
	UINT8 jj = 0u;
	UINT16 wMagLen = 0u;
	UINT16 wMagLenIndex = 0u;
	UINT16 wRetVal = 0u;
	UINT8 cFunRetVal = CI_ERROR;
	WLScreenReportStruct tmpWLScreenReportStru = { 0u };

	if (NULL != TiocToTmcDataBuffer)
	{

		cFunRetVal = wls_PrepareWLSInfoToTMC(&tmpWLScreenReportStru);

		if (CI_SUCCESS == cFunRetVal)
		{
			wMagLenIndex = ii;
			ii += 2u;

			ShortToChar(TIOC_TO_TMC_MIANSHAI_MSG, &TiocToTmcDataBuffer[ii]);/* 报文类型 */
			ii += 2u;

			/* 预留2字节 */
			ii += 2u;

			/* 上电解锁成功 */
			LongToChar(tmpWLScreenReportStru.sendSeq, &TiocToTmcDataBuffer[ii]);  /*免筛序列号*/
			ii += 4u;

			TiocToTmcDataBuffer[ii++] = tmpWLScreenReportStru.UTFlag;  /*是否存在UT或者前后端可疑标志*/

			TiocToTmcDataBuffer[ii++] = tmpWLScreenReportStru.enterCheckFlag;  /*入口异常检测标志*/

			TiocToTmcDataBuffer[ii++] = tmpWLScreenReportStru.controlTrainCnt;  /*本TIOC范围内受控列车数量*/
																				/*受控车ID*/
			for (jj = 0u; jj < tmpWLScreenReportStru.controlTrainCnt; jj++)
			{
				if ((0u == tmpWLScreenReportStru.controlTrainID[jj]) || (UINT8_MAX <= tmpWLScreenReportStru.controlTrainID[jj]))
				{
					cFunRetVal = CI_ERROR;
					break;
				}
				else
				{
					ShortToChar(tmpWLScreenReportStru.controlTrainID[jj], &TiocToTmcDataBuffer[ii]);
					ii += 2u;
				}
			}

			if (CI_SUCCESS == cFunRetVal)
			{
				TiocToTmcDataBuffer[ii++] = tmpWLScreenReportStru.offlineTrainCnt;  /*从本TIOC回段或者驶出联络线的受控列车数量*/
																					/*受控车ID*/
				for (jj = 0u; jj < tmpWLScreenReportStru.offlineTrainCnt; jj++)
				{
					if ((0u == tmpWLScreenReportStru.offlineTrainID[jj]) || (UINT8_MAX <= tmpWLScreenReportStru.offlineTrainID[jj]))
					{
						cFunRetVal = CI_ERROR;
						break;
					}
					else
					{
						ShortToChar(tmpWLScreenReportStru.offlineTrainID[jj], &TiocToTmcDataBuffer[ii]);
						ii += 2u;
					}
				}
			}
		}
	}
	else
	{
		; /* 返回失败 */
	}

	if (CI_SUCCESS == cFunRetVal)
	{
		/* 填写数据长度 */
		wMagLen = ii - wMagLenIndex;
		wRetVal = wMagLen;
		wMagLen -= 2u;

		ShortToChar(wMagLen, &TiocToTmcDataBuffer[wMagLenIndex]);

	}

	return wRetVal;
}

/*
* 功能描述：解析ITE切除信息
* 参数说明：const UINT8* dataBuf, 数据缓冲区
*           const UINT16 dataLength, 数据长度
* 返 回 值：CI_ERROR 0 数据解析失败
*			CI_SUCCESS 1 数据解析成功
* Created By LQ 2024.07.12
*/
static UINT8 ParseIteCutData(UINT8* dataBuf, UINT16 dataLen)
{
	UINT8 cRetVal = CI_ERROR;
	UINT8 cIteLineCutState = 0U;  /*ITE全线切除状态*/
	UINT16 ii = 0U;
	UINT8 jj = 0U;
	UINT16 wPlatFormId = 0U;  /*站台ID*/
	UINT8 cPlatFormNum = 0U;  /*站台数量*/
	UINT8 cTmepNum = 0U;
	UINT8 cPlatFormBelongCiId = 0U;  /*站台关联Link所属CI*/
	UINT8 cLocalCiId = 0U;

	if (NULL != dataBuf)
	{
		cRetVal = CI_SUCCESS;
		cIteLineCutState = dataBuf[ii];
		ii++;

		if ((CI_ITE_LINE_CUT_VALID == cIteLineCutState) || (CI_ITE_LINE_CUT_INVALID == cIteLineCutState))
		{
			g_TmcToTiocDataStru.cIteLineCutState = cIteLineCutState;  /*存储解析的ITE全线切除状态*/

			/*解析区间ITE切除信息*/
			cPlatFormNum = dataBuf[ii];  /*解析区间ITE切除数量*/
			ii++;

			if (ALL_AREA_SNOW_SUM_MAX >= cPlatFormNum)
			{				
				cLocalCiId = GetSystemParaLocalCiId();
				for (jj = 0U; jj < cPlatFormNum; jj++)
				{
					wPlatFormId = ShortFromChar(&dataBuf[ii]);  /*解析区间ID*/
					ii += 2U;
					if ((0U < wPlatFormId) && (UINT16_MAX > wPlatFormId))
					{
						cPlatFormBelongCiId = GetAreaSnowPlatFormBelongCiId(wPlatFormId);  /*获取区间所属控区*/
						if ((cLocalCiId == cPlatFormBelongCiId) && (0U != cLocalCiId))
						{
							if (LOCAL_AREA_SNOW_SUM_MAX > cTmepNum)
							{
								g_TmcToTiocDataStru.szAreaIteCutId[cTmepNum] = wPlatFormId;
								cTmepNum++;
							}
							else
							{
								debug_infor_printf((const)"ParseIteCutData: Local AreaIteCutNum Exceed Max\n");
								cRetVal = CI_ERROR;  /*本控区区间ITE切除数量超限，停止遍历，返回失败*/
							}
						}
						else
						{
							/*非本控区，不保存*/
						}
					}
					else
					{
						debug_infor_printf((const)"ParseIteCutData: Area Id Error\n");
						cRetVal = CI_ERROR;  /*区间编号ID非法*/
					}

					if (CI_SUCCESS != cRetVal)
					{
						break;  /*解析失败，停止解析*/
					}
					else
					{
						/*继续解析*/
					}
				}

				g_TmcToTiocDataStru.cAreaIteCutNum = cTmepNum;

				if (CI_SUCCESS == cRetVal)
				{
					if (dataLen == ii)
					{
						/*解析成功*/
					}
					else
					{
						debug_infor_printf((const)"ParseIteCutData: MsgLen Is Error\n");
						cRetVal = CI_ERROR;  /*长度不一致，返回失败*/
					}
				}
				else
				{
					/*不处理*/
				}
			}
			else
			{
				debug_infor_printf((const)"ParseIteCutData: TMC AreaIteCutNum Exceed Max\n");
				cRetVal = CI_ERROR;  /*区间ITE切除数量超限，返回失败*/
			}
		}
		else
		{
			cRetVal = CI_ERROR;  /*状态非法，返回失败*/
			debug_infor_printf((const)"ParseIteCutData: IteLineCutState[0x%2x] Is Invalid\n", cIteLineCutState);
		}		
	}
	else
	{
		/*入参非法，返回失败*/
	}

	return cRetVal;
}

/*
* 功能描述：组ITE切除信息
* 参数说明：UINT8* TiocToTmcDataBuffer 数据地址
* 返 回 值：0 组数据失败
*			其他 整包数据长度
* Created By LQ 2024.07.12
*/
static UINT16 PackToTmcIteCutData(UINT8* TiocToTmcDataBuffer)
{
	UINT16 ii = 0U;
	UINT16 wMagLen = 0U;
	UINT16 wMagLenIndex = 0U;
	UINT16 wRetVal = 0U;
	UINT8 cIteLineCutState = 0U;  /*ITE全线切除状态*/
    UINT8 cAreaIteCutNum = 0U;  /*本地区间ITE切除数量*/
	UINT16* pAreaIteCutId = NULL;  /*本地区间ITE切除ID数组*/
	UINT8 jj = 0U;
	UINT8 cFunRetVal = CI_ERROR;

	if (NULL != TiocToTmcDataBuffer)
	{
		cFunRetVal = CI_SUCCESS;
		wMagLenIndex = ii;
		ii += 2U;

		ShortToChar(TIOC_TO_TMC_ITELINECUT_MSG, &TiocToTmcDataBuffer[ii]);  /* 报文类型 */
		ii += 2U;

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

		/*组ITE全线切除状态*/
		cIteLineCutState = GetIteLineCutState();
		if ((CI_ITE_LINE_CUT_VALID == cIteLineCutState) || (CI_ITE_LINE_CUT_INVALID == cIteLineCutState))
		{
			TiocToTmcDataBuffer[ii] = cIteLineCutState;
		}
		else
		{
			TiocToTmcDataBuffer[ii] = CI_ITE_LINE_CUT_DEFAULT;  /* 组默认值 */
		}
		ii++;

		/*组区间ITE切除信息*/
		cAreaIteCutNum = GetLocalAreaIteCutNum();
		pAreaIteCutId = GetLocalAreaIteCutId();

		if ((LOCAL_AREA_SNOW_SUM_MAX >= cAreaIteCutNum) && (NULL != pAreaIteCutId))
		{
			TiocToTmcDataBuffer[ii] = cAreaIteCutNum;  /*组区间ITE切除数量*/
			ii++;

			for (jj = 0U; jj < cAreaIteCutNum; jj++)
			{
				ShortToChar(pAreaIteCutId[jj], &TiocToTmcDataBuffer[ii]);  /*组区间ID*/
				ii += 2U;
			}
		}
		else
		{
			debug_infor_printf((const)"PackToTmcIteCutData: Local AreaIteCutNum Exceed Max\n");
			cFunRetVal = CI_ERROR;  /*区间ITE切除数量超限，返回失败*/
		}

		if (CI_SUCCESS == cFunRetVal)
		{
			/* 填写数据长度 */
			wMagLen = ii - wMagLenIndex;
			wRetVal = wMagLen;
			wMagLen -= 2U;

			ShortToChar(wMagLen, &TiocToTmcDataBuffer[wMagLenIndex]);
		}
		else
		{
			/*组包失败，返回0*/
		}
	}
	else
	{
		/*入参非法，返回0*/
	}
	
	return wRetVal;
}

/*
* 功能描述：解析全线通信车信息
* 参数说明：const UINT8* dataBuf, 数据缓冲区
*           const UINT16 dataLength, 数据长度
* 返 回 值：CI_ERROR 0 数据解析失败
*			CI_SUCCESS 1 数据解析成功
* Created By LQ 2024.07.12
*/
static UINT8 ParseLineCTData(UINT8* dataBuf, UINT16 dataLen)
{
	UINT8 cRetVal = CI_ERROR;
	UINT16 ii = 0U;
	UINT8 jj = 0U;
	UINT8 cLineCtNum = 0U;
	UINT16 wTrainId = 0U;

	if (NULL != dataBuf)
	{
		cRetVal = CI_SUCCESS;

		cLineCtNum = dataBuf[ii];
		ii++;

		if (TRAIN_SUM_MAX > cLineCtNum)
		{
			g_TmcToTiocDataStru.cLineCtNum = cLineCtNum;
			for (jj = 0u; jj < g_TmcToTiocDataStru.cLineCtNum; jj++)
			{
				wTrainId = ShortFromChar(&dataBuf[ii]);
				ii += 2U;

				if ((0u < wTrainId) && (TRAIN_SUM_MAX > wTrainId))
				{
					g_TmcToTiocDataStru.szLineCtId[jj] = wTrainId;  /*继续解析*/
				}
				else
				{
					debug_infor_printf((const)"ParseLineCTData Error: Train ID[%d] Is Invalid\n", wTrainId);
					cRetVal = CI_ERROR;  /*通信车ID非法，停止解析，返回失败*/
					break;
				}
			}
			if (CI_SUCCESS == cRetVal)
			{
				if (dataLen == ii)
				{
					/*不处理*/
				}
				else
				{
					debug_infor_printf((const)"ParseLineCTData Error: MsgLen Is Error\n");
					cRetVal = CI_ERROR;  /*长度不一致，返回失败*/
				}
			}
			else
			{
				/*不处理*/
			}
		}
		else
		{
			debug_infor_printf((const)"ParseLineCTData Error: Train Num[%d] Exceed Max[%d]\n", cLineCtNum, TRAIN_SUM_MAX);
			cRetVal = CI_ERROR;  /*通信车数量超限，返回失败*/
		}
	}
	else
	{
		cRetVal = CI_ERROR;  /*入参非法，返回失败*/
	}

	return cRetVal;
}

/*
* 功能描述：组TMC全线通信车数据
* 参数说明：UINT8* TiocToTmcDataBuffer 数据地址
* 返 回 值：0 组数据失败
*			其他 整包数据长度
* Created By LQ 2024.07.14
*/
static UINT16 PackToTmcLineCTData(UINT8* TiocToTmcDataBuffer)
{
	UINT16 ii = 0U;
	UINT8 jj = 0U;
	UINT16 wMagLen = 0U;
	UINT16 wMagLenIndex = 0U;
	UINT16 wTrainNumIndex = 0U;
	UINT16 wRetVal = 0U;
	UINT8 cFunRetVal = CI_ERROR;
	UINT8 cCommTrainNum = 0U;  /*与本RC通信的通信车数量*/
	TrainInfoStru* pstrTrainInfo = NULL;  /*列车信息结构体*/
	UINT16 wTrainId = 0U;
	UINT8 cCtEnvelopeFlag = CI_ERROR;  /*列车是否存在CT包络标志*/

	if (NULL != TiocToTmcDataBuffer)
	{
		cFunRetVal = CI_SUCCESS;
		wMagLenIndex = ii;
		ii += 2U;

		ShortToChar(TIOC_TO_TMC_LINECT_MSG, &TiocToTmcDataBuffer[ii]);  /* 报文类型 */
		ii += 2U;
		
		ii += 2U;  /*预留2字节*/

		wTrainNumIndex = ii;  /*通信列车数量位置索引*/
		ii++;

		pstrTrainInfo = GetTrainInfoData();
		if (NULL == pstrTrainInfo)
		{
			cCommTrainNum = 0U;  /*通信车结构体为NULL，通信车数量组0*/
		}
		else
		{
			for (jj = 0U; jj < TRAIN_SUM_MAX; jj++)
			{
				if (TRAIN_COMM_STATE_GOOD == pstrTrainInfo[jj].chTransmitStat)
				{
					wTrainId = pstrTrainInfo[jj].wTrainId & 0x00FFU;
					cCtEnvelopeFlag = CheckTrainRelCtEnvelope(wTrainId);  /*检查通信车是否存在CT包络*/
					if (CI_SUCCESS == cCtEnvelopeFlag)
					{
						if ((0U < wTrainId) && (TRAIN_SUM_MAX > wTrainId))
						{
							if (VOBC_TO_CI_SUM_MAX > cCommTrainNum)
							{
								ShortToChar(wTrainId, &TiocToTmcDataBuffer[ii]);
								ii += 2U;
								cCommTrainNum++;
							}
							else
							{
								debug_infor_printf((const)"PackToTmcLineCTData Error: CommTrainNum[%d] Exceed Max[%d]\n", cCommTrainNum, VOBC_TO_CI_SUM_MAX);
								cFunRetVal = CI_ERROR;  /*通信车数量超限，不组包*/
							}
						}
						else
						{
							debug_infor_printf((const)"PackToTmcLineCTData Error: CommTrainID[%d] Is Invalid\n", wTrainId);
							cFunRetVal = CI_ERROR;  /*通信车ID非法，不组包*/
						}

						if (CI_ERROR == cFunRetVal)
						{
							break;
						}
						else
						{
							/*继续组包*/
						}
					}
					else
					{
						/*无CT包络，不组包*/
					}
				}
				else
				{
					/*不组非通信车*/
				}
			}
		}

		if (CI_SUCCESS == cFunRetVal)
		{
			/*填写数据长度*/
			TiocToTmcDataBuffer[wTrainNumIndex] = cCommTrainNum;  /*本TIOC范围内通信列车数量*/
			wMagLen = ii - wMagLenIndex;
			wRetVal = wMagLen;
			wMagLen -= 2U;

			ShortToChar(wMagLen, &TiocToTmcDataBuffer[wMagLenIndex]);
		}
		else
		{
			/*组包错误，不处理*/
		}
	}
	else
	{
		/*入参非法，不处理*/
	}

	return wRetVal;
}