/************************************************************************
* 文件名：RpInterface.c
* 文件描述：冗余层协议源代码文件
* 创建时间：2009.10.08 
* 修改记录： 
* 2011.12.07  王佩佩  增加定义RsrCommon.h
* 2011.12.07  王佩佩  增加RpLnkDelete函数。删除冗余层链路。
************************************************************************/
#include "stdlib.h"
#include "CommonMemory.h"
#include "RpStruct.h"
#include "RpInterface.h"
#include "Convert.h"
#include "CommonRecord.h"
#include "RpPlatform.h"
#include "RpDeclare.h"
#include "dsuRpFunc.h"

/*丢包或非宕机错误码记录信息*/
UINT32	gRpErrorInfo;	

UINT8 RpMemSet(UINT8 *pDestAdd, UINT16 Len, UINT8 Val);
static UINT8 StackInitial(CommonStackRp* pStack, UINT16 TotalSize);
static UINT8 StackPop(CommonStackRp* pStack, STACK_DATA_TYPE_RP* pData);
static UINT8 StackPush(CommonStackRp* pStack, STACK_DATA_TYPE_RP Data);
static UINT8 StackFree(CommonStackRp* pStack);

/**
 * @brief RpInit 初始化RP
 * @param fileName FS文件 取值范围:字节数组
 * @param pRpStruct RP实例 取值范围:参考结构体RP_INFO_STRU
 * @return 0:失败 1:成功
 */
UINT8 RpInit(UINT8* fileName, RP_INFO_STRU* pRpStruct)/* %RELAX<MISRA_8_10> */
{
	UINT32 temp; /*记录将要分配的空间大小*/
	UINT8 ret = 0; /*-< 设置函数返回值为失败*/

	if (pRpStruct == NULL) /*-< 参数是否非空*/
	{
		ret = 0; /*-< 设置函数返回值为失败*/
		return ret; /*-< 返回函数返回值*/
	}
	else
	{
		/*-< 往后继续处理*/
	}

	ret = dsuIpInit(fileName, pRpStruct->interfaceType); /*-< 调用初始化读取数据参数函数*/
	if (ret == 0) /*-< 调用函数是否失败*/
	{
		return ret; /*-< 返回函数返回值*/
	}
	/*初始化内部暂存数组*/
	temp = pRpStruct->OutputSize > pRpStruct->InputSize ? pRpStruct->OutputSize : pRpStruct->InputSize; /*-< 计算应用给数据长度*/
	temp += 20; /*-< 应用给数据长度自增20*/
	pRpStruct->Buff_Rp = (UINT8*)malloc(temp); /*-< 调用函数分配应用给数据空间*/
	if (pRpStruct->Buff_Rp == NULL) /*-< 调用函数是否失败*/
	{
		ret = 0; /*-< 设置函数返回值为失败*/
		return ret; /*-< 返回函数返回值*/
	}
	else
	{
		/*无操作*/
		CommonMemSet(pRpStruct->Buff_Rp, sizeof(UINT8) * temp, 0, sizeof(UINT8) * temp); /*-< 清零应用给数据*/
	}

	/*为记录数组分配空间*/
	pRpStruct->RecordArray = (UINT8*)malloc(pRpStruct->RecordArraySize + 2); /*-< 调用函数分配日志记录空间*/
	if (pRpStruct->RecordArray == NULL) /*-< 调用函数是否失败*/
	{
		ret = 0; /*-< 设置函数返回值为失败*/
		return ret; /*-< 返回函数返回值*/
	}
	else
	{
		CommonMemSet(pRpStruct->RecordArray, sizeof(UINT8) * (pRpStruct->RecordArraySize + 2), 0, sizeof(UINT8) * (pRpStruct->RecordArraySize + 2)); /*-< 清零日志记录*/
	}

	/*为冗余输出出口AppArray分配空间*/
	pRpStruct->AppArraySize = (pRpStruct->OutputSize + 15 + 26) * (pRpStruct->MaxNumPerCycle) * (pRpStruct->MaxNumLink) + 2; /*-< 计算输出时协议给应用数据长度*/
	pRpStruct->AppArray = (UINT8*)malloc(pRpStruct->AppArraySize); /*-< 调用函数分配协议给应用数据空间*/
	if (pRpStruct->AppArray == NULL) /*-< 调用函数是否失败*/
	{
		ret = 0; /*-< 设置函数返回值为失败*/
		return ret; /*-< 返回函数返回值*/
	}
	else
	{
		CommonMemSet(pRpStruct->AppArray, sizeof(UINT8) * pRpStruct->AppArraySize, 0, sizeof(UINT8) * pRpStruct->AppArraySize); /*-< 清零协议给应用数据*/
	}

	/*为冗余输出出口VarArray分配空间*/
	pRpStruct->VarArraySize = 68 * (pRpStruct->MaxNumLink + 2); /*-< 计算链路数据长度*/
	pRpStruct->VarArray = (UINT8*)malloc(pRpStruct->VarArraySize); /*-< 调用函数分配链路数据空间*/
	if (pRpStruct->VarArray == NULL) /*-< 调用函数是否失败*/
	{
		ret = 0; /*-< 设置函数返回值为失败*/
		return ret; /*-< 返回函数返回值*/
	}
	else
	{
		CommonMemSet(pRpStruct->VarArray, sizeof(UINT8) * pRpStruct->VarArraySize, 0, sizeof(UINT8) * pRpStruct->VarArraySize); /*-< 清零链路数据*/
	}

	/*为输入给应用的队列DataToApp分配空间*/
	pRpStruct->DataToAppSize = (pRpStruct->InputSize + 4) * pRpStruct->MaxNumPerCycle * pRpStruct->MaxNumLink; /*-< 计算输入时协议给应用队列长度*/
	ret = QueueInitial(&pRpStruct->DataToApp, pRpStruct->DataToAppSize); /*-< 调用函数初始化协议给应用队列,结果赋值给函数返回值*/
	if (ret == 0) /*-< 函数返回值是否失败*/
	{
		return ret; /*-< 返回函数返回值*/
	}
	else
	{
		/*-< 无操作*/
	}

	/*为应用给输出的队列OutputDataQueue分配空间*/
	pRpStruct->OutputDataQueueSize = (pRpStruct->OutputSize + 4) * pRpStruct->MaxNumPerCycle * pRpStruct->MaxNumLink; /*-< 计算输出时应用给协议队列长度*/
	ret = QueueInitial(&pRpStruct->OutputDataQueue, pRpStruct->OutputDataQueueSize); /*-< 调用函数初始化输出时应用给协议队列,结果赋值给函数返回值*/
	if (ret == 0) /*-< 函数返回值是否失败*/
	{
		return ret; /*-< 返回函数返回值*/
	}
	else
	{
		/*-< 无操作*/
	}

	/*为应用给输入的队列OutnetQueueA分配空间*/
	pRpStruct->OutnetQueueSize = (pRpStruct->InputSize + 2 + 15) * pRpStruct->MaxNumPerCycle * pRpStruct->MaxNumLink; /*-< 计算输入时应用给协议队列1长度*/
	ret = QueueInitial(&pRpStruct->OutnetQueueA, pRpStruct->OutnetQueueSize); /*-< 调用函数初始化输入时应用给协议队列1,结果赋值给函数返回值*/
	if (ret == 0) /*-< 函数返回值是否失败*/
	{
		return ret; /*-< 返回函数返回值*/
	}
	else
	{
		/*-< 无操作*/
	}

	/*为应用给输入的队列OutnetQueueB分配空间*/
	pRpStruct->OutnetQueueSize = (pRpStruct->InputSize + 2 + 15) * pRpStruct->MaxNumPerCycle * pRpStruct->MaxNumLink; /*-< 计算输入时应用给协议队列2长度*/
	ret = QueueInitial(&pRpStruct->OutnetQueueB, pRpStruct->OutnetQueueSize); /*-< 调用函数初始化输入时应用给协议队列2,结果赋值给函数返回值*/
	if (ret == 0) /*-< 函数返回值是否失败*/
	{
		return ret; /*-< 返回函数返回值*/
	}
	else
	{
		/*-< 无操作*/
	}

	/*分配序列号缓冲表堆栈空间*/
	StackInitial(&pRpStruct->SnLnkStack, (UINT16)pRpStruct->MaxNumLink); /*-< 调用函数初始化链路堆栈*/

	/*分配最大链路节点数存储空间*/
	if (!Rp_init_SnStack(pRpStruct)) /*-< 调用初始化序列号缓冲链表堆栈函数*/
	{
		ret = 0; /*-< 设置函数返回值为失败*/
		return ret; /*-< 返回函数返回值*/
	}
	else
	{
		/*-< 无操作*/
	}

	pRpStruct->SnLinkhead = NULL; /*-< 设置链路堆栈顶为空*/

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

/***********************************************************************
 * 方法名   : RpLnkDelete
 * 功能描述 : 通过该函数，应用可以删除该设备名称的链路
 * 输入参数 : 
 *	参数名				类型							输入输出		描述
 *  --------------------------------------------------------------
 *	 devName     UINT16           IN  设备名称
 *   pdelDevSn   RP_INFO_STRU *   IN  冗余层统一结构
 * 返回值   : UINT8  1：正常返回  0：错误返回
 ***********************************************************************/

UINT8 RpLnkDelete(UINT16 devName,RP_INFO_STRU *pdelDevSn)
{
	UINT8 ret = 0;
    RpSNLINK_STRU *curIndex = NULL;
    RpSNLINK_STRU *preIndex = NULL;

	curIndex = pdelDevSn->SnLinkhead;
	while(curIndex != NULL)
	{
		if(curIndex->DestDevName == devName)
		{
			if(preIndex == NULL)
			{
				pdelDevSn -> SnLinkhead = curIndex->NextNode;
				curIndex->DestDevName = 0;
				curIndex->SnLink_Info.DestDevName = 0;
				RpMemSet((UINT8 *)curIndex->SnLink_Info.SnArray,sizeof(curIndex->SnLink_Info.SnArray),0);
				if( StackPush(&pdelDevSn->SnLnkStack,(STACK_DATA_TYPE_RP)curIndex) == 0)
				{
					ret = 0;
					return ret;
				}
				else
				{
					/*无操作*/    
				} 
			}/*if(上一个指针preIndex == NULL)*/         
			/*如果删除节点不是头节点*/
			else
			{
				preIndex->NextNode = curIndex->NextNode;
				curIndex->DestDevName = 0;
				curIndex->SnLink_Info.DestDevName = 0;
				RpMemSet((UINT8 *)curIndex->SnLink_Info.SnArray,sizeof(curIndex->SnLink_Info.SnArray),0);
				if( StackPush(&pdelDevSn->SnLnkStack,(STACK_DATA_TYPE_RP)curIndex) == 0)
				{
					ret = 0;
					return ret;
				}
				else
				{
					/*无操作*/    
				} 
			}
			
		}
		else
		{
            
		}
		preIndex = curIndex;
		curIndex = curIndex->NextNode;
	}
    ret = 1;
    return ret;
}


/**************************************************************************************
 *功能描述：
 *	释放协议在函数RpInit中分配的内存空间
 *  入口参数：
 * 	 RP_INFO_STRU * pRpStruct 	统一结构体
 *  返回值：
 *	 成功返回1，失败返回0
 ***************************************************************************************/
UINT8 RpFreeSpace(RP_INFO_STRU *pRpStruct)/* %RELAX<MISRA_8_10> */
{
	UINT8 ret = 1;

	if(pRpStruct->Buff_Rp != NULL)
	{
		free((void *)pRpStruct->Buff_Rp);
		pRpStruct->Buff_Rp = NULL;
	}
	else
	{
		/*无操作*/    
	}

	if(pRpStruct->RecordArray != NULL)
	{
		free((void *)pRpStruct->RecordArray);
		pRpStruct->RecordArray = NULL;
	}
	else
	{
		/*无操作*/    
	}

	if(pRpStruct->AppArray != NULL)
	{
		free((void *)pRpStruct->AppArray);
		pRpStruct->AppArray = NULL;
	}
	else
	{
		/*无操作*/    
	}

	if(pRpStruct->VarArray!= NULL)
	{
		free((void *)pRpStruct->VarArray);
		pRpStruct->VarArray= NULL;
	}
	else
	{
		/*无操作*/    
	}

	QueueElementFree(&pRpStruct->DataToApp);
	QueueElementFree(&pRpStruct->OutputDataQueue);
	QueueElementFree(&pRpStruct->OutnetQueueA);
	QueueElementFree(&pRpStruct->OutnetQueueB);

	StackFree(&pRpStruct->SnLnkStack);
	
	if(pRpStruct->pSnStack != NULL)
	{
		free((void *)pRpStruct->pSnStack);
		pRpStruct->pSnStack = NULL;
	}
	else
	{
		/*无操作*/    
	}

	pRpStruct->SnLinkhead = NULL;	   /*链表头结点置空*/

	return ret;
}

/**
 * @brief RpReceive RP输入处理
 * @param pRpStruct RP实例 取值范围:参考结构体RP_INFO_STRU
 * @return 0:失败 1:成功
 */
UINT8 RpReceive(RP_INFO_STRU* pRpStruct)/* %RELAX<MISRA_8_10> */
{
	/** 定义局部变量*/
	UINT16 Length; /*记录纯数据长度*/
	UINT16 LocalDevNameInFrame; /*本方类型ID*/
	UINT16 DestDevNameInFrame; /*对方类型ID*/
	UINT32 SnInFrame; /*序列号*/
	UINT8 len[10]; /*10字节长度数组*/
	UINT8 temp[10]; /*10字节临时数组*/
	UINT16 lenthofData; /*纯数据长度*/
	UINT16 lenthofRcvA = 0; /*收到A队列长度*/
	UINT16 lenthofRcvB = 0; /*收到B队列长度*/
	UINT8 ToBeContinue = 0; /*-< 设置继续执行标志为0 1 忽略此帧数据，直接处理下帧数据，0不忽略*/
	UINT8 QueueReadFlag; /*记录上次读取是红/蓝网中的哪个*/
	UINT8 QueueAvailable; /*红蓝网读取标识*/
	UINT8 RVQueueRead; /*队列读取返回值*/
	UINT8 RcvQueueReadLenth; /*收队列长度*/
	UINT8 i = 0; /*用于循环*/
	RpSNLINK_STRU* CurrentSnNode; /*序号缓存列表*/
	UINT8 ret; /*-< 设置函数返回值为0*/
	UINT32 QueueCnt; /*队列数量*/
	UINT8 fitFrameLen = 0u; /*-< 设置固定帧长度为0*/
	UINT32 oppHlhtId = 0u; /*对方互联互通ID*/
	UINT32 locHlhtId = 0u; /*本方互联互通ID*/
	UINT8 oppTypeIdArr[2] = { 0 }; /*对方类型ID字节数组*/

	QueueReadFlag = 0x55; /*-< 设置是否读标志为是*/
	RVQueueRead = 0xFF; /*-< 设置收队列标识为都不收*/
	QueueAvailable = 0; /*-< 清除队列可用标志*/
	CurrentSnNode = NULL; /*-< 设置序号缓存列表为空*/

	if (pRpStruct == NULL) /*-< 入参非空检查*/
	{
		ret = 0; /*-< 设置函数返回值为失败*/
		return ret; /*-< 返回函数返回值*/
	}
	else
	{
		/*-< 往后继续处理*/
	}

	ShortToChar(0, pRpStruct->RecordArray); /*-< 清零日志记录*/

#ifdef RP_RECORD_ERR_ASC
	PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "Cycle:\n");
	PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "LName:");
	PrintFileHex(pRpStruct->RecordArray, pRpStruct->RecordArraySize, &pRpStruct->LocalType, 1);
	PrintFileHex(pRpStruct->RecordArray, pRpStruct->RecordArraySize, &pRpStruct->LocalID, 1);
	PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "\n");
	PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "Rcv:\n");
#endif
#ifdef RP_RECORD_SIMPLIFY_BIN
	/*新周期开始标志*/
	PrintRecArrayByte(pRpStruct->RecordArray, pRpStruct->RecordArraySize, 0xf0); /*-< 记录周期开始标识日志*/
	/*输入单元标识*/
	PrintRecArrayByte(pRpStruct->RecordArray, pRpStruct->RecordArraySize, 0xf2); /*-< 记录输入处理日志*/
	/*本地Type和ID*/
	PrintRecArrayByte(pRpStruct->RecordArray, pRpStruct->RecordArraySize, pRpStruct->LocalType); /*-< 记录本方类型日志*/
	PrintRecArrayByte(pRpStruct->RecordArray, pRpStruct->RecordArraySize, pRpStruct->LocalID); /*-< 记录本方ID日志*/
#endif


	for (i = 0; i < 10; i++) /*-< 当前循环下标是否小于10*/
	{
		len[i] = 0; /*-< 设置长度值为0*/
	}

	if (INTERFACE_TYPE_FOUR == pRpStruct->interfaceType) /*-< 接口类型是否发送/接收标识为4字节*/
	{
		fitFrameLen = 15u; /*-< 设置帧长度为15*/
	}
	else
	{
		fitFrameLen = 11u; /*-< 设置帧长度为11*/
	}

	while (1) /*-< 是否继续循环*/
	{
		QueueAvailable = 0; /*-< 设置队列不可用*/

#ifdef RP_RECORD_ERR_ASC	
		PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "IN:\n");
#endif		
		/*判断红网是否有数*/
		if (QueueScan(5, len, &pRpStruct->OutnetQueueA) != 0) /*-< A队列是否能扫描出长度*/
		{
			lenthofRcvA = ShortFromChar(len); /*-< 得到解析帧的长度*/
			lenthofData = ShortFromChar(&len[3]); /*-< 得到解析数据的长度*/

			if ((lenthofRcvA > (pRpStruct->InputSize + fitFrameLen)) || (lenthofRcvA != (lenthofData + fitFrameLen))) /*-< 长度是否非法*/
			{
				/*接收到的数据超长,处理机制是从队列中读出这帧超长的数据，读完后继续下一帧的读取*/
#ifdef RP_RECORD_ERR_ASC
				PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, " W:");
				PrintFileU16Hex(pRpStruct->RecordArray, pRpStruct->RecordArraySize, RP_WARN | RP_RECEIVE | RP_ERROR_NULL | RP_QUEUE_INTEGRITY_R);
				PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "\n");
#endif
#ifdef RP_RECORD_SIMPLIFY_BIN
				/*记录错误*/
				PrintRecArray2ByteB(pRpStruct->RecordArray, pRpStruct->RecordArraySize, RP_WARN | RP_RECEIVE | RP_ERROR_NULL | RP_QUEUE_INTEGRITY_R); /*-< 记录A队列长度非法日志*/
#endif
				gRpErrorInfo |= RP_WARN_RECEIVE_RP_QUEUE_INTEGRITY_R; /*-< 记录错误码*/


				/*将lenthofRcvA+2个字节数据从队列中读出，丢弃，继续下次读取*/
				QueueElementDiscard((UINT16)(lenthofRcvA + 2), &pRpStruct->OutnetQueueA); /*-< 调用函数删除队列中此长度数据*/

				ToBeContinue = 1; /*-< 设置是否继续循环标志为否*/
			}
			else
			{
				QueueAvailable |= 0x0F; /*-< 设置A队列可用标志*/
			}
		}
		else
		{
			/*-< 无操作*/
		}

		/*判断蓝网是否有数*/
		if (QueueScan(5, len, &pRpStruct->OutnetQueueB) != 0) /*-< B队列是否能扫描出长度*/
		{
			lenthofRcvB = ShortFromChar(len); /*-< 得到解析帧的长度*/
			lenthofData = ShortFromChar(&len[3]); /*-< 得到解析数据的长度*/

			if ((lenthofRcvB > (pRpStruct->InputSize + fitFrameLen)) || (lenthofRcvB != (lenthofData + fitFrameLen))) /*-< 长度是否非法*/
			{
				/*记录记录接收到的数据超长*/
#ifdef RP_RECORD_ERR_ASC
				PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, " W:");
				PrintFileU16Hex(pRpStruct->RecordArray, pRpStruct->RecordArraySize, RP_WARN | RP_RECEIVE | RP_ERROR_NULL | RP_QUEUE_INTEGRITY_B);
				PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "\n");
#endif				
#ifdef RP_RECORD_SIMPLIFY_BIN
				/*记录错误*/
				PrintRecArray2ByteB(pRpStruct->RecordArray, pRpStruct->RecordArraySize, RP_WARN | RP_RECEIVE | RP_ERROR_NULL | RP_QUEUE_INTEGRITY_B); /*-< 记录B队列长度非法日志*/
#endif				
				gRpErrorInfo |= RP_WARN_RECEIVE_RP_QUEUE_INTEGRITY_B; /*-< 记录错误码*/


				/*将lenthofRcvB+2个字节数据从队列中读出，丢弃，继续下次读取*/
				QueueElementDiscard((UINT16)(lenthofRcvB + 2), &pRpStruct->OutnetQueueB); /*-< 调用函数删除队列中此长度数据*/

				ToBeContinue = 1; /*-< 设置是否继续循环标志为否*/
			}
			else
			{
				QueueAvailable |= 0xF0; /*-< 设置A队列可用标志*/
			}

		}
		else
		{
			/*-< 无操作*/
		}

		if (ToBeContinue == 0) /*-< 是否继续循环标志是否为是*/
		{
			if (QueueAvailable == 0xFF) /*-< 是否两个队列都可用*/
			{
				if (QueueReadFlag == 0x55) /*-< 上次读的队列是否A*/
				{
					/*因为帧头添加了两个字节，为保持源程序不变，先读出两个字节，丢弃*/
					RcvQueueReadLenth = QueueRead(2, pRpStruct->Buff_Rp, &pRpStruct->OutnetQueueB); /*-< 调用函数读取B队列2字节长度*/
					if (RcvQueueReadLenth != 1) /*-< 调用函数是否失败*/
					{
#ifdef RP_RECORD_ERR_ASC
						PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, " W:");
						PrintFileU16Hex(pRpStruct->RecordArray, pRpStruct->RecordArraySize, RP_WARN | RP_RECEIVE | RP_ERROR_NULL | RP_QUEUE_READ);
						PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, " \n");
#endif					
#ifdef RP_RECORD_SIMPLIFY_BIN
						/*记录错误*/
						PrintRecArray2ByteB(pRpStruct->RecordArray, pRpStruct->RecordArraySize, RP_WARN | RP_RECEIVE | RP_ERROR_NULL | RP_QUEUE_READ); /*-< 记录读B队列长度失败日志*/
#endif	
						gRpErrorInfo |= RP_WARN_RECEIVE_RP_QUEUE_READ; /*-< 设置错误码*/

						break; /*-< 退出遍历*/
					}

					RVQueueRead = QueueRead((UINT16)(lenthofRcvB), pRpStruct->Buff_Rp, &pRpStruct->OutnetQueueB); /*-< 调用函数读取B队列长度数据*/
					QueueReadFlag = 0xAA; /*-< 设置次读的队列为B*/

#ifdef RP_RECORD_ERR_ASC	
					PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "BNet:");
#endif	
#ifdef RP_RECORD_SIMPLIFY_BIN
					/*一帧消息起始标识和消息来源*/
					PrintRecArrayByte(pRpStruct->RecordArray, pRpStruct->RecordArraySize, 0x40 | 0x0A); /*-< 记录读B队列标志日志*/
#endif  
				}
				else
				{
					/*因为帧头添加了两个字节，为保持源程序不变，先读出两个字节，丢弃*/
					RcvQueueReadLenth = QueueRead(2, pRpStruct->Buff_Rp, &pRpStruct->OutnetQueueA); /*-< 调用函数读取A队列2字节长度*/
					if (RcvQueueReadLenth != 1) /*-< 调用函数是否失败*/
					{
#ifdef RP_RECORD_ERR_ASC
						PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, " W:");
						PrintFileU16Hex(pRpStruct->RecordArray, pRpStruct->RecordArraySize, RP_WARN | RP_RECEIVE | RP_ERROR_NULL | RP_QUEUE_READ);
						PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, " \n");
#endif						
#ifdef RP_RECORD_SIMPLIFY_BIN
						/*记录错误*/
						PrintRecArray2ByteB(pRpStruct->RecordArray, pRpStruct->RecordArraySize, RP_WARN | RP_RECEIVE | RP_ERROR_NULL | RP_QUEUE_READ); /*-< 记录读A队列长度失败日志*/
#endif	
						gRpErrorInfo |= RP_WARN_RECEIVE_RP_QUEUE_READ; /*-< 设置错误码*/

						break; /*-< 退出遍历*/
					}

					RVQueueRead = QueueRead((UINT16)(lenthofRcvA), pRpStruct->Buff_Rp, &pRpStruct->OutnetQueueA); /*-< 调用函数读取A队列长度数据*/
					QueueReadFlag = 0x55; /*-< 设置次读的队列为A*/
#ifdef RP_RECORD_ERR_ASC	
					PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "RNet:");
#endif						
#ifdef RP_RECORD_SIMPLIFY_BIN
					/*一帧消息起始标识和消息来源*/
					PrintRecArrayByte(pRpStruct->RecordArray, pRpStruct->RecordArraySize, 0x40 | 0x05); /*-< 记录读A队列标志日志*/
#endif  
				}
			}
			else if (QueueAvailable == 0x0F) /*-< 是否A队列都可用*/
			{
				/*因为帧头添加了两个字节，为保持源程序不变，先读出两个字节，丢弃*/
				RcvQueueReadLenth = QueueRead(2, pRpStruct->Buff_Rp, &pRpStruct->OutnetQueueA); /*-< 调用函数读取A队列2字节长度*/
				if (RcvQueueReadLenth != 1) /*-< 调用函数是否失败*/
				{
#ifdef RP_RECORD_ERR_ASC
					PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, " W:");
					PrintFileU16Hex(pRpStruct->RecordArray, pRpStruct->RecordArraySize, RP_WARN | RP_RECEIVE | RP_ERROR_NULL | RP_QUEUE_READ);
					PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, " \n");
#endif				
#ifdef RP_RECORD_SIMPLIFY_BIN
					/*记录错误*/
					PrintRecArray2ByteB(pRpStruct->RecordArray, pRpStruct->RecordArraySize, RP_WARN | RP_RECEIVE | RP_ERROR_NULL | RP_QUEUE_READ); /*-< 记录读A队列长度失败日志*/
#endif	
					gRpErrorInfo |= RP_WARN_RECEIVE_RP_QUEUE_READ; /*-< 设置错误码*/

					break; /*-< 退出遍历*/
				}

				RVQueueRead = QueueRead((UINT16)(lenthofRcvA), pRpStruct->Buff_Rp, &pRpStruct->OutnetQueueA); /*-< 记录读A队列标志日志*/
				QueueReadFlag = 0x55; /*-< 设置次读的队列为A*/
#ifdef RP_RECORD_ERR_ASC	
				PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "RNet:");
#endif					
#ifdef RP_RECORD_SIMPLIFY_BIN
				/*一帧消息起始标识和消息来源*/
				PrintRecArrayByte(pRpStruct->RecordArray, pRpStruct->RecordArraySize, 0x40 | 0x05); /*-< 记录读A队列标志日志*/
#endif  				           
			}
			else if (QueueAvailable == 0xF0) /*-< 是否B队列都可用*/
			{
				/*因为帧头添加了两个字节，为保持源程序不变，先读出两个字节，丢弃*/
				RcvQueueReadLenth = QueueRead(2, pRpStruct->Buff_Rp, &pRpStruct->OutnetQueueB); /*-< 调用函数读取B队列2字节长度*/
				if (RcvQueueReadLenth != 1) /*-< 调用函数是否失败*/
				{
#ifdef RP_RECORD_ERR_ASC
					PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, " W:");
					PrintFileU16Hex(pRpStruct->RecordArray, pRpStruct->RecordArraySize, RP_WARN | RP_RECEIVE | RP_ERROR_NULL | RP_QUEUE_READ);
					PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, " \n");
#endif					
#ifdef RP_RECORD_SIMPLIFY_BIN
					/*记录错误*/
					PrintRecArray2ByteB(pRpStruct->RecordArray, pRpStruct->RecordArraySize, RP_WARN | RP_RECEIVE | RP_ERROR_NULL | RP_QUEUE_READ); /*-< 记录读B队列长度失败日志*/
#endif	
					gRpErrorInfo |= RP_WARN_RECEIVE_RP_QUEUE_READ; /*-< 设置错误码*/

					break; /*-< 退出遍历*/
				}

				RVQueueRead = QueueRead((UINT16)(lenthofRcvB), pRpStruct->Buff_Rp, &pRpStruct->OutnetQueueB); /*-< 调用函数读取B队列长度数据*/
				QueueReadFlag = 0xAA; /*-< 设置次读的队列为B*/
#ifdef RP_RECORD_ERR_ASC	
				PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "BNet:");
#endif	
#ifdef RP_RECORD_SIMPLIFY_BIN
				/*一帧消息起始标识和消息来源*/
				PrintRecArrayByte(pRpStruct->RecordArray, pRpStruct->RecordArraySize, 0x40 | 0x0A); /*-< 记录读B队列标志日志*/
#endif  	

			}
			else
			{
				break; /*-< 退出遍历*/
			}

			if (RVQueueRead == 1) /*-< 判断是否可以读出完整帧*/
			{
				if (pRpStruct->Buff_Rp[0] != 0xFF) /*-< 是否非RP帧标识*/
				{
#ifdef RP_RECORD_ERR_ASC
					PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, " W:");
					PrintFileU16Hex(pRpStruct->RecordArray, pRpStruct->RecordArraySize, RP_WARN | RP_RECEIVE | RP_EDITION_ILLEGAL | RP_ERROR_NULL);
					PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, " \n");
#endif				
#ifdef RP_RECORD_SIMPLIFY_BIN
					/*记录错误*/
					PrintRecArray2ByteB(pRpStruct->RecordArray, pRpStruct->RecordArraySize, RP_WARN | RP_RECEIVE | RP_EDITION_ILLEGAL | RP_ERROR_NULL); /*-< 记录非RP帧标识日志*/
#endif	
					gRpErrorInfo |= RP_WARN_RECEIVE_RP_EDITION_ILLEGAL; /*-< 设置错误码*/

				}
				else
				{
					Length = ShortFromChar(&pRpStruct->Buff_Rp[1]); /*-< 得到帧长度*/

					if (INTERFACE_TYPE_FOUR == pRpStruct->interfaceType) /*-< 接口类型是否发送/接收标识为4字节*/
					{
						oppHlhtId = LongFromChar(&pRpStruct->Buff_Rp[3]); /*-< 得到对方互联互通ID*/
						locHlhtId = LongFromChar(&pRpStruct->Buff_Rp[7]); /*-< 得到本方互联互通ID*/
						DestDevNameInFrame = GetDevTypeId(oppHlhtId); /*-< 得到对方设备类型ID*/
						LocalDevNameInFrame = GetDevTypeId(locHlhtId); /*-< 得到本方设备类型ID*/

						SnInFrame = LongFromChar(&pRpStruct->Buff_Rp[12]); /*-< 得到数据序列号*/
					}
					else
					{
						DestDevNameInFrame = ShortFromChar(&pRpStruct->Buff_Rp[3]); /*-< 得到对方设备类型ID*/
						LocalDevNameInFrame = ShortFromChar(&pRpStruct->Buff_Rp[5]); /*-< 得到本方设备类型ID*/

						SnInFrame = LongFromChar(&pRpStruct->Buff_Rp[7]); /*-< 得到数据序列号*/
					}
					ShortToChar(DestDevNameInFrame, &oppTypeIdArr[0]); /*-< 设置对方类型ID到字节数组*/

					if (LocalDevNameInFrame != pRpStruct->LocalType * 0x100 + pRpStruct->LocalID) /*-< 收数据是否发本方*/
					{
#ifdef RP_RECORD_ERR_ASC
						PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, " W:");
						PrintFileU16Hex(pRpStruct->RecordArray, pRpStruct->RecordArraySize, RP_WARN | RP_RECEIVE | RP_DESTNAME_ERR | RP_ERROR_NULL);
						PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, " \n");
#endif		
#ifdef RP_RECORD_SIMPLIFY_BIN
						/*记录错误*/
						PrintRecArray2ByteB(pRpStruct->RecordArray, pRpStruct->RecordArraySize, RP_WARN | RP_RECEIVE | RP_DESTNAME_ERR | RP_ERROR_NULL); /*-< 记录收数据非发本方日志*/
#endif	
						gRpErrorInfo |= RP_WARN_RECEIVE_RP_DESTNAME_ERR; /*-< 设置错误码*/

					}
					else
					{
#ifdef RP_RECORD_ERR_ASC	
						PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "Len:");
						PrintFileU16Hex(pRpStruct->RecordArray, pRpStruct->RecordArraySize, Length);
						PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "\n");
						PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "DN:");
						PrintFileU16Hex(pRpStruct->RecordArray, pRpStruct->RecordArraySize, DestDevNameInFrame);
						PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "\n");
						PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "LN:");
						PrintFileU16Hex(pRpStruct->RecordArray, pRpStruct->RecordArraySize, LocalDevNameInFrame);
						PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "\n");
						PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "Sn:");
						PrintFileU32Hex(pRpStruct->RecordArray, pRpStruct->RecordArraySize, SnInFrame);
						PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "\n");
						PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "Data:");
						PrintFileHex(pRpStruct->RecordArray, pRpStruct->RecordArraySize, &pRpStruct->Buff_Rp[fitFrameLen], 2);
						PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "\n");
#endif						
#ifdef RP_RECORD_SIMPLIFY_BIN
						/*记录接收方对象类型ID*/
						PrintRecArray2ByteB(pRpStruct->RecordArray, pRpStruct->RecordArraySize, LocalDevNameInFrame); /*-< 记录本方类型ID日志*/
						/*记录发送方对象类型ID*/
						PrintRecArray2ByteB(pRpStruct->RecordArray, pRpStruct->RecordArraySize, DestDevNameInFrame); /*-< 记录对方类型ID日志*/
						/*记录发送方对象Sn*/
						PrintRecArray4ByteB(pRpStruct->RecordArray, pRpStruct->RecordArraySize, SnInFrame); /*-< 记录序列号日志*/
						/*记录纯应用数据长度*/
						PrintRecArray2ByteB(pRpStruct->RecordArray, pRpStruct->RecordArraySize, Length); /*-< 记录数据长度日志*/
#endif
						CurrentSnNode = Rp_SearchSnLnk(DestDevNameInFrame, pRpStruct); /*-< 调用函数查询此设备通信链路*/
						if (CurrentSnNode == NULL) /*-< 调用函数是否失败*/
						{
							CurrentSnNode = Rp_InsertLnk(DestDevNameInFrame, pRpStruct); /*-< 调用函数插入链路*/
							if (CurrentSnNode != NULL) /*-< 调用函数是否成功*/
							{
								if (SnInFrame != 0x00) /*-< 序号是否非0*/
								{
#ifdef RP_RECORD_ERR_ASC	
									PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "W:");
									PrintFileU16Hex(pRpStruct->RecordArray, pRpStruct->RecordArraySize, RP_WARN | RP_RECEIVE | RP_SN_ILLEGAL | RP_ERROR_NULL);
									PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "\n");
#endif									
#ifdef RP_RECORD_SIMPLIFY_BIN
									/*记录错误*/
									PrintRecArray2ByteB(pRpStruct->RecordArray, pRpStruct->RecordArraySize, RP_WARN | RP_RECEIVE | RP_SN_ILLEGAL | RP_ERROR_NULL); /*-< 记录收数据日志*/
#endif	
									gRpErrorInfo |= RP_WARN_RECEIVE_RP_SN_ILLEGAL; /*-< 设置错误码*/


									CurrentSnNode->SnLink_Info.SnArray[CurrentSnNode->SnLink_Info.SnArrayIndex++] = SnInFrame; /*-< 更新收序号到链路序号数组中*/
									QueueCnt = QueueStatus(&pRpStruct->DataToApp); /*-< 得到输入协议给应用队列空间长度*/
									QueueCnt = pRpStruct->DataToApp.qsize - QueueCnt; /*-< 得到输入协议给应用队列空间剩余长度*/
									if (QueueCnt >= (UINT32)(2 + 2 + Length)) /*-< 得到输入协议给应用队列空间剩余长度是否够用*/
									{
										ShortToChar((UINT16)(Length + 2), temp); /*-< 设置长度值到长度字节数组*/
										(void)QueueWrite(2, temp, &pRpStruct->DataToApp); /*-< 写长度字节数组到输入协议给应用队列*/

										(void)QueueWrite(2, &oppTypeIdArr[0], &pRpStruct->DataToApp); /*-< 写设备类型ID字节数组到输入协议给应用队列*/

										(void)QueueWrite(Length, &pRpStruct->Buff_Rp[fitFrameLen], &pRpStruct->DataToApp); /*-< 写应用数据到输入协议给应用队列*/

#ifdef RP_RECORD_ERR_ASC	
										PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "OUT:\n");
										PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "Len:");
										PrintFileU16Hex(pRpStruct->RecordArray, pRpStruct->RecordArraySize, Length);
										PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "\n");
										PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "SrcNm:");
										PrintFileHex(pRpStruct->RecordArray, pRpStruct->RecordArraySize, &pRpStruct->Buff_Rp[3], 2);
										PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "\n");
										PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "Data:");
										PrintFileHex(pRpStruct->RecordArray, pRpStruct->RecordArraySize, &pRpStruct->Buff_Rp[fitFrameLen], 2);
										PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "\n");
#endif
#ifdef RP_RECORD_SIMPLIFY_BIN
										/*记录向队列写数据的相关信息，首先是起始标志*/
										PrintRecArrayByte(pRpStruct->RecordArray, pRpStruct->RecordArraySize, 0x80 | 0x00); /*-< 记录写应用数据标志日志*/
										/*记录发送方对象类型ID*/
										PrintRecArray2ByteB(pRpStruct->RecordArray, pRpStruct->RecordArraySize, DestDevNameInFrame); /*-< 记录对方类型ID日志*/
										/*记录纯应用数据长度*/
										PrintRecArray2ByteB(pRpStruct->RecordArray, pRpStruct->RecordArraySize, Length); /*-< 记录数据长度日志*/
#endif
									}
									else
									{
#ifdef RP_RECORD_ERR_ASC	
										PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "W:");
										PrintFileU16Hex(pRpStruct->RecordArray, pRpStruct->RecordArraySize, RP_WARN | RP_RECEIVE | RP_QUEUE_OVLOAD | RP_ERROR_NULL);
										PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "\n");
#endif									
#ifdef RP_RECORD_SIMPLIFY_BIN
										/*记录错误*/
										PrintRecArray2ByteB(pRpStruct->RecordArray, pRpStruct->RecordArraySize, RP_WARN | RP_RECEIVE | RP_QUEUE_OVLOAD | RP_ERROR_NULL); /*-< 记录队列空间不够日志*/
#endif	
										gRpErrorInfo |= RP_WARN_RECEIVE_RP_QUEUE_OVLOAD; /*-< 设置错误码*/

									}
								}
								else
								{
									/*-< 丢弃此帧*/
								}
							}
							else
							{
#ifdef RP_RECORD_ERR_ASC	
								PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "E:");
								PrintFileU16Hex(pRpStruct->RecordArray, pRpStruct->RecordArraySize, RP_ERR | RP_RECEIVE | RP_ERROR_NULL | RP_LNK_POP);
								PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "\n");
#endif								
#ifdef RP_RECORD_SIMPLIFY_BIN
								/*记录错误*/
								PrintRecArray2ByteB(pRpStruct->RecordArray, pRpStruct->RecordArraySize, RP_ERR | RP_RECEIVE | RP_ERROR_NULL | RP_LNK_POP); /*-< 记录插入链路失败日志*/
#endif	
								gRpErrorInfo |= RP_ERR_RECEIVE_RP_LNK_POP; /*-< 设置错误码*/

							}
						}
						else
						{
							if (SnInFrame == 0) /*-< 序号是否为0*/
							{
								/*该节点的序列号数组，清0*/
								for (i = 0; i < 15; i++) /*-< 下标是否小于15*/
								{
									CurrentSnNode->SnLink_Info.SnArray[i] = 0; /*-< 设置序号数组下标的序号值为0*/
								}
								CurrentSnNode->SnLink_Info.SnArrayIndex = 0; /*-< 设置序号数组下标为0*/

							}
							else
							{
								ret = Rp_IsSnExit(SnInFrame, CurrentSnNode); /*-< 调用判断序列号在缓冲数组里是否已经存储函数*/
								if (ret == 1) /*-< 设置函数是否失败*/
								{
									/*-< 丢弃此帧*/
								}
								else
								{
									if (CurrentSnNode->SnLink_Info.SnArrayIndex > 14) /*-< 序号数组下标是否大于14*/
									{
										CurrentSnNode->SnLink_Info.SnArrayIndex = 0; /*-< 设置序号数组下标为0*/
									}
									CurrentSnNode->SnLink_Info.SnArray[CurrentSnNode->SnLink_Info.SnArrayIndex++] = SnInFrame; /*-< 设置序号数组当前下标的序号为当前序号*/
									QueueCnt = QueueStatus(&pRpStruct->DataToApp); /*-< 得到输入协议给应用队列空间长度*/
									QueueCnt = pRpStruct->DataToApp.qsize - QueueCnt; /*-< 得到输入协议给应用队列空间剩余长度*/
									if (QueueCnt >= (UINT32)(2 + 2 + Length)) /*-< 得到输入协议给应用队列空间剩余长度是否够用*/
									{
										ShortToChar((UINT16)(Length + 2), temp); /*-< 设置长度值到长度字节数组*/
										(void)QueueWrite(2, temp, &pRpStruct->DataToApp); /*-< 写长度字节数组到输入协议给应用队列*/

										(void)QueueWrite(2, &oppTypeIdArr[0], &pRpStruct->DataToApp); /*-< 写设备类型ID字节数组到输入协议给应用队列*/

										(void)QueueWrite(Length, &pRpStruct->Buff_Rp[fitFrameLen], &pRpStruct->DataToApp); /*-< 写应用数据到输入协议给应用队列*/

#ifdef RP_RECORD_ERR_ASC	
										PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "OUT:\n");
										PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "Len:");
										PrintFileU16Hex(pRpStruct->RecordArray, pRpStruct->RecordArraySize, Length);
										PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "\n");
										PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "SrcNm:");
										PrintFileHex(pRpStruct->RecordArray, pRpStruct->RecordArraySize, &pRpStruct->Buff_Rp[3], 2);
										PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "\n");
										PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "Data:");
										PrintFileHex(pRpStruct->RecordArray, pRpStruct->RecordArraySize, &pRpStruct->Buff_Rp[fitFrameLen], 2);
										PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "\n");
#endif										
#ifdef RP_RECORD_SIMPLIFY_BIN
										/*记录向队列写数据的相关信息，首先是起始标志*/
										PrintRecArrayByte(pRpStruct->RecordArray, pRpStruct->RecordArraySize, 0x80 | 0x00); /*-< 记录写应用数据标志日志*/
										/*记录发送方对象类型ID*/
										PrintRecArray2ByteB(pRpStruct->RecordArray, pRpStruct->RecordArraySize, DestDevNameInFrame); /*-< 记录对方类型ID日志*/
										/*记录纯应用数据长度*/
										PrintRecArray2ByteB(pRpStruct->RecordArray, pRpStruct->RecordArraySize, Length); /*-< 记录数据长度日志*/
#endif
									}
									else
									{
#ifdef RP_RECORD_ERR_ASC	
										PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "W:");
										PrintFileU16Hex(pRpStruct->RecordArray, pRpStruct->RecordArraySize, RP_WARN | RP_RECEIVE | RP_QUEUE_OVLOAD | RP_ERROR_NULL);
										PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "\n");
#endif										
#ifdef RP_RECORD_SIMPLIFY_BIN
										/*记录错误*/
										PrintRecArray2ByteB(pRpStruct->RecordArray, pRpStruct->RecordArraySize, RP_WARN | RP_RECEIVE | RP_QUEUE_OVLOAD | RP_ERROR_NULL); /*-< 记录队列空间不够日志*/
#endif	
										gRpErrorInfo |= RP_WARN_RECEIVE_RP_QUEUE_OVLOAD; /*-< 设置错误码*/

									}
								}
							}
						}
					}
				}
			}
			else
			{
#ifdef RP_RECORD_ERR_ASC	
				PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "W:");
				PrintFileU16Hex(pRpStruct->RecordArray, pRpStruct->RecordArraySize, RP_WARN | RP_RECEIVE | RP_ERROR_NULL | RP_QUEUE_READ);
				PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "\n");
#endif			
#ifdef RP_RECORD_SIMPLIFY_BIN
				/*记录错误*/
				PrintRecArray2ByteB(pRpStruct->RecordArray, pRpStruct->RecordArraySize, RP_WARN | RP_RECEIVE | RP_ERROR_NULL | RP_QUEUE_READ); /*-< 记录队列空间不够日志*/
#endif	
				gRpErrorInfo |= RP_WARN_RECEIVE_RP_QUEUE_READ; /*-< 设置错误码*/

				break; /*-< 退出遍历*/
			}
		}
		else
		{
			ToBeContinue = 0; /*-< 设置继续循环标志是否为是*/
		}
	}

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

/**
 * @brief RpOutput RP输出处理
 * @param pRpStruct RP实例 取值范围:参考结构体RP_INFO_STRU
 * @return 0:失败 1:成功
 */
UINT8 RpOutput(RP_INFO_STRU* pRpStruct)/* %RELAX<MISRA_8_10> */
{
	/** 定义局部变量*/
	UINT32 QueueLength; /*队列长度*/
	UINT16 Length; /*数据长度*/
	UINT16 DestDevNameInFrame; /*对方设备类型ID*/
	UINT16 LocalDevName; /*本方设备类型ID*/
	RpSNLINK_STRU* CurrentSnLink; /*在写AppArray数组过程中，指向操作节点*/
	RpSNLINK_STRU* CurNumLink;  /*在写VarArray数组过程中，指向操作节点*/
	UINT16 i = 0; /*用于循环*/
	UINT16 j = 0; /*用于循环*/
	UINT16 NumOfLink = 0; /*链路数*/
	UINT16 AppArray_Len = 0; /*AppAarry数组已存数据长度*/
	UINT16 AppArray_Temp = 0; /*应用数据临时*/
	UINT8 ret; /*-< 设置函数返回值为失败*/
	UINT8 RpGetLnkInfoRet; /*获取链路返回值*/
	UINT16 locDevName = 0; /*本方类型ID*/
	UINT16 destDevName = 0; /*对方类型ID*/
	UINT8 protclType = 0; /*协议类型*/
	UINT8 outPutDstTypeIdIdx = 0u; /*-< 目的类型ID在输出数据位置*/
	UINT8 outPutSnIdx = 0u; /*-< 序号在输出数据位置*/
	UINT8 outPutTextIdx = 0u; /*-< 应用数据在输出数据位置*/
	UINT8 fitFrameLen = 0u; /*-< 固定帧长度*/
	UINT32 oppHlhtId = 0u; /*对方互联互通ID*/
	UINT32 locHlhtId = 0u; /*本方互联互通ID*/

	if (pRpStruct == NULL) /*-< 输入参数是否非空*/
	{
		ret = 0;/*-< 设置函数返回值为失败*/
		return ret; /*-< 返回函数返回值*/
	}
	else
	{
		/*-< 往后继续处理*/
	}

#ifdef RP_RECORD_ERR_ASC
	PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "Output:\n");
#endif
#ifdef RP_RECORD_SIMPLIFY_BIN
	/*输出单元标识*/
	PrintRecArrayByte(pRpStruct->RecordArray, pRpStruct->RecordArraySize, 0xf3); /*-< 记录输出处理标识日志*/
	/*本地Type和ID*/
	PrintRecArrayByte(pRpStruct->RecordArray, pRpStruct->RecordArraySize, pRpStruct->LocalType); /*-< 记录本方类型日志*/
	PrintRecArrayByte(pRpStruct->RecordArray, pRpStruct->RecordArraySize, pRpStruct->LocalID); /*-< 记录本方ID日志*/
#endif
	/*清空输出到应用的接口数组*/
	ShortToChar(0, pRpStruct->AppArray); /*-< 清零应用数据*/

	if (INTERFACE_TYPE_FOUR == pRpStruct->interfaceType) /*-< 接口类型是否发送/接收标识为4字节*/
	{
		outPutDstTypeIdIdx = OUTPUT_LOC_TYPEID + 4u; /*-< 设置目的类型ID在输出数据位置*/
		outPutSnIdx = outPutDstTypeIdIdx + 4u; /*-< 设置序号在输出数据位置*/
		fitFrameLen = 15u; /*-< 设置固定帧长度*/
	}
	else
	{
		outPutDstTypeIdIdx = OUTPUT_LOC_TYPEID + 2u; /*-< 设置目的类型ID在输出数据位置*/
		outPutSnIdx = outPutDstTypeIdIdx + 2u; /*-< 设置序号在输出数据位置*/
		fitFrameLen = 11u; /*-< 设置固定帧长度*/
	}
	outPutTextIdx = outPutSnIdx + 4u; /*-< 设置应用数据在输出数据位置位置*/


	QueueLength = QueueStatus(&pRpStruct->OutputDataQueue); /*-< 调用函数得到输出队列状态*/
#ifdef RP_RECORD_SIMPLIFY_BIN
	/*应用发送数据队列总长度*/
	PrintRecArray4ByteB(pRpStruct->RecordArray, pRpStruct->RecordArraySize, QueueLength); /*-< 记录长度日志*/
#endif
	while (QueueLength > 2) /*-< 队列是否有数*/
	{
		if (QueueRead(2, pRpStruct->Buff_Rp, &pRpStruct->OutputDataQueue)) /*-< 是否读到数据*/
		{
			Length = ShortFromChar(pRpStruct->Buff_Rp); /*-< 得到数据长度*/

			if (Length > pRpStruct->OutputSize + 2) /*-< 数据长度是否非法*/
			{
#ifdef RP_RECORD_ERR_ASC
				PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "W:");
				PrintFileU16Hex(pRpStruct->RecordArray, pRpStruct->RecordArraySize, RP_WARN | RP_OUTPUT | RP_ERROR_NULL | RP_QUEUE_OVERLONG);
				PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "\n");
#endif			
#ifdef RP_RECORD_SIMPLIFY_BIN
				/*记录错误*/
				PrintRecArray2ByteB(pRpStruct->RecordArray, pRpStruct->RecordArraySize, RP_WARN | RP_OUTPUT | RP_ERROR_NULL | RP_QUEUE_OVERLONG); /*-< 记录数据非法日志*/
#endif
				gRpErrorInfo |= RP_WARN_RECEIVE_RP_QUEUE_OVLOAD; /*-< 设置错误码*/


				/*将Length个字节数据从队列中读出，丢弃，继续下次读取*/
				QueueElementDiscard(Length, &pRpStruct->OutputDataQueue); /*-< 调用函数删除长度数据*/

			}
			else if ((UINT32)(Length + 2) > QueueLength) /*-< 数据长度是否超出队列长度*/
			{
#ifdef RP_RECORD_ERR_ASC
				PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "W:");
				PrintFileU16Hex(pRpStruct->RecordArray, pRpStruct->RecordArraySize, RP_WARN | RP_OUTPUT | RP_ERROR_NULL | RP_QUEUE_INTEGRITY);
				PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "\n");
#endif			
#ifdef RP_RECORD_SIMPLIFY_BIN
				/*记录错误*/
				PrintRecArray2ByteB(pRpStruct->RecordArray, pRpStruct->RecordArraySize, RP_WARN | RP_OUTPUT | RP_ERROR_NULL | RP_QUEUE_INTEGRITY); /*-< 记录超出队列长度日志*/
#endif
				gRpErrorInfo |= RP_WARN_OUTPUT_RP_QUEUE_INTEGRITY; /*-< 设置错误码*/

				break; /*-< 退出遍历*/
			}
			else
			{
				if (QueueRead(Length, pRpStruct->Buff_Rp, &pRpStruct->OutputDataQueue)) /*-< 是否能读到数据*/
				{
					DestDevNameInFrame = ShortFromChar(pRpStruct->Buff_Rp); /*-< 得到对方类型ID*/
					LocalDevName = pRpStruct->LocalType * 0x100 + pRpStruct->LocalID; /*-< 得到本方类型ID*/
					oppHlhtId = GetHlhtId(DestDevNameInFrame); /*-< 获取对方互联互通ID*/
					locHlhtId = GetHlhtId(LocalDevName); /*-< 获取对方互联互通ID*/

#ifdef RP_RECORD_ERR_ASC
					PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "IN:\n");
					PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "Len:");
					PrintFileU16Hex(pRpStruct->RecordArray, pRpStruct->RecordArraySize, (UINT16)(Length - 2));
					PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "  ");
					PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "DstNm:");
					PrintFileU16Hex(pRpStruct->RecordArray, pRpStruct->RecordArraySize, DestDevNameInFrame);
					PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "  ");
					PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "Data:");
					PrintFileHex(pRpStruct->RecordArray, pRpStruct->RecordArraySize, &pRpStruct->Buff_Rp[2], 2);
					PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "\n");
#endif						
#ifdef RP_RECORD_SIMPLIFY_BIN
					/*从队列读数据的起始标识*/
					PrintRecArrayByte(pRpStruct->RecordArray, pRpStruct->RecordArraySize, 0x40 | 0x00); /*-< 记录读数据标识日志*/
					/*目的Type和ID*/
					PrintRecArrayByte(pRpStruct->RecordArray, pRpStruct->RecordArraySize, pRpStruct->Buff_Rp[0]); /*-< 记录目的类型日志*/
					PrintRecArrayByte(pRpStruct->RecordArray, pRpStruct->RecordArraySize, pRpStruct->Buff_Rp[1]); /*-< 记录目的ID日志*/
					/*本帧数据中纯应用数据的长度*/
					PrintRecArray2ByteB(pRpStruct->RecordArray, pRpStruct->RecordArraySize, (UINT16)(Length - 2)); /*-< 记录长度日志*/
#endif
						/*获取发送方和接收方设备标识*/
					dsuRpTypeId2DevName(pRpStruct->LocalType, pRpStruct->LocalID, &locDevName); /*-< 调用函数得到本方类型ID*/
					dsuRpTypeId2DevName(pRpStruct->Buff_Rp[0], pRpStruct->Buff_Rp[1], &destDevName); /*-< 调用函数得到对方类型ID*/
					/*根据发送方和接收方设备标识获取协议类型*/
					dsurRpGetProtclType(locDevName, destDevName, &protclType); /*-< 调用函数得到使用协议类型*/

					/*读取成功*/
					CurrentSnLink = Rp_SearchSnLnk(DestDevNameInFrame, pRpStruct); /*-< 调用函数得到链路*/
					if (CurrentSnLink != NULL) /*-< 调用函数是否成功*/
					{
						/*判断是否发出过序列号0.如果LastSn为0，则没有发出过序列号0*/
						if (CurrentSnLink->SnLink_Info.LastSn == 0) /*-< 当前输出序号是否0*/
						{
							for (i = 0; i < 3; i++) /*-< 当前下标是否小于3*/
							{
								/*读取数组已存数据长度*/
								AppArray_Len = ShortFromChar(pRpStruct->AppArray); /*-< 得到输出应用数据长度*/
								/*写入序列号为0*/
								LongToChar(0, &pRpStruct->AppArray[AppArray_Len + 2 + outPutSnIdx]); /*-< 写入序号到输出应用数据*/
								/*写入帧长度*/
								AppArray_Temp = 5 + fitFrameLen; /*-< 得到写入帧长度*/
								ShortToChar(AppArray_Temp, &pRpStruct->AppArray[AppArray_Len + 2 + OUTPUT_FRAME_LEN]); /*-< 写入帧长度到输出应用数据*/
								/*写入协议类型*/
								pRpStruct->AppArray[AppArray_Len + 2 + OUTPUT_PTOTCL_TYPE] = protclType; /*-< 写入协议类型到输出应用数据*/

								/*写入目标类型和目标ID*/
								ShortToChar(DestDevNameInFrame, &pRpStruct->AppArray[AppArray_Len + 2 + OUTPUT_DEST_DEVTYPE]); /*-< 写入目的类型ID到输出应用数据*/
								/*预留两个字节*/
								ShortToChar(0, &pRpStruct->AppArray[AppArray_Len + 2 + OUTPUT_RESERVED]); /*-< 写入预留到输出应用数据*/
								/*写入版本号*/
								pRpStruct->AppArray[AppArray_Len + 2 + OUTPUT_EDITION] = 0xFF; /*-< 写入RP帧标识到输出应用数据*/
								/*写入消息正文长度*/
								AppArray_Temp = 0; /*-< 设置应用长度为0*/
								ShortToChar(AppArray_Temp, &pRpStruct->AppArray[AppArray_Len + 2 + OUTPUT_TEXT_LEN]); /*-< 写入应用长度到输出应用数据*/

								if (INTERFACE_TYPE_FOUR == pRpStruct->interfaceType) /*-< 接口类型是否发送/接收标识为4字节*/
								{
									LongToChar(locHlhtId, &pRpStruct->AppArray[AppArray_Len + 2 + OUTPUT_LOC_TYPEID]); /*-< 设置本方互联互通ID到输出应用数据*/
									LongToChar(oppHlhtId, &pRpStruct->AppArray[AppArray_Len + 2 + outPutDstTypeIdIdx]); /*-< 设置本方互联互通ID到输出应用数据*/
								}
								else
								{
									/*写入发送方标识*/
									pRpStruct->AppArray[AppArray_Len + 2 + OUTPUT_LOC_TYPEID] = pRpStruct->LocalType; /*-< 设置本方类型到输出应用数据*/
									pRpStruct->AppArray[AppArray_Len + 2 + OUTPUT_LOC_TYPEID + 1] = pRpStruct->LocalID; /*-< 设置本方ID到输出应用数据*/
									/*写入接收方标识*/
									pRpStruct->AppArray[AppArray_Len + 2 + outPutDstTypeIdIdx] = pRpStruct->Buff_Rp[0]; /*-< 设置对方类型到输出应用数据*/
									pRpStruct->AppArray[AppArray_Len + 2 + outPutDstTypeIdIdx + 1] = pRpStruct->Buff_Rp[1]; /*-< 设置对方ID到输出应用数据*/
								}


								AppArray_Temp = 7 + fitFrameLen + AppArray_Len; /*-< 计算总长度*/
								ShortToChar(AppArray_Temp, &pRpStruct->AppArray[0]); /*-< 设置总长度到输出应用数据*/

								CurrentSnLink->SnLink_Info.LastSn = 0; /*-< 设置输出序号为0*/
#ifdef RP_RECORD_ERR_ASC
								PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "OUT:\n");
								PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "Len:");
								PrintFileU16Hex(pRpStruct->RecordArray, pRpStruct->RecordArraySize, 0);
								PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "  ");
								PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "Sn:");
								PrintFileU32Hex(pRpStruct->RecordArray, pRpStruct->RecordArraySize, CurrentSnLink->SnLink_Info.LastSn);
								PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "  ");
								PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "DstNm:");
								PrintFileU16Hex(pRpStruct->RecordArray, pRpStruct->RecordArraySize, ShortFromChar(pRpStruct->Buff_Rp));
								PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "\n");
#endif										
#ifdef RP_RECORD_SIMPLIFY_BIN 
								/*向网络发送的起始标识*/
								PrintRecArrayByte(pRpStruct->RecordArray, pRpStruct->RecordArraySize, 0x80 | 0x00); /*-< 记录输出标识日志*/
								/*接收方Type和ID*/
								PrintRecArrayByte(pRpStruct->RecordArray, pRpStruct->RecordArraySize, pRpStruct->Buff_Rp[0]); /*-< 记录对方类型日志*/
								PrintRecArrayByte(pRpStruct->RecordArray, pRpStruct->RecordArraySize, pRpStruct->Buff_Rp[1]); /*-< 记录对方ID日志*/
								/*发送方Type和ID*/
								PrintRecArrayByte(pRpStruct->RecordArray, pRpStruct->RecordArraySize, pRpStruct->LocalType); /*-< 记录本方类型日志*/
								PrintRecArrayByte(pRpStruct->RecordArray, pRpStruct->RecordArraySize, pRpStruct->LocalID); /*-< 记录本方ID日志*/
								/*序列号*/
								PrintRecArray4ByteB(pRpStruct->RecordArray, pRpStruct->RecordArraySize, CurrentSnLink->SnLink_Info.LastSn); /*-< 记录输出序号日志*/
								/*本帧数据中纯应用数据的长度*/
								PrintRecArray2ByteB(pRpStruct->RecordArray, pRpStruct->RecordArraySize, 0); /*-< 记录输出长度日志*/
#endif
							}
						}
						/*读取数组已存数据长度*/
						AppArray_Len = ShortFromChar(pRpStruct->AppArray); /*-< 得到输出应用数据长度*/
						/*写入序列号*/
						if (CurrentSnLink->SnLink_Info.LastSn == 0xFFFFFFFF) /*-< 输出序号是否最大*/
						{
							CurrentSnLink->SnLink_Info.LastSn = 0; /*-< 设置输出序号为0*/
						}
						LongToChar((CurrentSnLink->SnLink_Info.LastSn + 1), &pRpStruct->AppArray[AppArray_Len + 2 + outPutSnIdx]); /*-< 设置自增后输出序号到输出应用数据*/
						/*写入帧长度*/
						AppArray_Temp = 5 + Length - 2 + fitFrameLen; /*-< 得到写入帧长度*/
						ShortToChar(AppArray_Temp, &pRpStruct->AppArray[AppArray_Len + 2 + OUTPUT_FRAME_LEN]);	/*-< 写入帧长度到输出应用数据*/
						/*写入协议类型*/
						pRpStruct->AppArray[AppArray_Len + 2 + OUTPUT_PTOTCL_TYPE] = protclType; /*-< 写入协议类型到输出应用数据*/
						/*写入目标类型和目标ID*/
						ShortToChar(DestDevNameInFrame, &pRpStruct->AppArray[AppArray_Len + 2 + OUTPUT_DEST_DEVTYPE]); /*-< 写入目的类型ID到输出应用数据*/
						/*预留两个字节*/
						ShortToChar(0, &pRpStruct->AppArray[AppArray_Len + 2 + OUTPUT_RESERVED]); /*-< 写入预留到输出应用数据*/
						/*写入版本号*/
						pRpStruct->AppArray[AppArray_Len + 2 + OUTPUT_EDITION] = 0xFF; /*-< 写入RP帧标识到输出应用数据*/
						/*写入消息正文长度*/
						AppArray_Temp = Length - 2; /*-< 设置应用长度*/
						ShortToChar(AppArray_Temp, &pRpStruct->AppArray[AppArray_Len + 2 + OUTPUT_TEXT_LEN]); /*-< 写入应用长度到输出应用数据*/

						if (INTERFACE_TYPE_FOUR == pRpStruct->interfaceType) /*-< 接口类型是否发送/接收标识为4字节*/
						{
							LongToChar(locHlhtId, &pRpStruct->AppArray[AppArray_Len + 2 + OUTPUT_LOC_TYPEID]); /*-< 设置本方互联互通ID到输出应用数据*/
							LongToChar(oppHlhtId, &pRpStruct->AppArray[AppArray_Len + 2 + outPutDstTypeIdIdx]); /*-< 设置本方互联互通ID到输出应用数据*/
						}
						else
						{
							/*写入发送方标识*/
							pRpStruct->AppArray[AppArray_Len + 2 + OUTPUT_LOC_TYPEID] = pRpStruct->LocalType; /*-< 设置本方类型到输出应用数据*/
							pRpStruct->AppArray[AppArray_Len + 2 + OUTPUT_LOC_TYPEID + 1] = pRpStruct->LocalID; /*-< 设置本方ID到输出应用数据*/
							/*写入接收方标识*/
							pRpStruct->AppArray[AppArray_Len + 2 + outPutDstTypeIdIdx] = pRpStruct->Buff_Rp[0]; /*-< 设置对方类型到输出应用数据*/
							pRpStruct->AppArray[AppArray_Len + 2 + outPutDstTypeIdIdx + 1] = pRpStruct->Buff_Rp[1]; /*-< 设置对方ID到输出应用数据*/
						}

						/*写入消息正文*/
						for (i = 0; i < Length - 2; i++) /*-< 长度下标是否小于应用长度*/
						{
							pRpStruct->AppArray[AppArray_Len + 2 + outPutTextIdx + i] = pRpStruct->Buff_Rp[2 + i]; /*-< 设置应用值*/
						}

						AppArray_Temp = 7 + fitFrameLen + Length - 2 + AppArray_Len; /*-< 计算总长度*/
						ShortToChar(AppArray_Temp, &pRpStruct->AppArray[0]); /*-< 设置总长度到输出应用数据*/

						CurrentSnLink->SnLink_Info.LastSn++; /*-< 设置输出序号自增1*/
#ifdef RP_RECORD_ERR_ASC
						PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "OUT:\n");
						PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "Len:");
						PrintFileU16Hex(pRpStruct->RecordArray, pRpStruct->RecordArraySize, (UINT16)(Length - 2));
						PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "  ");
						PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "Sn:");
						PrintFileU32Hex(pRpStruct->RecordArray, pRpStruct->RecordArraySize, CurrentSnLink->SnLink_Info.LastSn);
						PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "  ");
						PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "DstNm:");
						PrintFileU16Hex(pRpStruct->RecordArray, pRpStruct->RecordArraySize, ShortFromChar(pRpStruct->Buff_Rp));
						PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "  ");
						PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "Data:");
						PrintFileHex(pRpStruct->RecordArray, pRpStruct->RecordArraySize, &pRpStruct->Buff_Rp[2], 2);
						PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "\n");
#endif									
#ifdef RP_RECORD_SIMPLIFY_BIN 
						/*向网络发送的起始标识*/
						PrintRecArrayByte(pRpStruct->RecordArray, pRpStruct->RecordArraySize, 0x80 | 0x00); /*-< 记录输出标识日志*/
						/*接收方Type和ID*/
						PrintRecArrayByte(pRpStruct->RecordArray, pRpStruct->RecordArraySize, pRpStruct->Buff_Rp[0]); /*-< 记录对方类型日志*/
						PrintRecArrayByte(pRpStruct->RecordArray, pRpStruct->RecordArraySize, pRpStruct->Buff_Rp[1]); /*-< 记录对方ID日志*/
						/*发送方Type和ID*/
						PrintRecArrayByte(pRpStruct->RecordArray, pRpStruct->RecordArraySize, pRpStruct->LocalType); /*-< 记录本方类型日志*/
						PrintRecArrayByte(pRpStruct->RecordArray, pRpStruct->RecordArraySize, pRpStruct->LocalID); /*-< 记录本方ID日志*/
						/*序列号*/
						PrintRecArray4ByteB(pRpStruct->RecordArray, pRpStruct->RecordArraySize, CurrentSnLink->SnLink_Info.LastSn); /*-< 记录输出序号日志*/
						/*本帧数据中纯应用数据的长度*/
						PrintRecArray2ByteB(pRpStruct->RecordArray, pRpStruct->RecordArraySize, (UINT16)(Length - 2)); /*-< 记录输出长度日志*/
#endif								
					}
					else
					{
						CurrentSnLink = Rp_InsertLnk(DestDevNameInFrame, pRpStruct); /*-< 调用函数插入链路是否成功*/
						if (CurrentSnLink != NULL) /*-< 调用函数是否成功*/
						{
							for (i = 0; i < 3; i++) /*-< 当前下标是否小于3*/
							{
								/*读取数组已存数据长度*/
								AppArray_Len = ShortFromChar(pRpStruct->AppArray); /*-< 得到输出应用数据长度*/
								/*写入序列号为0*/
								LongToChar(0, &pRpStruct->AppArray[AppArray_Len + 2 + outPutSnIdx]); /*-< 写入序号到输出应用数据*/
								/*写入帧长度*/
								AppArray_Temp = 5 + fitFrameLen; /*-< 得到写入帧长度*/
								ShortToChar(AppArray_Temp, &pRpStruct->AppArray[AppArray_Len + 2 + OUTPUT_FRAME_LEN]); /*-< 写入帧长度到输出应用数据*/
								/*写入协议类型*/
								pRpStruct->AppArray[AppArray_Len + 2 + OUTPUT_PTOTCL_TYPE] = protclType; /*-< 写入协议类型到输出应用数据*/

								/*写入目标类型和目标ID*/
								ShortToChar(DestDevNameInFrame, &pRpStruct->AppArray[AppArray_Len + 2 + OUTPUT_DEST_DEVTYPE]); /*-< 写入目的类型ID到输出应用数据*/
								/*预留两个字节*/
								ShortToChar(0, &pRpStruct->AppArray[AppArray_Len + 2 + OUTPUT_RESERVED]); /*-< 写入预留到输出应用数据*/
								/*写入版本号*/
								pRpStruct->AppArray[AppArray_Len + 2 + OUTPUT_EDITION] = 0xFF; /*-< 写入RP帧标识到输出应用数据*/
								/*写入消息正文长度*/
								AppArray_Temp = 0;
								ShortToChar(AppArray_Temp, &pRpStruct->AppArray[AppArray_Len + 2 + OUTPUT_TEXT_LEN]); /*-< 写入应用长度到输出应用数据*/

								if (INTERFACE_TYPE_FOUR == pRpStruct->interfaceType) /*-< 接口类型是否发送/接收标识为4字节*/
								{
									LongToChar(locHlhtId, &pRpStruct->AppArray[AppArray_Len + 2 + OUTPUT_LOC_TYPEID]); /*-< 设置本方互联互通ID到输出应用数据*/
									LongToChar(oppHlhtId, &pRpStruct->AppArray[AppArray_Len + 2 + outPutDstTypeIdIdx]); /*-< 设置本方互联互通ID到输出应用数据*/
								}
								else
								{
									/*写入发送方标识*/
									pRpStruct->AppArray[AppArray_Len + 2 + OUTPUT_LOC_TYPEID] = pRpStruct->LocalType; /*-< 设置本方类型到输出应用数据*/
									pRpStruct->AppArray[AppArray_Len + 2 + OUTPUT_LOC_TYPEID + 1] = pRpStruct->LocalID; /*-< 设置本方ID到输出应用数据*/
									/*写入接收方标识*/
									pRpStruct->AppArray[AppArray_Len + 2 + outPutDstTypeIdIdx] = pRpStruct->Buff_Rp[0]; /*-< 设置对方类型到输出应用数据*/
									pRpStruct->AppArray[AppArray_Len + 2 + outPutDstTypeIdIdx + 1] = pRpStruct->Buff_Rp[1]; /*-< 设置对方ID到输出应用数据*/
								}


								AppArray_Temp = 7 + fitFrameLen + AppArray_Len; /*-< 计算总长度*/
								ShortToChar(AppArray_Temp, &pRpStruct->AppArray[0]); /*-< 设置总长度到输出应用数据*/

								CurrentSnLink->SnLink_Info.LastSn = 0; /*-< 设置输出序号为0*/
#ifdef RP_RECORD_ERR_ASC
								PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "OUT:\n");
								PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "Len:");
								PrintFileU16Hex(pRpStruct->RecordArray, pRpStruct->RecordArraySize, 0);
								PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "  ");
								PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "Sn:");
								PrintFileU32Hex(pRpStruct->RecordArray, pRpStruct->RecordArraySize, CurrentSnLink->SnLink_Info.LastSn);
								PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "  ");
								PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "DstNm:");
								PrintFileU16Hex(pRpStruct->RecordArray, pRpStruct->RecordArraySize, ShortFromChar(pRpStruct->Buff_Rp));
								PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "\n");
#endif										
#ifdef RP_RECORD_SIMPLIFY_BIN 
								/*向网络发送的起始标识*/
								PrintRecArrayByte(pRpStruct->RecordArray, pRpStruct->RecordArraySize, 0x80 | 0x00); /*-< 记录输出标识日志*/
								/*接收方Type和ID*/
								PrintRecArrayByte(pRpStruct->RecordArray, pRpStruct->RecordArraySize, pRpStruct->Buff_Rp[0]); /*-< 记录对方类型日志*/
								PrintRecArrayByte(pRpStruct->RecordArray, pRpStruct->RecordArraySize, pRpStruct->Buff_Rp[1]); /*-< 记录对方ID日志*/
								/*发送方Type和ID*/
								PrintRecArrayByte(pRpStruct->RecordArray, pRpStruct->RecordArraySize, pRpStruct->LocalType); /*-< 记录本方类型日志*/
								PrintRecArrayByte(pRpStruct->RecordArray, pRpStruct->RecordArraySize, pRpStruct->LocalID); /*-< 记录本方ID日志*/
								/*序列号*/
								PrintRecArray4ByteB(pRpStruct->RecordArray, pRpStruct->RecordArraySize, CurrentSnLink->SnLink_Info.LastSn); /*-< 记录输出序号日志*/
								/*本帧数据中纯应用数据的长度*/
								PrintRecArray2ByteB(pRpStruct->RecordArray, pRpStruct->RecordArraySize, 0); /*-< 记录输出长度日志*/
#endif
							}
							/*读取数组已存数据长度*/
							AppArray_Len = ShortFromChar(pRpStruct->AppArray); /*-< 得到输出应用数据长度*/
							/*写入序列号为1*/
							LongToChar(1, &pRpStruct->AppArray[AppArray_Len + 2 + outPutSnIdx]); /*-< 设置输出序号1到输出应用数据*/
							/*写入帧长度*/
							AppArray_Temp = 5 + Length - 2 + fitFrameLen; /*-< 得到写入帧长度*/
							ShortToChar(AppArray_Temp, &pRpStruct->AppArray[AppArray_Len + 2 + OUTPUT_FRAME_LEN]);	/*-< 写入帧长度到输出应用数据*/
							/*写入协议类型*/
							pRpStruct->AppArray[AppArray_Len + 2 + OUTPUT_PTOTCL_TYPE] = protclType; /*-< 写入协议类型到输出应用数据*/

							/*写入目标类型和目标ID*/
							ShortToChar(DestDevNameInFrame, &pRpStruct->AppArray[AppArray_Len + 2 + OUTPUT_DEST_DEVTYPE]); /*-< 写入目的类型ID到输出应用数据*/
							/*预留两个字节*/
							ShortToChar(0, &pRpStruct->AppArray[AppArray_Len + 2 + OUTPUT_RESERVED]); /*-< 写入预留到输出应用数据*/
							/*写入版本号*/
							pRpStruct->AppArray[AppArray_Len + 2 + OUTPUT_EDITION] = 0xFF; /*-< 写入RP帧标识到输出应用数据*/
							/*写入消息正文长度*/
							AppArray_Temp = Length - 2; /*-< 设置应用长度*/
							ShortToChar(AppArray_Temp, &pRpStruct->AppArray[AppArray_Len + 2 + OUTPUT_TEXT_LEN]); /*-< 写入应用长度到输出应用数据*/

							if (INTERFACE_TYPE_FOUR == pRpStruct->interfaceType) /*-< 接口类型是否发送/接收标识为4字节*/
							{
								LongToChar(locHlhtId, &pRpStruct->AppArray[AppArray_Len + 2 + OUTPUT_LOC_TYPEID]); /*-< 设置本方互联互通ID到输出应用数据*/
								LongToChar(oppHlhtId, &pRpStruct->AppArray[AppArray_Len + 2 + outPutDstTypeIdIdx]); /*-< 设置本方互联互通ID到输出应用数据*/
							}
							else
							{
								/*写入发送方标识*/
								pRpStruct->AppArray[AppArray_Len + 2 + OUTPUT_LOC_TYPEID] = pRpStruct->LocalType; /*-< 设置本方类型到输出应用数据*/
								pRpStruct->AppArray[AppArray_Len + 2 + OUTPUT_LOC_TYPEID + 1] = pRpStruct->LocalID; /*-< 设置本方ID到输出应用数据*/
								/*写入接收方标识*/
								pRpStruct->AppArray[AppArray_Len + 2 + outPutDstTypeIdIdx] = pRpStruct->Buff_Rp[0]; /*-< 设置对方类型到输出应用数据*/
								pRpStruct->AppArray[AppArray_Len + 2 + outPutDstTypeIdIdx + 1] = pRpStruct->Buff_Rp[1]; /*-< 设置对方ID到输出应用数据*/
							}

							/*写入消息正文*/
							for (i = 0; i < Length - 2; i++) /*-< 长度下标是否小于应用长度*/
							{
								pRpStruct->AppArray[AppArray_Len + 2 + outPutTextIdx + i] = pRpStruct->Buff_Rp[2 + i]; /*-< 设置应用值*/
							}

							AppArray_Temp = 7 + fitFrameLen + Length - 2 + AppArray_Len; /*-< 计算总长度*/
							ShortToChar(AppArray_Temp, &pRpStruct->AppArray[0]); /*-< 设置总长度到输出应用数据*/

							CurrentSnLink->SnLink_Info.LastSn = 1; /*-< 设置输出序号为1*/
#ifdef RP_RECORD_ERR_ASC
							PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "OUT:\n");
							PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "Len:");
							PrintFileU16Hex(pRpStruct->RecordArray, pRpStruct->RecordArraySize, (UINT16)(Length - 2));
							PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "  ");
							PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "Sn:");
							PrintFileU32Hex(pRpStruct->RecordArray, pRpStruct->RecordArraySize, CurrentSnLink->SnLink_Info.LastSn);
							PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "  ");
							PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "DstNm:");
							PrintFileU16Hex(pRpStruct->RecordArray, pRpStruct->RecordArraySize, ShortFromChar(pRpStruct->Buff_Rp));
							PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "  ");
							PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "Data:");
							PrintFileHex(pRpStruct->RecordArray, pRpStruct->RecordArraySize, &pRpStruct->Buff_Rp[2], 2);
							PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "\n");
#endif									
#ifdef RP_RECORD_SIMPLIFY_BIN 
							/*向网络发送的起始标识*/
							PrintRecArrayByte(pRpStruct->RecordArray, pRpStruct->RecordArraySize, 0x80 | 0x00); /*-< 记录输出标识日志*/
							/*接收方Type和ID*/
							PrintRecArrayByte(pRpStruct->RecordArray, pRpStruct->RecordArraySize, pRpStruct->Buff_Rp[0]); /*-< 记录对方类型日志*/
							PrintRecArrayByte(pRpStruct->RecordArray, pRpStruct->RecordArraySize, pRpStruct->Buff_Rp[1]); /*-< 记录对方ID日志*/
							/*发送方Type和ID*/
							PrintRecArrayByte(pRpStruct->RecordArray, pRpStruct->RecordArraySize, pRpStruct->LocalType); /*-< 记录本方类型日志*/
							PrintRecArrayByte(pRpStruct->RecordArray, pRpStruct->RecordArraySize, pRpStruct->LocalID); /*-< 记录本方ID日志*/
							/*序列号*/
							PrintRecArray4ByteB(pRpStruct->RecordArray, pRpStruct->RecordArraySize, CurrentSnLink->SnLink_Info.LastSn); /*-< 记录输出序号日志*/
							/*本帧数据中纯应用数据的长度*/
							PrintRecArray2ByteB(pRpStruct->RecordArray, pRpStruct->RecordArraySize, (UINT16)(Length - 2)); /*-< 记录输出长度日志*/
#endif
						}
						else
						{
#ifdef RP_RECORD_ERR_ASC
							PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "E:");
							PrintFileU16Hex(pRpStruct->RecordArray, pRpStruct->RecordArraySize, RP_ERR | RP_OUTPUT | RP_ERROR_NULL | RP_LNK_POP);
							PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "\n");
#endif	
#ifdef RP_RECORD_SIMPLIFY_BIN 								
							/*记录错误*/
							PrintRecArray2ByteB(pRpStruct->RecordArray, pRpStruct->RecordArraySize, RP_ERR | RP_OUTPUT | RP_ERROR_NULL | RP_LNK_POP); /*-< 记录插入链路失败日志*/
#endif				
							gRpErrorInfo |= RP_ERR_OUTPUT_RP_LNK_POP; /*-< 设置错误码*/

						}
					}
				}
				else
				{
#ifdef RP_RECORD_ERR_ASC
					PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "W:");
					PrintFileU16Hex(pRpStruct->RecordArray, pRpStruct->RecordArraySize, RP_WARN | RP_OUTPUT | RP_ERROR_NULL | RP_QUEUE_READ);
					PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "\n");
#endif				
#ifdef RP_RECORD_SIMPLIFY_BIN
					/*记录错误*/
					PrintRecArray2ByteB(pRpStruct->RecordArray, pRpStruct->RecordArraySize, RP_WARN | RP_OUTPUT | RP_ERROR_NULL | RP_QUEUE_READ); /*-< 记录未读到数据日志*/
#endif	
					gRpErrorInfo |= RP_WARN_OUTPUT_RP_QUEUE_READ; /*-< 设置错误码*/

					break; /*-< 退出遍历*/
				}
			}
		}
		else
		{
#ifdef RP_RECORD_ERR_ASC
			PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "W:");
			PrintFileU16Hex(pRpStruct->RecordArray, pRpStruct->RecordArraySize, RP_WARN | RP_OUTPUT | RP_ERROR_NULL | RP_QUEUE_READ);
			PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "\n");
#endif		
#ifdef RP_RECORD_SIMPLIFY_BIN
			/*记录错误*/
			PrintRecArray2ByteB(pRpStruct->RecordArray, pRpStruct->RecordArraySize, RP_WARN | RP_OUTPUT | RP_ERROR_NULL | RP_QUEUE_READ); /*-< 记录未读到长度日志*/
#endif	
			gRpErrorInfo |= RP_WARN_OUTPUT_RP_QUEUE_READ; /*-< 设置错误码*/

			break; /*-< 退出遍历*/
		}

		QueueLength = QueueStatus(&pRpStruct->OutputDataQueue); /*-< 得到输出应用给协议队列长度*/
	}

	CurNumLink = pRpStruct->SnLinkhead; /*-< 设置当前序号堆栈顶*/
	NumOfLink = 0; /*-< 设置链路数为0*/

	while (CurNumLink != NULL) /*-< 当前序号堆栈顶是否非空*/
	{
		ShortToChar(CurNumLink->DestDevName, &pRpStruct->VarArray[2 + 68 * NumOfLink]); /*-< 设置对方类型ID到中间变量中*/
		ShortToChar(CurNumLink->SnLink_Info.SnArrayIndex, &pRpStruct->VarArray[4 + 68 * NumOfLink]); /*-< 设置序号下标到中间变量中*/
		LongToChar(CurNumLink->SnLink_Info.LastSn, &pRpStruct->VarArray[6 + 68 * NumOfLink]); /*-< 设置输出序号到中间变量中*/
#ifdef RP_RECORD_ERR_ASC
		PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "Lnk:\n");
		PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "DstNm:");
		PrintFileU16Hex(pRpStruct->RecordArray, pRpStruct->RecordArraySize, CurNumLink->DestDevName);
		PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "  ");
		PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "Sn:");
		PrintFileU32Hex(pRpStruct->RecordArray, pRpStruct->RecordArraySize, CurNumLink->SnLink_Info.LastSn);
		PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "\n");
#endif		
#ifdef RP_RECORD_SIMPLIFY_BIN 
		/*一条链路起始标识*/
		PrintRecArrayByte(pRpStruct->RecordArray, pRpStruct->RecordArraySize, 0xC0 | 0x00); /*-< 记录输出标识日志*/
		ShortToChar(CurNumLink->DestDevName, pRpStruct->Buff_Rp); /*-< 记录对方类型ID日志*/
		PrintRecArrayByte(pRpStruct->RecordArray, pRpStruct->RecordArraySize, pRpStruct->Buff_Rp[0]); /*-< 记录本方类型ID日志*/
		PrintRecArrayByte(pRpStruct->RecordArray, pRpStruct->RecordArraySize, pRpStruct->Buff_Rp[1]); /*-< 记录本方类型ID日志*/
		PrintRecArray4ByteB(pRpStruct->RecordArray, pRpStruct->RecordArraySize, CurNumLink->SnLink_Info.LastSn); /*-< 记录输出序号日志*/
#endif		

#ifdef RP_RECORD_ERR_ASC								
		PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "SnArray:");
#endif
		for (i = 0; i < 15; i++) /*-< 当前下标是否小于15*/
		{
			LongToChar(CurNumLink->SnLink_Info.SnArray[i], &pRpStruct->VarArray[10 + i * 4 + 68 * NumOfLink]); /*-< 设置序号给中间变量中*/
#ifdef RP_RECORD_ERR_ASC								
			PrintFileU32Hex(pRpStruct->RecordArray, pRpStruct->RecordArraySize, CurNumLink->SnLink_Info.SnArray[i]);
			PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "  ");
#endif				
#ifdef RP_RECORD_SIMPLIFY_BIN 	
			PrintRecArray4ByteB(pRpStruct->RecordArray, pRpStruct->RecordArraySize, CurNumLink->SnLink_Info.SnArray[i]); /*-< 记录序号日志*/
#endif	
		}
#ifdef RP_RECORD_ERR_ASC								
		PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "\n");
#endif
		NumOfLink++; /*-< 链路数自增1*/
		CurNumLink = CurNumLink->NextNode; /*-< 下一链路设置给当前链路*/
	}

	ShortToChar((UINT16)(68 * NumOfLink), pRpStruct->VarArray); /*-< 设置中间变量长度到中间变量中*/

#ifdef RP_RECORD_SIMPLIFY_BIN 	
	/*输出单元结束标识*/
	PrintRecArrayByte(pRpStruct->RecordArray, pRpStruct->RecordArraySize, 0xE0 | 0x00); /*-< 记录链路日志*/
	PrintRecArray2ByteB(pRpStruct->RecordArray, pRpStruct->RecordArraySize, AppArray_Temp); /*-< 记录链路长度日志*/
	PrintRecArray2ByteB(pRpStruct->RecordArray, pRpStruct->RecordArraySize, (UINT16)(68 * NumOfLink)); /*-< 记录链路数据日志*/
#endif	
#ifdef RP_RECORD_ERR_ASC								
	Length = ShortFromChar(pRpStruct->RecordArray);
	PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "RcdLen:");
	PrintFileU16Hex(pRpStruct->RecordArray, pRpStruct->RecordArraySize, Length);
	PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "\n");
	PrintFiles(pRpStruct->RecordArray, pRpStruct->RecordArraySize, "\n");
#endif	

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

/*****************************************************************************************
*功能描述:
*    刷新冗余层中间变量
*参数说明:
*    RP_INFO_STRU *pRpStruct 统一结构体
*    UINT16 sLen_Input    冗余层中间变量长度
*    UINT8 *Input_Data_LnkMes 冗余层中间变量
*返回值:
*   正确返回1；错误返回0;                                                     
*****************************************************************************************/
UINT8 RpRefresh(UINT16 sLen_Input, UINT8 *Input_Data_LnkMes,RP_INFO_STRU *pRpStruct)/* %RELAX<MISRA_8_10> */
{
	UINT8 NumOfLink, i = 0, j = 0, ret = 0;
	RpSNLINK_STRU *TempIndex=NULL;
	RpSNLINK_STRU *LastIndex=NULL;
	STACK_DATA_TYPE_RP pData;
	UINT8 popret;	
	
	if((pRpStruct == NULL)||(Input_Data_LnkMes == NULL))	/* 非空检查 */
    {
        ret = 0;
        return ret;
    }
    else
    {
        /* 往后继续处理 */
    }

	/*将已用节点地址重新压进堆栈*/
	TempIndex = pRpStruct->SnLinkhead;
	while(TempIndex != NULL)
	{
		StackPush(&pRpStruct->SnLnkStack,(STACK_DATA_TYPE_RP)TempIndex);
		TempIndex = TempIndex->NextNode;
	}
	pRpStruct->SnLinkhead = NULL;
		
	if(sLen_Input%68 != 0) 
	{
		/*记录错误*/
		ret = 0;
		return ret;
	}
	else if(sLen_Input == 0)
	{
		/*记录错误*/
		ret = 1;
		return ret;
	}
	else
	{
		NumOfLink = (UINT8)(sLen_Input / 68);   /*单个节点信息长度68个字节*/

		for(i = 0; i < NumOfLink; i++)
		{
			/*获取节点内存;*/		
			popret = StackPop(&pRpStruct->SnLnkStack, &pData);
			if(0 == popret)
			{
				ret = 0;
				return ret;   /*没有可用的内存节点*/
			}
			else  /*为节点链路信息赋值*/
			{
				TempIndex = (RpSNLINK_STRU *)pData;
				TempIndex->DestDevName = ShortFromChar(&Input_Data_LnkMes[i * 68+ 0]);
				TempIndex->SnLink_Info.DestDevName = ShortFromChar(&Input_Data_LnkMes[i * 68+ 0]);
				TempIndex->SnLink_Info.SnArrayIndex= ShortFromChar(&Input_Data_LnkMes[i * 68+ 2]);
				TempIndex->SnLink_Info.LastSn= LongFromChar(&Input_Data_LnkMes[i * 68+ 4]);
				for(j = 0; j < 15; j++)
				{
					TempIndex->SnLink_Info.SnArray[j] = LongFromChar(&Input_Data_LnkMes[i * 68+ 8 + 4 * j]);
				}
			}

			if(i == 0)  /*第一次插入为头节点*/
			{
				pRpStruct->SnLinkhead = TempIndex;
			}
			else
			{
				LastIndex->NextNode = TempIndex;
			}
			LastIndex = TempIndex;
		}
		TempIndex->NextNode = NULL;

		ret = 1;
		return ret;
	}
}

/***************************************************************************************************************
函数描述: 
	初始化序列号缓冲链表堆栈
参数说明:
	RP_INFO_STRU *pRpStruct		统一结构体
返回值:
	成功返回1,失败返回0
功能描述：
	初始化特定大小特定结构的堆栈,不同的结构体只需要采用压入不同的指针使用方式便可以做成不同的管理堆栈
***************************************************************************************************************/
UINT8 Rp_init_SnStack(RP_INFO_STRU *pRpStruct)
{
	UINT16 i;/*循环变量*/
	RpSNLINK_STRU *SnLnk_stack = NULL;
	UINT8 ret;

	if(pRpStruct->SnLnkStack.pStackData != NULL)
	{
		for(i = 0;i < pRpStruct->SnLnkStack.TotalSize;i++)
		{
			pRpStruct->SnLnkStack.pStackData[i] = 0;/*保护性赋值，填充为空指针，相当于清空相应内存区域*/        
		}
	}
	else
	{
		ret = 0;
		return ret;
	}
	    
	SnLnk_stack = (RpSNLINK_STRU *)malloc(sizeof(RpSNLINK_STRU) * pRpStruct->SnLnkStack.TotalSize);
	if(SnLnk_stack == NULL)
	{
		ret = 0;
		return ret;
	}
	else
	{
		/*无操作*/   
		CommonMemSet(SnLnk_stack,sizeof(RpSNLINK_STRU) * pRpStruct->SnLnkStack.TotalSize,0,sizeof(RpSNLINK_STRU) * pRpStruct->SnLnkStack.TotalSize);
	}  
	for (i = 0;i < pRpStruct->SnLnkStack.TotalSize;i++)
	{	/*压入totalsize个节点*/
		if(StackPush(&pRpStruct->SnLnkStack,(STACK_DATA_TYPE_RP)&SnLnk_stack[i]) != 1)
		{
			ret = 0;
			return ret;/*压入节点失败*/
		}
		else
		{
			/*无操作*/
		}
	}
	pRpStruct->pSnStack = (UINT32 *) SnLnk_stack;
	
	ret = 1;
	return ret;
}

/*******************************************************************************************
函数描述:
	查询链路管理表中已有节点指针的操作——在冗余层序列号缓冲链表查询链路，完成定位链路的功能 
参数说明:
	[in]  UINT16 Dest_DevName	对方设备名（Type+ID） 
	RP_INFO_STRU *pRpStruct 	统一结构体
返回值:
	所需节点的地址指针 
功能描述：
	1.  根据对方的设备名在冗余层序列号缓冲链表中查询相应的链路，并返回此节点指针
*******************************************************************************************/
RpSNLINK_STRU* Rp_SearchSnLnk(UINT16 Dest_DevName,RP_INFO_STRU *pRpStruct)
{
    RpSNLINK_STRU *CurIndex;
    RpSNLINK_STRU *pret;

    /*当前指针从链表头指针开始*/
    CurIndex =  pRpStruct->SnLinkhead;
  
    while(1)
    {
        if(CurIndex != NULL)
        {
            /*找到要查询节点*/
            if(Dest_DevName == CurIndex->DestDevName)
            { 
                return CurIndex;/*返回当前指针*/
            }     
            else
            {
                CurIndex = CurIndex->NextNode;  /*没有找到要删除节点，将当前指针都往后移一个节点*/
            }
        }    /* if(CurIndex != NULL)*/
        else
        {   
            pret = NULL;
            return pret;    /*没有找到要该链路*/
        }
    }/*while(1)*/
}

/*******************************************************************************************
函数描述:
	将指定的节点插入到序列号缓冲链表中规定的位置
参数说明:
	[in]UINT16 Dest_DevName	对方设备名  
	RP_INFO_STRU *pRpStruct 	统一结构体	
返回值:
	当前插入链路的指针
功能描述：
	1、将所需插入的链路插入到序列号缓冲链表中
	2、为该链路添加一些信息
*******************************************************************************************/
RpSNLINK_STRU* Rp_InsertLnk( UINT16 Dest_DevName,RP_INFO_STRU *pRpStruct) 
{
	RpSNLINK_STRU *LastIndex;
	RpSNLINK_STRU *CurIndex;
	RpSNLINK_STRU *TempIndex;
	STACK_DATA_TYPE_RP pData;
	UINT8 i;

	UINT8 popret;
	RpSNLINK_STRU *pret;

	/*当前指针从链表头指针开始*/
	CurIndex =  pRpStruct->SnLinkhead;
	TempIndex = NULL;
	LastIndex = NULL;

	/*遍历已有链路管理表*/ 
	while(1)
	{
		/*链路管理表中已经有节点*/
		if(CurIndex != NULL)
		{
			/*节点大于当前节点,在当前节点之前插入*/
			if( Dest_DevName >CurIndex ->DestDevName)
			{
				/*获取节点内存;*/
				popret = StackPop(&pRpStruct->SnLnkStack, &pData);
				if(0 == popret)
				{
					pret = NULL;
					return pret;   /*没有可用的内存节点*/
				}
				else
				{
					TempIndex = (RpSNLINK_STRU *)pData;
					/*将目标Name赋值*/
					TempIndex->DestDevName = Dest_DevName;
					TempIndex->SnLink_Info.DestDevName = Dest_DevName;
					TempIndex->SnLink_Info.SnArrayIndex= 0;
					TempIndex->SnLink_Info.LastSn = 0;
					for(i = 0;i < 15;i++)
					{
					    TempIndex->SnLink_Info.SnArray[i] = 0;    
					}  
				}
				/*插入指针下一个节点指向当前指针*/
				TempIndex->NextNode = CurIndex;

				/*插入节点为第一个节点,将链表头节点重新置成新插入节点*/
				if(LastIndex == NULL)
				{
				    pRpStruct->SnLinkhead = TempIndex;
				}
				/*插入节点不为链表第一个节点，将上一个节点指向插入节点*/
				else
				{
				    LastIndex->NextNode = TempIndex;    
				}

				/*返回插入当前指针地址跳出循环*/ 
				return TempIndex;            
			}
			/*节点已经过存在，注：这里是否要重新覆盖*/
			else if( Dest_DevName == CurIndex ->DestDevName)
			{
				/*将目标Name赋值*/
				CurIndex->DestDevName = Dest_DevName;
				CurIndex->SnLink_Info.DestDevName = Dest_DevName;
				CurIndex->SnLink_Info.SnArrayIndex= 0;
				CurIndex->SnLink_Info.LastSn = 0;
                for(i = 0;i < 15;i++)
                {
                    CurIndex->SnLink_Info.SnArray[i] = 0;    
                }
			    
				/*跳出循环*/
				return CurIndex;   
			}
			/*插入节点小于当前节点，将当前和上一个节点向后一个节点*/
			else
			{
				LastIndex = CurIndex;
				CurIndex = CurIndex->NextNode;
			}
		}
		/*插入节点为最后一个节点||插入节点为第一个节点*/
		else
		{
			/*获取节点内存*/
			popret = StackPop(&pRpStruct->SnLnkStack, &pData);
			if(0 == popret)
			{
				pret = NULL;
				return pret;   /*没有可用的内存节点*/
			}			
			else
			{
				TempIndex = (RpSNLINK_STRU *)pData;			
				/*将目标Name赋值*/
				TempIndex->DestDevName = Dest_DevName; 
				TempIndex->SnLink_Info.DestDevName = Dest_DevName;
				TempIndex->SnLink_Info.SnArrayIndex= 0;
				TempIndex->SnLink_Info.LastSn = 0;
                for(i = 0;i < 15;i++)
                {
                    TempIndex->SnLink_Info.SnArray[i] = 0;    
                } 
			}


			/*插入节点为链表第一个节点，置为链表头节点第一个节点*/
			if(LastIndex == NULL)
			{
				/*将链表头指针赋值*/
				pRpStruct->SnLinkhead= TempIndex;
			}
			/*插入节点为链表最后一个节点，将该节点插入到最后一个节点位置上*/
			else
			{
				LastIndex->NextNode = TempIndex;    
			} 
			/*插入指针下一个节点指为空*/
			TempIndex->NextNode = NULL;

			/*返回插入当前指针地址*/  
			return TempIndex;   
		}
	}
}   

/*******************************************************************************************
*函数描述: 
*	判断序列号在缓冲数组里是否已经存储
*参数说明:
*	UINT32 Sn		要查询的序列号
*	RpSNLINK_STRU* SnNode	序列号缓冲列表节点
*返回值：
*	存在	return 1
*	不存在	return 0
********************************************************************************************/
UINT8 Rp_IsSnExit(UINT32 Sn, RpSNLINK_STRU* SnNode)
{
	UINT8 i, ret = 0;

	if(SnNode == NULL)
	{
		return ret;
	}
	
	for(i = 0; i < 15; i++)  /*缓冲数组最多存储15个序列号*/
	{
		if(SnNode->SnLink_Info.SnArray[i] == Sn)
		{
			ret = 1;
			return ret;
		}
	}

	return ret;
}


/*--------------------------------------------------------------------
 * RSR层内公用函数申明 Start
 *--------------------------------------------------------------------*/
/***********************************************************************
 * 方法名   : MemSet
 * 功能描述 : 对指定内存设定指定的值
 * 输入参数 : 
 *	参数名		类型		输入输出	描述
 *  --------------------------------------------------------------
 *	pDestAdd	UINT8 *		INOUT		内存空间开始地址
 *  Len			UINT16		IN			内存空间大小
 *	Val			UINT8		IN			指定值	
 * 
 * 返回值   : 1 正常
 ***********************************************************************/
UINT8 RpMemSet(UINT8 *pDestAdd, UINT16 Len, UINT8 Val)
{
    UINT16 index = 0;
	
    for(index = 0; index < Len; index++)
    {
	    pDestAdd[index] = Val;
    }

	return (UINT8)1;
}
/*******************************************************************************************************
* 功能描述: 	  获得 RP协议丢包和非宕机错误码
* 输入参数: 		无
* 输入输出参数: 	无
* 输出参数: 		gRpErrorInfo
* 全局变量: 	  gRpErrorInfo
* 返回值:			gRpErrorInfo
*******************************************************************************************************/

UINT32 GetRpErrorInfo(void)
{
	UINT32 ret = 0;
	ret = gRpErrorInfo;	
	return ret;
}
/*******************************************************************************************************
* 功能描述: 	   RP协议丢包和非宕机错误码复位
* 输入参数: 		无
* 输入输出参数: 	无
* 输出参数: 		gRpErrorInfo
* 全局变量: 	  gRpErrorInfo
* 返回值:			1:成功
*******************************************************************************************************/

UINT32 ReSetRpErrorInfo(void)
{
	UINT32 ret = 1;
	gRpErrorInfo = 0;	
	return ret;
}

/**
 * @brief RpDelAllLink RP删除所有链路
 * @param rp RP结构体变量 取值范围:参考结构体RP_INFO_STRU
 */
void RpDelAllLink(RP_INFO_STRU* rp)
{
	RpSNLINK_STRU* curLink = NULL; /*当前链路*/

	if (NULL != rp) /*-< 参数是否非空*/
	{
		curLink = rp->SnLinkhead; /*-< 设置当前链路*/
		while (NULL != curLink) /*-< 当前链路是否非空*/
		{
			rp->SnLinkhead = curLink->NextNode; /*-< 更新头指针*/

			(void)CommonMemSet(curLink, sizeof(RpSNLINK_STRU), 0u, sizeof(RpSNLINK_STRU)); /*-< 清零链路信息*/
			(void)PushStack(&rp->SnLnkStack, curLink); /*-< 链路节点压栈*/

			curLink = rp->SnLinkhead; /*-< 更新当前链路为下一链路*/
		}

		if (NULL != rp->RecordArray) /*-< 记录日志数组是否非空*/
		{
			(void)PrintRecArray2ByteB(rp->RecordArray, rp->RecordArraySize, (UINT16)0xF0F0u); /*-< 记录删所有链路日志*/
		}
	}
}

/*
* 功能描述： 堆栈初始化函数，用于初始化一个堆栈，与StackFree配对使用
*            主要为堆栈分配空间，并进行堆栈内部变量初始化
* 参数说明： CommonStackRp *pStack,      待初始化的的堆栈
*            UINT32 TotalSize,         堆栈大小
* 返回值  ： 1，成功
*            0，失败
*/
static UINT8 StackInitial(CommonStackRp* pStack, UINT16 TotalSize)
{
	UINT8 bRet = 0;/*用于函数返回*/

	/*对输入值进行判断*/
	if ((NULL != pStack) && (0 != TotalSize))
	{
		/*输入值合法*/

		/*堆栈数据初始化 */
		pStack->TotalSize = TotalSize;
		pStack->Top = 0;

		/*堆栈空间分配*/
		pStack->pStackData = (STACK_DATA_TYPE_RP*)malloc(sizeof(STACK_DATA_TYPE_RP) * (pStack->TotalSize));
		if (pStack->pStackData != NULL)
		{
			/*成功初始化*/
			bRet = 1;
		}
		else
		{
			/*堆栈初始化空间分配失败，函数返回失败*/
			bRet = 0;
		}
	}
	else
	{
		/*输入值不合法，函数返回失败*/

		bRet = 0;
	}

	return bRet;

}

/******************************************************************************************
* 功能描述      : 从堆栈中弹出栈顶元素，
* 输入参数      :
* 输入输出参数  : CommonStackRp *pStack，    堆栈的指针
* 输出参数      : STACK_DATA_TYPE_RP* pData， 弹出的栈顶元素
* 全局变量      :
* 返回值        : 成功返回1，否则返回0
*******************************************************************************************/
static UINT8 StackPop(CommonStackRp* pStack, STACK_DATA_TYPE_RP* pData)/* %RELAX<MISRA_8_10> */
{
	UINT8 ret;/*用于函数返回*/

	if (pStack->Top > 0)
	{
		/*堆栈中有数据*/

		/*弹出栈顶元素*/
		pStack->Top--;
		*pData = pStack->pStackData[pStack->Top];

		/*函数执行成功*/
		ret = 1;
		return ret;
	}
	else
	{
		/*堆栈中已无数据，返回失败*/
		ret = 0;
		return ret;
	}
}

/******************************************************************************************
* 功能描述      : 向堆栈中压入一个数据
* 输入参数      : STACK_DATA_TYPE_RP Data，    堆栈数据
* 输入输出参数  : CommonStackRp *pStack，     堆栈的指针
* 输出参数      :
* 全局变量      :
* 返回值        : 成功返回1,失败返回0
*******************************************************************************************/
static UINT8 StackPush(CommonStackRp* pStack, STACK_DATA_TYPE_RP Data)/* %RELAX<MISRA_8_10> */
{
	UINT8 ret;/*用于函数返回*/

	if (pStack->Top < pStack->TotalSize)
	{
		/*堆栈大小小于堆栈最大值这时可以压栈*/

		/*压入堆栈*/
		pStack->pStackData[pStack->Top] = Data;
		pStack->Top++;

		ret = 1;
		return ret;
	}
	else
	{
		/*堆栈大小大于堆栈最大值,不可以压栈.*/

		ret = 0;
		return ret;/*无法压入堆栈元素*/
	}
}

/*
* 函数描述： 堆栈存储空间释放函数
*            在不需要某个堆栈的时候，把堆栈的数据存储空间释放掉,与StackInitial配对使用
* 参数说明： CommonStackRp *pStack,       堆栈指针
* 返回值  ： 1，成功
*/
static UINT8 StackFree(CommonStackRp* pStack)
{

	UINT8 ret = 1;/*用于函数返回*/

	/*堆栈指针归位*/
	pStack->Top = 0;
	pStack->TotalSize = 0;

	/*释放堆栈空间*/
	if (pStack->pStackData != NULL)
	{
		free(pStack->pStackData);
		pStack->pStackData = NULL;
	}

	return    ret;
}
