/********************************************************
*                                                                                                            
* 文件名  ： RsspOutputWl.C   
* 版权说明： 北京瑞安时代科技有限责任公司 
* 版本号  ： 1.0
* 创建时间： 2009.11.25
* 作者    ： 车载及协议部
* 功能描述： Rssp层对外输出模块。 
* 使用注意： 
*		必须在RsspInit函数调用才能，调用本文件内的函数。
* 修改记录：   
*   更新时间	更新者	更新理由
* ------------  ------  ---------------
*	2009.12.07	楼宇伟	初版作成
*	2009.12.16	楼宇伟	记录追加
*	2010.02.01	楼宇伟	TimeCounter 按周期累加，卡斯柯文档变更
*   2011.11.17  楼宇伟  在应用没有数据发送的时候不在对外发送任何数据。
*   2013.03.01  王佩佩  将CreateBsdMsg函数变为CreateRsdMsg
********************************************************/ 

#include "RsspIFWl.h" 
#include "RsspStructWl.h"
#include "RsspCommonWl.h"
#include "CommonQueue.h"
#include "Convert.h"
#include "dsuRsspFunc.h"
#include "RsspLnkNodeMgrWl.h"
#include "RsspRecordDelareWl.h"
#include "CommonRecord.h"

#ifdef __cplusplus
extern "C" {
#endif

/*--------------------------------------------------------------------
 * RSSP层输出模块内部使用函数申明 Start
 *--------------------------------------------------------------------*/
static UINT8 CreateRsdMsg_WL(const UINT8 *pAppData,UINT16 DataLen,UINT8 *OutBsdMsg, Lnk_Info_Node_Stru_WL** pPNode,RSSP_INFO_STRU *pRsspStru);
static UINT8 CreateSseMsg_WL(Lnk_Info_Node_Stru_WL *pLnkNodeInfo,UINT8 *OutSseMsg,RSSP_INFO_STRU *pRsspStru);
static UINT8 CreateSsrMsg_WL(Lnk_Info_Node_Stru_WL *pLnkNodeInfo,UINT8 *OutSsrMsg,RSSP_INFO_STRU *pRsspStru);

static UINT8 WriteToAppArray(const UINT8* appData, const UINT16 appDataLen, Lnk_Info_Node_Stru_WL* lnkNode, UINT32* curAppArrayIdx, RSSP_INFO_STRU* rssp);

static void SetRsspMsgHead_WL(UINT8 MsgType, UINT16 SrcAddr, UINT16 DestAddr, UINT8 *OutRsspMsg);

static void RecvLnkStatusMng_WL(RSSP_INFO_STRU* pRsspStru);

/*--------------------------------------------------------------------
 *  RSSP层输出模块内部使用函数申明 End
 *--------------------------------------------------------------------*/
 
/*--------------------------------------------------------------------
 * RSSP层对外接口函数定义 Start
 *--------------------------------------------------------------------*/

 /**
  * @brief RsspOutput_WL RSSPI输出处理
  * @param AppToRs 应用给协议数据队列 取值范围:参考结构体QueueStruct
  * @param VarArray 输出链路数据 取值范围:字节数组
  * @param pRsspStru RSSPI实例 取值范围:参考结构体RSSP_INFO_STRU
  * @return 0:失败 1:成功
  */
UINT8 RsspOutput_WL(QueueStruct* AppToRs, UINT8* VarArray, RSSP_INFO_STRU* pRsspStru)
{
	/** 定义局部变量*/
	UINT8 ret = 0, index = 0; /*-< 设置返回值为失败*/
	UINT8 QueErrFlag = 0; /*-< 设置队列错误标识为否*/
	UINT8 LnkNodeNum = 0;						/* 通信节点数 */
	UINT16 MaxMsgLen = 0;						/* 一个队列节点的最大数据长度 */
	UINT16 MsgLen = 0;							/* 消息长度 */
	UINT8* TmpOutMsg = NULL;		/* 作成报文数据缓存区 */
	Lnk_Info_Node_Stru_WL* LnkNodeArr = NULL;		/* 通信节点数组 */
	Lnk_Info_Node_Stru_WL* pNode = NULL;			/* 通信节点指针 */
		/* ywlou20101118 Add S */
	UINT8 appDataFlg = 0; /*-< 设置是否有应用给数据标识为否*/
	/* ywlou20101118 Add E */
	UINT32 destDevName = 0;		/* 对方设备标识 */
	UINT8 dstType = 0;	/*目的类型*/
	UINT8* RecordArray = NULL;
	UINT16 RecordSize = 0;
	const UINT8 twoLen = 2;	/*长度值2*/
	UINT32 curAppArrayIdx = 4; /*应用数组下标,前4字节是总长度*/

	if ((NULL != AppToRs) && (NULL != VarArray) && (NULL != pRsspStru) && (NULL != pRsspStru->RecordArray) && (NULL != pRsspStru->gpSendSingleOutMsg)) /*-< 入参是否非空*/
	{
		RecvLnkStatusMng_WL(pRsspStru); /*-< 调用更新收链路状态函数*/

		TmpOutMsg = pRsspStru->gpSendSingleOutMsg; /*-< 调用更新收链路状态函数*/

		RecordArray = pRsspStru->RecordArray; /*-< 得到记录数组*/
		RecordSize = pRsspStru->RecordArraySize; /*-< 得到记录数组长度*/
#ifdef RSSP_RECORD_ERR_ASCII	/* 字符串格式 */
		PrintFiles(RecordArray, RecordSize, "RSSP Output:\n");
#endif 
#ifdef RSSP_RECORD_SIMPLIFY_BIN	/*是否定义二进制宏开关*/
		/* RSR输出单元标识 */
		PrintRecArrayByte(RecordArray, RecordSize, RSSP_OUTPUT); /*-< 记录输出标识日志*/
		PrintRecArray2ByteB(RecordArray, RecordSize, (UINT16)QueueStatus(AppToRs));	/*-< 记录输入队列总长度日志*/
#endif
		RsspMemSet_WL(&pRsspStru->AppArray[0], pRsspStru->AppArraySize, 0); /*-< 调用清空给应用数据存放的数组函数*/
		/* 取得全局的通信节点数组 */
		GetLnkNodeArr_WL(&LnkNodeArr, &LnkNodeNum, pRsspStru); /*-< 调用取得通信节点数组函数*/

		/* 无发送数据周期数累加 */
		for (index = 0; index < LnkNodeNum; index++) /*-< 当前链路数下标是否小于链路总数*/
		{
			LnkNodeArr[index].CycleNum++; /*-< 协议周期累加1*/
			AdjustLnkCycle(pRsspStru->LocalType, LnkNodeArr[index].CycleNum, &LnkNodeArr[index]); /*-< 调用根据指定本方类型、周期号、当前链路，调整当前链路周期号并设置是否为执行周期函数*/
			if (1 == LnkNodeArr[index].ExeCycle) /*-< 此链路是否执行周期*/
			{
				LnkNodeArr[index].HasRsdBeforeSseOrSsr = 0;	/*-< 设置未生成过RSD标识为否*/
				/* 不可覆盖节点 */
				if ((DisbaledReplace_WL == LnkNodeArr[index].NodeStatus)
					&& (Halt_WL != LnkNodeArr[index].RsspLinInfo.SendLinkStatus)) /*-< 当前链路可用性为可用且发送状态非中断*/
				{
					/* 正常通信时，无发送数据周期数累加 */
					LnkNodeArr[index].RsspLinInfo.NoAppDataCycleNum++; /*-< 无发送应用周期数自增1*/
				}
				else
				{
					/*-< 什么不做*/
				}

				/* 计数器累加 */
				AddTimeStamp_WL(&LnkNodeArr[index].RsspLinInfo.TimeStmp); /*-< 当前链路周期号自增1*/
			}
			else
			{
				/*-< 什么不做*/
			}
		}

		/* 队列节点的最大数据长度 */
		MaxMsgLen = pRsspStru->OutputSize + 6; /*-< 设置队列节点的最大数据长度*/

		/* 读取应用数据 */
		while (QueueStatus(AppToRs) > 2) /*-< 应用给数据队列是否有数据*/
		{
			QueueScan(2, pRsspStru->FrameData, AppToRs); /*-< 得到数据长度两个字节*/
			MsgLen = ShortFromChar(pRsspStru->FrameData); /*-< 得到数据长度*/

			/* 队列节点数据长度 小于 最大入力数据 */
			if ((MsgLen <= MaxMsgLen) && (MsgLen > twoLen)) /*-< 数据长度是否合法*/
			{
				/* 读出一节点的应用数据 */
				ret = QueueRead((MsgLen + 2), pRsspStru->FrameData, AppToRs); /*-< 调用读队列函数读出一节点的应用数据*/
				if (1 == ret) /*-< 调用函数是否成功*/
				{
					/* RSD 报文作成 */
					ret = CreateRsdMsg_WL(pRsspStru->FrameData, (UINT16)(MsgLen + 2), TmpOutMsg, &pNode, pRsspStru); /*-< 调用生成RSD帧函数*/
					RsspMemSet_WL(pRsspStru->FrameData, (UINT16)(MsgLen + 2), 0); /*-< 清零应用给帧数据*/
					/* RSD报文作成成功	*/
					if (1 == ret) /*-< 调用函数是否成功*/
					{
						/* 写入队列 :安全数据长度+ 帧头长度 + 计数器值+ 长度字节 */
						MsgLen = ShortFromCharLE(&TmpOutMsg[RSSP_DATA_SIZE_POS_WL]) + RSSP_CRCM_1_POS_WL + CRC_16_LEN_WL; /*-< 得到输出帧长度*/
						ret = WriteToAppArray(TmpOutMsg, MsgLen, pNode, &curAppArrayIdx, pRsspStru); /*-< 调用RSD帧写入输出队列函数*/
						if (0 == ret) /*-< 调用函数是否失败*/
						{
							/*-< 什么不做*/
						}
						else
						{
							/* 什么不做 继续处理下一个节点数据 */
							/* ywlou20101118 Add S */
							/* 作成一帧BSD报文 */
							pNode->HasRsdBeforeSseOrSsr = 1; /*-< 设置未生成过RSD标识为是*/
							/* ywlou20101118 Add E */
						}
					}
					else  /* 报文作成失败 */
					{
						/*-< 什么不做*/
					}
				}
				else
				{
					/* 指定长度的队列读取失败，说明队列剩下元素不足，则直接跳出循环。记录 */
#ifdef RSSP_RECORD_ERR_ASCII	/* 字符串格式 */
					PrintFiles(RecordArray, RecordSize, "W:QueueRead Err\n");	/* 读队列失败 */
#endif 
#ifdef RSSP_RECORD_SIMPLIFY_BIN	/*是否定义二进制宏开关*/
					PrintRecArrayByte(RecordArray, RecordSize, OUTPUT_READ_QUE_ERR); /*-< 记录读队列失败日志*/
#endif
					break; /*-< 退出遍历*/
				}
			}
			else	/* MsgLen >= MaxMsgLen */
			{
				/* 记录，丢弃数据,继续处理下一数据  */
				QueueElementDiscard(MsgLen + 2, AppToRs); /*-< 调用删除队列元素函数*/
				/* 指定长度的队列读取失败，说明队列剩下元素不足，则直接跳出循环。记录 */
#ifdef RSSP_RECORD_ERR_ASCII	/* 字符串格式 */
				PrintFiles(RecordArray, RecordSize, "W:QueueRead Err\n");	/* 读队列失败 */
#endif 
#ifdef RSSP_RECORD_SIMPLIFY_BIN	/*是否定义二进制宏开关*/
				PrintRecArrayByte(RecordArray, RecordSize, OUTPUT_LEN_ERR);	/*-< 记录长度不正确日志*/
#endif
			}
		}
		QueErrFlag = 0; /*-< 设置队列不足标识为否*/
		/* 通信节点数组链路状态变化 */
		for (index = 0; index < LnkNodeNum; index++) /*-< 当前链路数下标是否小于链路总数*/
		{
			if (1 == LnkNodeArr[index].ExeCycle) /*-< 此链路是否执行周期*/
			{
				if (pRsspStru->NoSendAppData < LnkNodeArr[index].RsspLinInfo.NoAppDataCycleNum) /*-< 此链路无发应用周期数是否大于配置值*/
				{
					/*发送状态置中断*/
					LnkNodeArr[index].RsspLinInfo.SendLinkStatus = Halt_WL; /*-< 设置此链路发状态为中断*/
					/*无发送应用数据周期数 清零*/
					LnkNodeArr[index].RsspLinInfo.NoAppDataCycleNum = 0; /*-< 清零此链路无发应用周期数*/
					/*接收状态为中断*/
					if (Halt_WL == LnkNodeArr[index].RsspLinInfo.RecvLinkStatus) /*-< 此链路收状态是否中断*/
					{
						/*对方设备标识*/
						destDevName = LnkNodeArr[index].DestDevName; /*-< 得到此链路对方唯一ID*/
						/*删除安全层链路*/
						ret = RsspLnkDelete_WL(destDevName, pRsspStru); /*-< 调用删了链路函数*/
					}
				}
				else
				{
					/*-< 什么不做*/
				}

				if ((RSSP_TYPE_VOBC_WL == pRsspStru->LocalType) || (RSSP_TYPE_VOBC_BACK_WL == pRsspStru->LocalType) || (RSSP_TYPE_AOM_WL == pRsspStru->LocalType)) /*-< 本方类型是否车或车后备或AOM*/
				{
					if (DisbaledReplace_WL == LnkNodeArr[index].NodeStatus) /*-< 当前链路可用性是否可用*/
					{
#ifdef RSSP_NO_HLHT	/*是否定义无互联互通ID宏开关*/
						dstType = (LnkNodeArr[index].DestDevName >> 8) & 0xff; /*-< 设置目的类型ID*/

#else
						dstType = DquToDevType(LnkNodeArr[index].DestDevName, pRsspStru->pDsuRsspInfoStruWL); /*-< 调用根据HLHTID转成设备类型函数设置目的类型ID*/
#endif
					}
					if ((RSSP_TYPE_VOBC_WL == dstType) || (RSSP_TYPE_VOBC_BACK_WL == dstType) || (RSSP_TYPE_TTIL_WL == dstType)) /*-< 对方类型是否车或车后备或列尾通信*/
					{
						appDataFlg = 1; /*-< 设置是否有应用给数据标识为是*/
					}
					else /*车地通信*/
					{
						if (1 == LnkNodeArr[index].HasRsdBeforeSseOrSsr) /*-< 在生成SSE或者SSR之前是否有生成RSD标识是否为是*/
						{
							appDataFlg = 1; /*-< 设置是否有应用给数据标识为是*/
						}
						else  /*否则不发SSE或SSR*/
						{
							appDataFlg = 0; /*-< 设置是否有应用给数据标识为否*/
						}
					}
				}
				else
				{
					appDataFlg = 1; /*-< 设置是否有应用给数据标识为是*/
				}
				LnkNodeArr[index].HasRsdBeforeSseOrSsr = 0; /*-< 设置在生成SSE或者SSR之前是否有生成RSD标识为否*/

				/* 接受状态为 发送SSE */
				/* ywlou20101118 MOd S */
				/* 修改为没有BSD报文数据不再 发送SSE 以及SSR 报文 */
				if ((0 == QueErrFlag) && (DisbaledReplace_WL == LnkNodeArr[index].NodeStatus) && (SendSSE_WL == LnkNodeArr[index].RsspLinInfo.RecvLinkStatus) && (1 == appDataFlg)) /*-< 队列错误标识是否否 且此链路可用性是否可用 且收状态是否发SSE 且否有应用给数据标识是否是*/
				{
					/* ywlou20101118 MOd S */
					ret = CreateSseMsg_WL(&LnkNodeArr[index], TmpOutMsg, pRsspStru); /*-< 调用生成SSE帧函数*/
					if (ret == 1) /*-< 调用函数是否成功*/
					{
						ret = WriteToAppArray(TmpOutMsg, RSSP_SSE_LEN_WL, &LnkNodeArr[index], &curAppArrayIdx, pRsspStru); /*-< 调用SSE帧写入输出队列函数*/
						if (0 == ret) /*-< 调用函数是否失败*/
						{
							/* 因为写入失败，说明空闲队列空间不够写入SSE报文
							 * 因而已经不能再写入报文。
							 * 把队列不足的标志设置为 1
							 */
							QueErrFlag = 1; /*-< 设置队列错误标识为是*/
						}
						else
						{
							/*-< 什么不做*/
						}
					}
					else			/* 报文作成失败 */
					{
						/*-< 什么不做*/
					}
				}

				/* 节点状态为不可覆盖 而且 发送状态为SendSSR 那么作成SSR报文 */
				/* ywlou20101118 MOd S */
				/* 修改为没有BSD报文数据不再 发送SSE 以及SSR 报文 */
				if ((0 == QueErrFlag) && (DisbaledReplace_WL == LnkNodeArr[index].NodeStatus)
					&& (SendSSR_WL == LnkNodeArr[index].RsspLinInfo.SendLinkStatus)
					&& (1 == appDataFlg)) /*-< 队列错误标识是否否 且此链路可用性是否可用 且收状态是否发SSR 且否有应用给数据标识是否是*/
				{
					/* ywlou20101118 MOd E */
					ret = CreateSsrMsg_WL(&LnkNodeArr[index], TmpOutMsg, pRsspStru); /*-< 调用生成SSR帧函数*/
					if (ret == 1) /*-< 调用函数是否成功*/
					{
						ret = WriteToAppArray(TmpOutMsg, RSSP_SSR_LEN_WL, &LnkNodeArr[index], &curAppArrayIdx, pRsspStru); /*-< 调用SSR帧写入输出队列函数*/
						if (0 == ret) /*-< 调用函数是否失败*/
						{
							/*-< 什么不做*/
						}
						else
						{
							/*-< 什么不做*/
						}
					}
					else
					{
						/*-< 什么不做*/
					}

				}
				else
				{
					/* 什么不做 */
				}
			}
			else
			{
				/* 什么不做 */
			}
		}
		/* 中间变量输出 */
		ret = WriteToVarArray_WL(VarArray, pRsspStru); /*-< 调用写入链路数据函数*/

		PrintRecArrayByte(RecordArray, RecordSize, LINK_INFO); /*-< 记录RSSPI输出链路数据标识*/
		PrintRecArray2ByteB(RecordArray, RecordSize, ShortFromChar(VarArray)); /*-< 记录链路数据长度 */

		/* 通信节点数组信息输出 */
		for (index = 0; index < LnkNodeNum; index++) /*-< 当前链路数下标是否小于链路总数*/
		{
			if (DisbaledReplace_WL == LnkNodeArr[index].NodeStatus) /*-< 当前链路节点可用性是否可用*/
			{
#ifdef RSSP_RECORD_ERR_ASCII	/* 字符串格式 */
				PrintFiles(RecordArray, RecordSize, "Node Info:");
				PrintFiles(RecordArray, RecordSize, "\nDestType:");
				PrintFileU16Hex(RecordArray, RecordSize, LnkNodeArr[index].DestDevName);	/* 对方标识（DestType） */

				PrintFiles(RecordArray, RecordSize, "\tSrcAddr:");
				PrintFileU16Hex(RecordArray, RecordSize, LnkNodeArr[index].RsspSrcAddr);	/* 本方RSSP源地址(SrcAddr) */
				PrintFiles(RecordArray, RecordSize, "\tBsdAddr:");
				PrintFileU16Hex(RecordArray, RecordSize, LnkNodeArr[index].DestBsdAdd);	/* 本方RSSPBSD地址(BsdAddr) */
				PrintFiles(RecordArray, RecordSize, "\tDestAddr:");
				PrintFileU16Hex(RecordArray, RecordSize, LnkNodeArr[index].RsspDestAddr);	/* 本方RSSP目标地址(DestAddr) */
				/* wangpeipei 20111205 ADD E */

				PrintFiles(RecordArray, RecordSize, "\tNoAppDataCr:");
				PrintFileHex(RecordArray, RecordSize, &LnkNodeArr[index].RsspLinInfo.NoAppDataCycleNum, 1);	/* 无应用数据周期数 */
				PrintFiles(RecordArray, RecordSize, "\tRecvDataCr:");
				PrintFileHex(RecordArray, RecordSize, &LnkNodeArr[index].RsspLinInfo.NoRecvDataCycleNum, 1);	/* 无接受数据周期数 */
				PrintFiles(RecordArray, RecordSize, "\tRcvStatus:");
				PrintFileHex(RecordArray, RecordSize, &LnkNodeArr[index].RsspLinInfo.RecvLinkStatus, 1);	/* 接受状态(RcvStatus) */
				PrintFiles(RecordArray, RecordSize, "\tSndStatus:");
				PrintFileHex(RecordArray, RecordSize, &LnkNodeArr[index].RsspLinInfo.SendLinkStatus, 1);	/* 接受状态(RcvStatus) */
				PrintFiles(RecordArray, RecordSize, "\tNodeStatus:");
				PrintFileHex(RecordArray, RecordSize, &LnkNodeArr[index].NodeStatus, 1);	/* 可覆盖状态(NodeStatus) */
				PrintFiles(RecordArray, RecordSize, "\tTC:");
				PrintFileU32Hex(RecordArray, RecordSize, LnkNodeArr[index].RsspLinInfo.TimeStmp.TC);	/* 计数器(TC) */
				PrintFiles(RecordArray, RecordSize, "\tSrcAddr:");
				PrintFileU16Hex(RecordArray, RecordSize, LnkNodeArr[index].RsspLinInfo.RsspSrcAddr);	/* 本方RSSP源地址(SrcAddr) */
				PrintFiles(RecordArray, RecordSize, "\tBsdAddr:");
				PrintFileU16Hex(RecordArray, RecordSize, LnkNodeArr[index].RsspLinInfo.DestBsdAdd);	/* 本方RSSPBSD地址(BsdAddr) */
				PrintFiles(RecordArray, RecordSize, "\tDestAddr:");
				PrintFileU16Hex(RecordArray, RecordSize, LnkNodeArr[index].RsspLinInfo.RsspDestAddr);	/* 本方RSSP目标地址(DestAddr) */
				PrintFiles(RecordArray, RecordSize, "\tLastRcvTCr:");
				PrintFileU32Hex(RecordArray, RecordSize, LnkNodeArr[index].RsspLinInfo.TimeStmp.LastLocalRecTC);	/* 最新收到报文本地时钟(LastRcvTCr)	 */
				PrintFiles(RecordArray, RecordSize, "\tLastSsrTC:");
				PrintFileU32Hex(RecordArray, RecordSize, LnkNodeArr[index].RsspLinInfo.TimeStmp.SsrTc);	/* 上次同步周期号(LastSsrTC) */
				PrintFiles(RecordArray, RecordSize, "\tRcvTCe:");
				PrintFileU32Hex(RecordArray, RecordSize, LnkNodeArr[index].RsspLinInfo.TimeStmp.NowRecvTCr);	/* 当前接收到发送方报文时钟(RcvTCe) */
				PrintFiles(RecordArray, RecordSize, "\tSSETCr:");
				PrintFileU32Hex(RecordArray, RecordSize, LnkNodeArr[index].RsspLinInfo.TimeStmp.SseTC);	/* SSE请求时周期号(SSETCr) */
				PrintFiles(RecordArray, RecordSize, "\tSndSsrNum:");
				PrintFileHex(RecordArray, RecordSize, &LnkNodeArr[index].RsspLinInfo.TimeStmp.NumSendSse, 1);	/* 发送SSE次数(SndSsrNum) */
				PrintFiles(RecordArray, RecordSize, "\n");
#endif 
#ifdef RSSP_RECORD_SIMPLIFY_BIN	/*是否定义二进制宏开关*/
				PrintRecArrayByte(RecordArray, RecordSize, index); /*-< 记录当前链路下标日志*/
				PrintRecArray2ByteB(RecordArray, RecordSize, LnkNodeArr[index].RsspLinInfo.RsspDestAddr); /*-< 记录RSSPI目的地址日志*/
				PrintRecArray2ByteB(RecordArray, RecordSize, LnkNodeArr[index].DestTypeId); /*-< 记录目的类型ID日志*/
				PrintRecArray2ByteB(RecordArray, RecordSize, LnkNodeArr[index].DestLogicId); /*-< 记录目的逻辑ID日志*/
				PrintRecArrayByte(RecordArray, RecordSize, LnkNodeArr[index].ExeCycle); /*-< 记录是否执行协议日志*/
				PrintRecArray4ByteB(RecordArray, RecordSize, LnkNodeArr[index].CycleNum); /*-< 记录周期号日志*/

				PrintRecArrayByte(RecordArray, RecordSize, LnkNodeArr[index].NodeStatus); /*-< 记录可覆盖状态日志*/
				PrintRecArrayByte(RecordArray, RecordSize, LnkNodeArr[index].RsspLinInfo.RecvLinkStatus); /*-< 记录接受状态日志*/
				PrintRecArrayByte(RecordArray, RecordSize, LnkNodeArr[index].RsspLinInfo.NoRecvDataCycleNum); /*-< 记录无接受数据周期数日志*/
				PrintRecArrayByte(RecordArray, RecordSize, LnkNodeArr[index].RsspLinInfo.SendLinkStatus); /*-< 记录发送状态日志*/
				PrintRecArrayByte(RecordArray, RecordSize, LnkNodeArr[index].RsspLinInfo.NoAppDataCycleNum); /*-< 记录无应用数据周期数日志*/
				PrintRecArrayByte(RecordArray, RecordSize, LnkNodeArr[index].RecvKeepHaltCycleNum);	/*-< 接收保持Halt_WL状态周期数日志*/
				PrintRecArrayByte(RecordArray, RecordSize, LnkNodeArr[index].RecvKeepSendSseCycleNum);	/*-< 接收保持SendSSE_WL状态周期数日志*/
				PrintRecArrayByte(RecordArray, RecordSize, LnkNodeArr[index].HasRsdBeforeSseOrSsr); /*-< 记录在生成SSE或者SSR之前是否有生成RSD日志*/

				PrintRecArray4ByteB(RecordArray, RecordSize, LnkNodeArr[index].RsspLinInfo.TimeStmp.TC); /*-< 记录计数日志*/
				PrintRecArray4ByteB(RecordArray, RecordSize, LnkNodeArr[index].RsspLinInfo.TimeStmp.NowTn[0]); /*-< 记录当前周期对应时间戳-1通道日志*/
				PrintRecArray4ByteB(RecordArray, RecordSize, LnkNodeArr[index].RsspLinInfo.TimeStmp.NowTn[1]); /*-< 记录当前周期对应时间戳-2通道日志*/

				PrintRecArray4ByteB(RecordArray, RecordSize, LnkNodeArr[index].RsspLinInfo.TimeStmp.NowRecvTCr); /*-< 记录当前接收到发送方报文时钟(RcvTCe)日志*/
				PrintRecArray4ByteB(RecordArray, RecordSize, LnkNodeArr[index].RsspLinInfo.TimeStmp.LastLocalRecTC); /*-< 记录最新收到报文本地时钟(LastRcvTCr)日志*/

				PrintRecArrayByte(RecordArray, RecordSize, LnkNodeArr[index].RsspLinInfo.TimeStmp.NumSendSse); /*-< 记录发送SSE次数日志*/
				PrintRecArray4ByteB(RecordArray, RecordSize, LnkNodeArr[index].RsspLinInfo.TimeStmp.SseTC); /*-< 记录发送SSE时本方TC日志*/
				PrintRecArray4ByteB(RecordArray, RecordSize, LnkNodeArr[index].RsspLinInfo.TimeStmp.SsrTc); /*-< 记录收到SSR时本方TC日志*/

				PrintRecArray4ByteB(RecordArray, RecordSize, LnkNodeArr[index].RsspLinInfo.TimeStmp.RecvSseTCe); /*-< 记录收到的SSE时帧里TC日志*/

				/*收到SSR RSD时更新*/
				PrintRecArray4ByteB(RecordArray, RecordSize, LnkNodeArr[index].RsspLinInfo.TimeStmp.NowSINIT_ADD_SID_XOR_Tn[0]); /*-< 记录当前的收到报文时 SINITr AND [SIDr ^ Tr(n)]1通道日志*/
				PrintRecArray4ByteB(RecordArray, RecordSize, LnkNodeArr[index].RsspLinInfo.TimeStmp.NowSINIT_ADD_SID_XOR_Tn[1]); /*-< 记录当前的收到报文时 SINITr AND [SIDr ^ Tr(n)]-2通道日志*/
#endif
			}
		}

	}

	return ret; /*-< 返回函数返回值*/
}


/*--------------------------------------------------------------------
 * RSSP层对外接口函数定义 End
 *--------------------------------------------------------------------*/
 
 /*--------------------------------------------------------------------
 * RSSP层输输出模块内部使用函数实现 Start
 *--------------------------------------------------------------------*/

 /**
* @brief CreateRsdMsg_WL 根据应用数据 作成 RSD报文
* @param pAppData 应用层到Rssp层的输入队列队列节点 取值范围:字节数组
* @param DataLen 数组pAppData的数据长度 取值范围:0x0000-0xFFFF
* @param OutBsdMsg RSSP消息帧  取值范围:字节数组
* @param pPNode 对应节点 取值范围:参考结构体Lnk_Info_Node_Stru_WL
* @param pRsspStru RSSPI变量 取值范围:参考结构体RSSP_INFO_STRU
 * @return 0:失败;1:成功
*/
static UINT8 CreateRsdMsg_WL(const UINT8 *pAppData,UINT16 DataLen,
						  UINT8 *OutBsdMsg, Lnk_Info_Node_Stru_WL** pPNode,RSSP_INFO_STRU *pRsspStru)
{
	UINT8 ret = 0; /*-< 设置函数返回值为失败*/
	UINT32 LocalDevName = 0;									/*本方唯一ID*/
	UINT16 oppTypeId = 0;										/*对方类型ID*/
	UINT16 oppLogicId = 0;										/*对方逻辑ID*/
	UINT16 MsgLen = 0;											/* 应用数据长度 */
	UINT16 SrcAddr = 0, DestAddr = 0;							/* 源地址，以及 目标地址（SSE_SSR）*/
	UINT16 BsdAddr = 0;											/* BSD地址 */
	UINT16 CRC16 = 0;											/* RSSP消息CRC */
	UINT32 CRCM[2] ={0};										/* CRCM数组 */
	Lnk_Info_Node_Stru_WL *pTmpNode = NULL;						/* 通信节点指针 */
	UINT8 *RecordArray = NULL;	/* 记录 */
	UINT16 RecordSize = 0;	/* 记录数组大小 */
	UINT32 DestDevName = 0;
	const UINT8 DEST_TYPE_APP_QUE_POS = 2;						/* 应用层队列保存对方类型的位置 */
	const UINT8 DEST_ID_APP_QUE_POS = DEST_TYPE_APP_QUE_POS+1;	/* 应用层队列保存对方ID的位置 */
	const UINT8 DEST_LOGIC_ID_QUE_POS = DEST_ID_APP_QUE_POS+1;		/* 应用层队列保存对方逻辑ID的位置 */
	const UINT8 DATA_APP_QUE_POS = DEST_LOGIC_ID_QUE_POS + 2;		/* 应用层队列保存应用数据的位置 */
    
	if ((NULL != pAppData)&&(NULL != OutBsdMsg)&&(NULL != pPNode) && (NULL != pRsspStru) &&(NULL != pRsspStru->pDsuRsspInfoStruWL)&&(DataLen >= DATA_APP_QUE_POS)&&(NULL != pRsspStru->RecordArray)) /*-< 参数是否非空*/
	{
		RecordArray = pRsspStru->RecordArray; /*-< 设置记录数组*/
		RecordSize = pRsspStru->RecordArraySize;	/*-< 设置记录数组长度*/

		LocalDevName = pRsspStru->pDsuRsspInfoStruWL->LocEmitterName;	/*-< 设置本方唯一ID*/
		/*
		 *  ----------------------------------------------------
		 *   数据长度 | DestType | DestID   | 应用数据	|
		 *    2字节   |  1字节   |   1字节  |      n    |
		 *  -----------------------------------------------------
		 */

		TypeId2DevName_WL(pAppData[DEST_TYPE_APP_QUE_POS], pAppData[DEST_ID_APP_QUE_POS], &oppTypeId); /*-< 调用得到对方类型ID函数*/
		oppLogicId = ShortFromChar(&pAppData[DEST_LOGIC_ID_QUE_POS]); /*-< 调用得到对方逻辑ID函数*/
#ifdef RSSP_NO_HLHT
		DestDevName = oppTypeId; /*-< 设置对方唯一ID*/
#else
		DestDevName = DquTypeIdToHlhtId(oppTypeId, oppLogicId, pRsspStru->pDsuRsspInfoStruWL); /*-< 调用设置对方唯一ID函数*/
#endif
		ret = dsuRsspRGetAddrWl(DestDevName, LocalDevName, &SrcAddr, &DestAddr, pRsspStru->pDsuRsspInfoStruWL); /*-< 调用获取协议地址函数,结果赋值给函数返回值*/
		if (ret == 1) /*-< 函数返回值是否成功*/
		{
		}
		else
		{
			ret = 0; /*-< 设置函数返回值为失败*/
			return ret; /*-< 返回函数返回值*/
		}
		BsdAddr = DestAddr;	/*-< 设置BSD地址*/
		MsgLen = DataLen - DATA_APP_QUE_POS; /*-< 设置应用数据长度*/

#ifdef RSSP_RECORD_ERR_ASCII	/* 字符串格式 */
		PrintFiles(RecordArray, RecordSize, "IN:\n");
		PrintFiles(RecordArray, RecordSize, "SrcAddr:");
		PrintFileU16Hex(RecordArray, RecordSize, SrcAddr);	/* 源地址 */
		PrintFiles(RecordArray, RecordSize, "\tBsdAddr:");
		PrintFileU16Hex(RecordArray, RecordSize, BsdAddr);	/* BSD地址 */
		PrintFiles(RecordArray, RecordSize, "\tSrcAddr:");
		PrintFileU16Hex(RecordArray, RecordSize, DestAddr);	/* 目标地址 */
		PrintFiles(RecordArray, RecordSize, "\tDataLen:");
		PrintFileU16Hex(RecordArray, RecordSize, MsgLen);		/* 纯应用数据长度 */
		PrintFiles(RecordArray, RecordSize, "\n");
#endif 
#ifdef RSSP_RECORD_SIMPLIFY_BIN	/* 二进制 */	
		PrintRecArrayByte(RecordArray, RecordSize, 0x80);		/*-< 记录帧类型日志*/
		PrintRecArray2ByteB(RecordArray, RecordSize, BsdAddr);	/*-< 记录目标地址日志*/
		PrintRecArray2ByteB(RecordArray, RecordSize, MsgLen);	/*-< 记录纯应用数据长度日志*/
#endif

	/* 查询对应通信节点是否存在 */
		pTmpNode = SearchNodeByAddr_WL(DestDevName, pRsspStru); /*-< 调用查询节点函数*/
		if (NULL == pTmpNode)		/*-< 通信节点是否为空开*/
		{
			/* 根据地址来区的覆盖节点，将节点覆盖 */
			ret = outputReplaceLnkNode_WL(SrcAddr, BsdAddr, DestAddr, LocalDevName, &pTmpNode, pRsspStru); /*-< 调用生成节点函数*/
			if (0 == ret) /*-< 调用函数是否成功*/
			{
				/* 节点覆盖 失败，记录 错误返回 */
#ifdef RSSP_RECORD_ERR_ASCII	/* 字符串格式 */
				PrintFiles(RecordArray, RecordSize, "W:Replace Node Err.\n"); /*-< 记录生成节点错误日志*/
#endif 
#ifdef RSSP_RECORD_SIMPLIFY_BIN
				PrintRecArrayByte(RecordArray, RecordSize, OUTPUT_NEW_NODE_ERR); /*-< 记录生成节点错误日志*/
#endif
				return ret; /*-< 返回函数返回值*/
			}
			else
			{
				pTmpNode->CycleNum = *pRsspStru->CycleNum;	/*-< 设置应用周期给协议*/
				pTmpNode->DestTypeId = oppTypeId;	/*-< 设置对方类型ID*/
				pTmpNode->DestLogicId = oppLogicId;	/*-< 设置对方逻辑ID*/
				pTmpNode->RsspLinInfo.TimeStmp.TC = pTmpNode->CycleNum; /*-< 新链路设置计算器开始*/
				PrintRecArrayByte(RecordArray, RecordSize, OUTPUT_NEW_NODE); /*-< 记录创建新节点日志*/
			}
		}
		else /* 通信节点存在 */
		{
			/* 继续处理 */
		}

		if (1 == pTmpNode->ExeCycle)	/*-< 此链路是否执行周期*/
		{
			/* 有应用数据发送的通信节点置为不可覆盖状态 */
			pTmpNode->NodeStatus = DisbaledReplace_WL; /*-< 设置链路节点可用*/
			(*pPNode) = pTmpNode;	/*-< 将通信节点指针保存到输出指针变量里*/

			/* 帧头设定 */
			SetRsspMsgHead_WL(RSSP_RSD_MSG_WL, SrcAddr, BsdAddr, OutBsdMsg); /*-< 调用设置帧头函数*/

			/* Body 设定
			 *  ----------------------------------------------------
			 *   计数器 | 安全数据长度 | CRCM_1 | CRCM_2 | 应用数据	|
			 *    4字节 |     2字节    | 4字节  |  4字节 |    n     |
			 *  -----------------------------------------------------
			 */
			 /* 应用数据 */
			 /* 从pAppData+8 开始拷贝 MsgLen个应用数据到 报文里 */
			RsspMemCopy_WL(&pAppData[DATA_APP_QUE_POS], &OutBsdMsg[RSSP_DATA_POS_WL], MsgLen); /*-< 复制应用数据到报文*/
			/* wangpeipei 20120328 yuweiliantiaoshi Mod */
			/*if((MsgLen%2) != 0)*/	/* 安全数据长度非偶数 */
			/*{
				OutBsdMsg[RSSP_DATA_POS+MsgLen] = 0;*/	/* 安全数据补零 */
				/*MsgLen += 1;
			}
			else
			{*/
			/* 什么不做 */
		/*}*/

		/* 计算CRCM值,(肯定返回1 ) */
			ret = CalcCRCM_WL(&OutBsdMsg[RSSP_DATA_POS_WL], MsgLen,
				pTmpNode->RsspLinInfo.LocalNode.SIDr,
				pTmpNode->RsspLinInfo.TimeStmp.NowTn,
				CRCM); /*-< 调用计算SVC函数,结果赋值给函数返回值*/

			/* 计数器 设定 4字节 */
			LongToCharLE(pTmpNode->RsspLinInfo.TimeStmp.TC, &OutBsdMsg[RSSP_TC_POS_WL]); /*-< 设置计数器到报文*/

			/* 安全数据长度 应用数据+ 2个CRCM长度  2字节 */
			ShortToCharLE((UINT16)(MsgLen + 2 * CRCM_LEN_WL), &OutBsdMsg[RSSP_DATA_SIZE_POS_WL]); /*-< 设置数据长度到报文*/
#ifdef DOUBLE_CPU_INTERACTIVE_SVC
            if(0u == pRsspStru->cpuId) /*-< CPUID是否为0*/
            {
                /* CRCM[0] CRCM[1] 设定  4 字节 */
                LongToCharLE(CRCM[0], &OutBsdMsg[RSSP_CRCM_1_POS_WL]); /*-< 设置1通道SVC到报文*/
                LongToCharLE((UINT32)0u, &OutBsdMsg[RSSP_CRCM_2_POS_WL]); /*-< 设置2通道0到报文*/
            }
            else
            {
                /* CRCM[0] CRCM[1] 设定  4 字节 */
               LongToCharLE((UINT32)0u, &OutBsdMsg[RSSP_CRCM_1_POS_WL]); /*-< 设置1通道0到报文*/
               LongToCharLE(CRCM[1], &OutBsdMsg[RSSP_CRCM_2_POS_WL]); /*-< 设置2通道SVC到报文*/
            }
#else
            /* CRCM[0] CRCM[1] 设定  4 字节 */
            LongToCharLE(CRCM[0], &OutBsdMsg[RSSP_CRCM_1_POS_WL]); /*-< 设置1通道SVC到报文*/
            LongToCharLE(CRCM[1], &OutBsdMsg[RSSP_CRCM_2_POS_WL]); /*-< 设置2通道SVC到报文*/
#endif
			/* 16位 CRC 设定 2 字节 */
			CRC16 = ComputeMsgCRC16_WL(OutBsdMsg, (UINT16)(MsgLen + RSSP_FIXED_LEN_WL - CRC_16_LEN_WL)); /*-< 计算CRC值*/
			ShortToCharLE(CRC16, &OutBsdMsg[(UINT16)(MsgLen + RSSP_FIXED_LEN_WL - CRC_16_LEN_WL)]); /*-< 设置CRC值到报文*/


			/* 无发送应用数据置为 0 */
			pTmpNode->RsspLinInfo.NoAppDataCycleNum = 0; /*-< 设置无应用数据周期数为0*/

			ret = 1; /*-< 设置函数返回值为成功*/
		}
		else	/*此链路不是执行周期则不生成RSD*/
		{
			ret = 0; /*-< 设置函数返回值为失败*/
		}
	}
	
	return ret; /*-< 返回函数返回值*/
}

 /**
  * @brief CreateSseMsg_WL 创建SSE帧
  * @param pLnkNodeInfo 链路节点 取值范围:参考结构体:Lnk_Info_Node_Stru_WL
  * @param OutSseMsg SSE帧数据 取值范围:参考结构体:字节数组
  * @param pRsspStru RSSPI实例 取值范围:参考结构体:RSSP_INFO_STRU
  * @return 0:失败 1:成功
  */
static UINT8 CreateSseMsg_WL(Lnk_Info_Node_Stru_WL* pLnkNodeInfo, UINT8* OutSseMsg, RSSP_INFO_STRU* pRsspStru)
{
	UINT8 ret = 0u; /*-< 设置函数返回值为失败*/
	UINT16 Crc16 = 0u; /*CRC值*/
	UINT32 TmpSeqEnq = 0u; /*临时保存SEQENQ*/

	pLnkNodeInfo->RsspLinInfo.RecvLinkStatus = WaitSSR_WL; /*-< 设置当前链路节点收状态为等SSR*/

	pLnkNodeInfo->RsspLinInfo.NoRecvDataCycleNum = 0u; /*-< 清零当前链路节点无收数据周期数*/

	pLnkNodeInfo->RsspLinInfo.NoAppDataCycleNum = 0u; /*-< 清零当前链路节点无发送应用数据*/

	pLnkNodeInfo->RecvKeepSendSseCycleNum = 0u; /*-< 清零接收保持SendSSE_WL状态周期数*/

	/* SSE请求时周期和对应时间戳设定 */
	pLnkNodeInfo->RsspLinInfo.TimeStmp.SseTC = pLnkNodeInfo->RsspLinInfo.TimeStmp.TC; /*-< 设置当前链路节点SSE请求时周期号为当前周期号*/
	pLnkNodeInfo->RsspLinInfo.TimeStmp.SseTn[0] = pLnkNodeInfo->RsspLinInfo.TimeStmp.NowTn[0]; /*-< 设置当前链路节点SSE请求时1通道时间戳为1通道SINIT*/
	pLnkNodeInfo->RsspLinInfo.TimeStmp.SseTn[1] = pLnkNodeInfo->RsspLinInfo.TimeStmp.NowTn[1]; /*-< 设置当前链路节点SSE请求时2通道时间戳为2通道SINIT*/

	SetRsspMsgHead_WL(RSSP_SSE_MSG_WL, pLnkNodeInfo->RsspLinInfo.RsspSrcAddr, pLnkNodeInfo->RsspLinInfo.RsspDestAddr, OutSseMsg); /*-< 调用生成帧头函数*/

	LongToCharLE(pLnkNodeInfo->RsspLinInfo.TimeStmp.SseTC, &OutSseMsg[RSSP_TC_POS_WL]); /*-< 设置SSE周期号*/

#ifdef DOUBLE_CPU_INTERACTIVE_SVC /*是否定义双SVC宏开关*/
	if (0u == pRsspStru->cpuId) /*-< 当前CPU是否0*/
	{
		TmpSeqEnq = pLnkNodeInfo->RsspLinInfo.LocalNode.SIDr[0] ^ pLnkNodeInfo->RsspLinInfo.TimeStmp.SseTn[0]; /*-< 得到1通道SSE时间戳*/
		LongToCharLE(TmpSeqEnq, &OutSseMsg[RSSP_SSE_ENQ_1_POS_WL]); /*-< 设置1通道SSE时间戳给SSE帧SeqEnq1位置数据*/

		LongToCharLE((UINT32)0u, &OutSseMsg[RSSP_SSE_ENQ_2_POS_WL]); /*-< 设置2通道0给SSE帧SeqEnq2位置数据*/
	}
	else
	{
		LongToCharLE((UINT32)0u, &OutSseMsg[RSSP_SSE_ENQ_1_POS_WL]); /*-< 设置1通道0给SSE帧SeqEnq1位置数据*/

		TmpSeqEnq = pLnkNodeInfo->RsspLinInfo.LocalNode.SIDr[1] ^ pLnkNodeInfo->RsspLinInfo.TimeStmp.SseTn[1]; /*-< 得到2通道SSE时间戳*/
		LongToCharLE(TmpSeqEnq, &OutSseMsg[RSSP_SSE_ENQ_2_POS_WL]); /*-< 设置2通道SSE时间戳给SSE帧SeqEnq2位置数据*/
	}
#else/* SEQENQ_1 （SIDe ^ Tn ）设定 */
	TmpSeqEnq = pLnkNodeInfo->RsspLinInfo.LocalNode.SIDr[0] ^ pLnkNodeInfo->RsspLinInfo.TimeStmp.SseTn[0]; /*-< 得到1通道SSE时间戳*/
	LongToCharLE(TmpSeqEnq, &OutSseMsg[RSSP_SSE_ENQ_1_POS_WL]); /*-< 设置1通道SSE时间戳给SSE帧SeqEnq1位置数据*/

	/* SEQENQ_2 设定 */
	TmpSeqEnq = pLnkNodeInfo->RsspLinInfo.LocalNode.SIDr[1] ^ pLnkNodeInfo->RsspLinInfo.TimeStmp.SseTn[1]; /*-< 得到2通道SSE时间戳*/
	LongToCharLE(TmpSeqEnq, &OutSseMsg[RSSP_SSE_ENQ_2_POS_WL]); /*-< 设置2通道SSE时间戳给SSE帧SeqEnq2位置数据*/
#endif

	Crc16 = ComputeMsgCRC16_WL(OutSseMsg, RSSP_SSE_LEN_WL - CRC_16_LEN_WL); /*-< 计算得到帧CRC值*/
	ShortToCharLE(Crc16, &OutSseMsg[RSSP_SSE_LEN_WL - CRC_16_LEN_WL]); /*-< 设置CRC值给帧数据*/

	ret = 1u; /*-< 设置函数返回值为成功*/
	return ret; /*-< 返回函数返回值*/
}

/***********************************************************************
 * 方法名   : CreateSsrMsg_WL
 * 功能描述 : 作成SSR报文消息帧。
 * 输入参数 : 
 *	参数名			类型				输入输出		描述
 *  --------------------------------------------------------------
 *	pLnkNodeInfo	Lnk_Info_Node_Stru_WL*	INOUT	通信节点指针
 *  OutSsrMsg		UINT8*				OUT		SSR报文
 *  限制条件：pLnkNodeInfo 以及OutSseMsg 指针非空，由调用处保证
 * 返回值   : 1 正常
 ***********************************************************************/
static UINT8 CreateSsrMsg_WL(Lnk_Info_Node_Stru_WL *pLnkNodeInfo,UINT8 *OutSsrMsg,RSSP_INFO_STRU *pRsspStru)
{
	UINT8 ret = 0;			/* 返回值 */
	UINT16 Crc16 = 0;		/* CRC 16 */
	UINT32 TmpSeqIni = 0;	/* 临时保存SEQIni */

	/* 设定发送状态为发送数据 */
	pLnkNodeInfo->RsspLinInfo.SendLinkStatus = SendData_WL;
	pLnkNodeInfo->RsspLinInfo.NoAppDataCycleNum = 0;
	

	/* 帧头设定 */
	SetRsspMsgHead_WL(RSSP_SSR_MSG_WL,pLnkNodeInfo->RsspLinInfo.RsspSrcAddr,
		pLnkNodeInfo->RsspLinInfo.RsspDestAddr,OutSsrMsg);

	/* Body 设定 */
	LongToCharLE(pLnkNodeInfo->RsspLinInfo.TimeStmp.TC, &OutSsrMsg[RSSP_TC_POS_WL]);		 /* 计数器 */
	LongToCharLE(pLnkNodeInfo->RsspLinInfo.TimeStmp.RecvSseTCe,&OutSsrMsg[RSSP_SSR_TCENQ_POS_WL]); /* 接受的SSE报文计数器 */
	
#ifdef DOUBLE_CPU_INTERACTIVE_SVC
    if(0u == pRsspStru->cpuId)
    {
        TmpSeqIni = pLnkNodeInfo->RsspLinInfo.TimeStmp.SeqEng[0] ^ pLnkNodeInfo->RsspLinInfo.LocalNode.SIDr[0]
                    ^ pLnkNodeInfo->RsspLinInfo.LocalNode.DATAVER[0] ^ pLnkNodeInfo->RsspLinInfo.TimeStmp.NowTn[0];
        LongToCharLE(TmpSeqIni,&OutSsrMsg[RSSP_SSR_INI_1_POS_WL]);

        /* SEQINI_2 设定 */
        LongToCharLE((UINT32)0u,&OutSsrMsg[RSSP_SSR_INI_2_POS_WL]);
    }
    else
    {
        /* SEQINI = SEQENQ ^ SIDr ^ DataVer ^ Tr(n) */
        /* SEQINI_1 设定 */
        LongToCharLE((UINT32)0u,&OutSsrMsg[RSSP_SSR_INI_1_POS_WL]);

        /* SEQINI_2 设定 */
        TmpSeqIni = pLnkNodeInfo->RsspLinInfo.TimeStmp.SeqEng[1] ^ pLnkNodeInfo->RsspLinInfo.LocalNode.SIDr[1]
                    ^ pLnkNodeInfo->RsspLinInfo.LocalNode.DATAVER[1] ^ pLnkNodeInfo->RsspLinInfo.TimeStmp.NowTn[1];
        LongToCharLE(TmpSeqIni,&OutSsrMsg[RSSP_SSR_INI_2_POS_WL]);
    }
#else
   /* SEQINI = SEQENQ ^ SIDr ^ DataVer ^ Tr(n) */
    /* SEQINI_1 设定 */
    TmpSeqIni = pLnkNodeInfo->RsspLinInfo.TimeStmp.SeqEng[0] ^ pLnkNodeInfo->RsspLinInfo.LocalNode.SIDr[0]
                ^ pLnkNodeInfo->RsspLinInfo.LocalNode.DATAVER[0] ^ pLnkNodeInfo->RsspLinInfo.TimeStmp.NowTn[0];
    LongToCharLE(TmpSeqIni,&OutSsrMsg[RSSP_SSR_INI_1_POS_WL]);

    /* SEQINI_2 设定 */
    TmpSeqIni = pLnkNodeInfo->RsspLinInfo.TimeStmp.SeqEng[1] ^ pLnkNodeInfo->RsspLinInfo.LocalNode.SIDr[1]
                ^ pLnkNodeInfo->RsspLinInfo.LocalNode.DATAVER[1] ^ pLnkNodeInfo->RsspLinInfo.TimeStmp.NowTn[1];
    LongToCharLE(TmpSeqIni,&OutSsrMsg[RSSP_SSR_INI_2_POS_WL]);
#endif
	/* NUM_DATAVER 设定 由于信号道1 和信号道2 版本号一致 因而默认为信号道1 */
	OutSsrMsg[RSSP_SSR_NUM_POS_WL] = pLnkNodeInfo->RsspLinInfo.LocalNode.NumDataVer[0];
	
	/* CRC 设定*/
	Crc16 = ComputeMsgCRC16_WL(OutSsrMsg,RSSP_SSR_LEN_WL-CRC_16_LEN_WL);
	ShortToCharLE(Crc16,&OutSsrMsg[RSSP_SSR_LEN_WL-CRC_16_LEN_WL]);	
	
	ret =1;
	return ret;
}

/***********************************************************************
 * 方法名   : SetRsspMsgHead_WL
 * 功能描述 : Rssp消息帧头作成。
 * 输入参数 : 
 *	参数名			类型		输入输出		描述
 *  --------------------------------------------------------------
 *	MsgLen			UINT8		IN		消息类型
 *	SrcAddr			UINT16		IN		源地址
 *  DestAddr		UINT16		IN		目标地址
 *  OutRsspMsg		UINT8*		OUT		RSSP消息帧
 *  限制条件：OutRsspMsg 指针非空以及各数据正确性，由调用处保证
 * 返回值   : 无
 ***********************************************************************/
static void SetRsspMsgHead_WL(UINT8 MsgType, UINT16 SrcAddr, UINT16 DestAddr, UINT8 *OutRsspMsg)
{
	OutRsspMsg[RSSP_APP_CTGRY_POS_WL] = RSSP_APP_CATEGORY_WL;			/* signaling variables */
	OutRsspMsg[RSSP_MSG_TYPE_POS_WL] = MsgType;					/* 消息类型设定 */
	ShortToCharLE(SrcAddr,&OutRsspMsg[RSSP_SRC_ADD_POS_WL]);		/* 设定源地址，LITTLE endian */
	ShortToCharLE(DestAddr,&OutRsspMsg[RSSP_DEST_ADD_POS_WL]);		/* 设定源地址，LITTLE endian */

}

/*
*函数名:	WriteToAppArray
*功能描述:	写输出数据到输出协议给应用数据数组中
*输入参数:	const UINT8* appData 应用数据数组
*			const UINT16 appDataLen 应用数据数组长度
*			Lnk_Info_Node_Stru_WL* lnkNode 链路节点
*			RSSP_INFO_STRU* rssp RSSPI结构
*输入出参:	UINT32* curAppArrayIdx 输出协议给应用数据数组当前下标
*输出参数:	无
*返回值:	是否写入成功.0:失败;1:成功
*/
static UINT8 WriteToAppArray(const UINT8* appData, const UINT16 appDataLen, Lnk_Info_Node_Stru_WL* lnkNode, UINT32* curAppArrayIdx, RSSP_INFO_STRU* rssp)
{
	UINT8 rtn = 0; /*返回值*/
	UINT8 pkgType = 0; /*包类型*/
	UINT16 dstAddr = 0; /*目的地址*/
	UINT32 sn = 0; /*序号*/

	if ((NULL != appData) && (NULL != lnkNode) && (NULL != curAppArrayIdx) && (NULL != rssp)) /*参数防空*/
	{
		PrintRecArray2ByteB(rssp->RecordArray, rssp->RecordArraySize, appDataLen); /*输出给应用长度*/
		
		if ((*curAppArrayIdx) + 7 + appDataLen <= rssp->AppArraySize) /*可写入数据,7字节AppArray的每包头*/
		{
			if (appDataLen > 10) /*帧格式正常,10字节到有RSSPI序号*/
			{
				ShortToChar(5 + appDataLen, &rssp->AppArray[*curAppArrayIdx]); /*设置此包长度*/
				(*curAppArrayIdx) += 2; /*2字节长度*/

				rssp->AppArray[*curAppArrayIdx] = RSSPI_TYPE_IN_ADAPTER; /*1字节协议类型 */
				(*curAppArrayIdx) += 1;

				ShortToChar(lnkNode->DestTypeId, &rssp->AppArray[*curAppArrayIdx]); /*2字节对方类型ID*/
				(*curAppArrayIdx) += 2;

				ShortToChar(lnkNode->DestLogicId, &rssp->AppArray[*curAppArrayIdx]); /*2字节对方逻辑ID*/
				(*curAppArrayIdx) += 2;

				RsspMemCopy_WL(appData, &rssp->AppArray[*curAppArrayIdx], appDataLen); /*RSSPI帧数据*/
				(*curAppArrayIdx) += appDataLen;

				LongToChar((*curAppArrayIdx) - 4, rssp->AppArray); /*调整总长度*/

				pkgType = appData[RSSP_MSG_TYPE_POS_WL]; /*帧类型*/
				dstAddr = ShortFromCharLE(&appData[RSSP_DEST_ADD_POS_WL]); /*对方地址*/
				sn = LongFromCharLE(&appData[RSSP_TC_POS_WL]); /*序号*/
				PrintRecArrayByte(rssp->RecordArray, rssp->RecordArraySize, pkgType); /*帧类型*/
				PrintRecArray2ByteB(rssp->RecordArray, rssp->RecordArraySize, dstAddr); /*RSSPI目的地址*/
				PrintRecArray4ByteB(rssp->RecordArray, rssp->RecordArraySize, sn); /*序号*/

				rtn = 1; /*处理正常*/
			}
			else /*帧格式错误*/
			{
				PrintRecArrayByte(rssp->RecordArray, rssp->RecordArraySize, OUTPUT_FRAME_ERR);
			}
		}
		else /*无空间*/
		{
			PrintRecArrayByte(rssp->RecordArray, rssp->RecordArraySize, OUTPUT_WRITE_NO_SPACE_ERR);
		}
	}

	return rtn;
}

/***********************************************************************
 * 方法名   : RecvLnkStatusMng_WL
 * 功能描述 : 根据通信节点的信息进行状态变化。
 * 输入参数 :
 *	参数名		类型				输入输出	描述
 *  --------------------------------------------------------------
 *	pBsdMsg		const DataNod_WLe*		IN			Bsd报文
 *  pLnkNode	Lnk_Info_Node_Stru_WL 	INOUT		RSSP到应用的输出队列
 *

 * 返回值   : UINT8  1：正常返回
 ***********************************************************************/
static void RecvLnkStatusMng_WL(RSSP_INFO_STRU* pRsspStru)
{
	UINT8 index = 0u; /*下标*/
	UINT8 LnkNodeNum = 0u; /*链路节点数*/
	UINT8 RecvStatus = 0u; /*收状态*/
	UINT32 LastLocalRecTC = 0u; /*上次收到报文本地周期号*/
	UINT32 NoRecDataTc = 0u; /*无收数据周期数*/
	UINT8 delLnkRtn = 0u; /*删除链路结果*/

#ifdef TIMED_SSE /*是否定义定时发SSE时序校正宏开关*/
	INT32 AntiDelayTC = 0; /*当前周期与收SSR周期差是否超配置,-1:超配置*/
#endif
	Lnk_Info_Node_Stru_WL* LnkNodeArr = NULL; /*链接节点列表*/
	UINT32 destDevName = 0u;	/*对方设备唯一ID*/

	GetLnkNodeArr_WL(&LnkNodeArr, &LnkNodeNum, pRsspStru); /*-< 调用函数获取链接节点列表和列表数量*/
	for (index = 0u; index < LnkNodeNum; index++) /*-< 当前节点下标是否小于节点总数*/
	{
		if (1u == LnkNodeArr[index].ExeCycle) /*-< 此链路是否执行周期*/
		{
			RecvStatus = LnkNodeArr[index].RsspLinInfo.RecvLinkStatus; /*-< 设置当前节点收状态给收状态*/
			if ((WaitSSR_WL == RecvStatus) || (RecvData_WL == RecvStatus)) /*-< 收状态是否等SSR或收数据状态*/
			{
				LastLocalRecTC = LnkNodeArr[index].RsspLinInfo.TimeStmp.LastLocalRecTC; /*-< 设置当前节点上次收到有效数据时周期号给上次收到有效数据时周期号*/
				if (LnkNodeArr[index].RsspLinInfo.TimeStmp.TC != LastLocalRecTC) /*-< 当前周期号是否不等于上次收到有效数据时周期号*/
				{
					LnkNodeArr[index].RsspLinInfo.NoRecvDataCycleNum += 1u; /*-< 设置当前节点无收数据周期数自增1*/
					NoRecDataTc = LnkNodeArr[index].RsspLinInfo.NoRecvDataCycleNum; /*-< 设置当前节点无收数据周期数给无收数据周期数*/
					if (WaitSSR_WL == RecvStatus) /*-< 收状态是否等SSR状态*/
					{
						if (LnkNodeArr[index].RsspLinInfo.LocalNode.SSDelay < NoRecDataTc) /*-< 无收数据周期数是否大于当前节点容忍的等SSR周期数*/
						{
							if (LnkNodeArr[index].RsspLinInfo.TimeStmp.NumSendSse >= SEND_SSE_NUM_WL) /*-< 当前节点发SSE次数是否大于等于最大发SSE次数*/
							{
								LnkNodeArr[index].RsspLinInfo.RecvLinkStatus = Halt_WL; /*-< 设置当前节点收状态为中断*/
								LnkNodeArr[index].RsspLinInfo.NoRecvDataCycleNum = 0; /*-< 清零当前节点收无数据周期数*/
								LnkNodeArr[index].RsspLinInfo.TimeStmp.NumSendSse = 0; /*-< 清零当前节点发SSE次数*/
							}
							else
							{
								LnkNodeArr[index].RsspLinInfo.RecvLinkStatus = SendSSE_WL; /*-< 设置当前节点收状态为发SSE状态*/
								LnkNodeArr[index].RsspLinInfo.TimeStmp.NumSendSse++; /*-< 设置当前节点发SSE次数自增1*/
							}
						}
						else
						{
							/*-< 什么不做 */
						}
					}
					else
					{
#ifdef TIMED_SSE /*是否定义定时发SSE时序校正宏开关*/
						AntiDelayTC = CheckTimeStamp_WL(LnkNodeArr[index].RsspLinInfo.TimeStmp.TC, LnkNodeArr[index].RsspLinInfo.TimeStmp.SsrTc, LnkNodeArr[index].RsspLinInfo.LocalNode.AntiDelayCount); /*-< 调用函数得到当前周期与收SSR周期差是否超配置*/
						if (AntiDelayTC < 0) /*-< 当前周期与收SSR周期差是否超配置*/
						{
							LnkNodeArr[index].RsspLinInfo.RecvLinkStatus = SendSSE_WL; /*-< 设置当前节点收状态为发SSE状态*/
						}
						else
						{
							/*-< 什么不做*/
						}
#endif
						if (NoRecDataTc > LnkNodeArr[index].RsspLinInfo.LocalNode.DLost) /*-< 无收数据周期数是否大于当前节点容忍的连续无数据周期数*/
						{
							LnkNodeArr[index].RsspLinInfo.RecvLinkStatus = Halt_WL; /*-< 设置当前节点收状态为中断*/
							LnkNodeArr[index].RsspLinInfo.NoRecvDataCycleNum = 0u; /*-< 清零当前节点收无数据周期数*/
						}
						else
						{
							/*-< 什么不做*/
						}
					}
				}
				else
				{
					/*-< 什么不做*/
				}
			}
			else
			{
				/*-< 什么不做*/
			}

			if (DisbaledReplace_WL == LnkNodeArr[index].NodeStatus) /*-< 当前节点链路是否可用*/
			{
				if ((Halt_WL == LnkNodeArr[index].RsspLinInfo.SendLinkStatus)
					&& ((Halt_WL == LnkNodeArr[index].RsspLinInfo.RecvLinkStatus) || (SendSSE_WL == LnkNodeArr[index].RsspLinInfo.RecvLinkStatus))) /*-< 当前节点发送状态是否中断 且 接收状态是否中断或发SSE*/
				{
					if (Halt_WL == LnkNodeArr[index].RsspLinInfo.RecvLinkStatus) /*-< 当前节点接收状态是否中断*/
					{
						LnkNodeArr[index].RecvKeepHaltCycleNum++; /*-< 接收保持Halt_WL状态周期数自增1*/
					}
					else
					{
						LnkNodeArr[index].RecvKeepSendSseCycleNum++; /*-< 接收保持SendSSE_WL状态周期数自增1*/
					}

					/*保持状态达到 最大无数据周期数时 清除链路*/
					if ((LnkNodeArr[index].RecvKeepHaltCycleNum > LnkNodeArr[index].RsspLinInfo.LocalNode.DLost) || (LnkNodeArr[index].RecvKeepSendSseCycleNum > LnkNodeArr[index].RsspLinInfo.LocalNode.DLost)) /*-< 当前节点接收保持Halt_WL状态周期数是否大于当前节点容忍的连续无数据周期数 或 当前节点接收保持SendSSE_WL状态周期数是否大于当前节点容忍的连续无数据周期数*/
					{
						destDevName = LnkNodeArr[index].DestDevName; /*-< 设置当前节点对方唯一ID给对方唯一ID*/
						delLnkRtn = RsspLnkDelete_WL(destDevName, pRsspStru); /*-< 调用删除链路函数*/
						if (0u == delLnkRtn) /*-< 调用函数返回失败*/
						{
							PrintRecArrayByte(pRsspStru->RecordArray, pRsspStru->RecordArraySize, INPUT_LNK_STATUS_ERR); /*-< 记录删除链路失败日志*/
							PrintRecArray4ByteB(pRsspStru->RecordArray, pRsspStru->RecordArraySize, destDevName); /*-< 记录删除链路失败的对方唯一ID日志*/
						}

						LnkNodeArr[index].RecvKeepHaltCycleNum = 0u; /*-< 清零接收保持Halt_WL状态周期数*/
						LnkNodeArr[index].RecvKeepSendSseCycleNum = 0u; /*-< 清零接收保持SendSSE_WL状态周期数*/
					}
				}
				else
				{
					LnkNodeArr[index].RecvKeepHaltCycleNum = 0u; /*-< 清零接收保持Halt_WL状态周期数*/
					LnkNodeArr[index].RecvKeepSendSseCycleNum = 0u; /*-< 清零接收保持SendSSE_WL状态周期数*/
				}
			}
		}
		else
		{
			/*-< 什么不做*/
		}
	}
}

#ifdef __cplusplus
}
#endif
