/**
* @file SFM_Prtcl.c
* @brief Safe Function Module: 安全协议处理
* @details
* 从通信层获取输入数据交给平台层交换、比较
* 从平台层获取输入数据交给协议层解析
* 从协议层获取输入数据交给应用层使用
* 从应用层获取输出数据交给协议层封装
* 从协议层获取输出数据交给平台层比较
* 从平台层获取输出数交给通信层发送
* @author GT-BU
* @date 2021.02.20
* @version V1.0
* @copyright TCT
* @par 修改日志
* <table>
* <tr><th>Date        <th>Version  <th>Author     <th>Description
* <tr><td>2021.02.01  <td>V1.0     <td>GT-BU      <td>创建初始版本
* </table>
*/

#include "SFM_Prtcl.h"
#include "CM_Convert.h"
#include "CM_Memory.h"
#include "CM_Queue.h"
#include "CM_CRC32.h"
#include "CM_Mutex.h"
#include "PFM_Cfg.h"
#include "PFM_FS.h"
#include "PFM_ControlFlowCheck.h"
#include "SFM_2oo2.h"
#include "SFM_2x2.h"
#include "PFM_Log.h"
#include "DFM_Time.h"
#include "MSCP_APP_API.h"
#if QNX
#else
#include "cp_interface.h"
#endif
#include "PFM_RemoteUpdate.h"
#include "CFM_Net.h"
#include "protclInterFun.h"
#include "sfpplatform.h"
#include "dsuProtclFun.h"
static CM_UINT8 s_Prtcl_UDP_Cache[NET_UDP_BUF_SIZE];  /**< UDP缓冲区 */
static CM_UINT8 s_TmpCache[SFM_TMP_CACHE_SIZE]; /**< 外网通信临时缓冲区 */

static ProtclConfigInfoStru s_OutnetPrtcl; /**< 外网通信控制结构体 */
static struc_Unify_Info s_InnetPrtcl;      /**< 内网通信控制结构体 */
static struc_Unify_Info s_InnetPrtcl_RM;      /**< 远程部署内网通信控制结构体 */

static CM_MUTEX_T s_Outnet_AppSend_M;
static STRU_CM_QUEUE_T s_Outnet_AppSendQ;

static CM_MUTEX_T s_Innet_AppSend_M;
static STRU_CM_QUEUE_T s_Innet_AppSendQ;

static CM_MUTEX_T s_Innet_AppRmSend_M;
static STRU_CM_QUEUE_T s_Innet_AppRmSendQ;

static CM_MUTEX_T s_Innet_RmSend_M;
static STRU_CM_QUEUE_T s_Innet_RmSendQ;

static CM_MUTEX_T s_Outnet_AppRecv_M;
static STRU_CM_QUEUE_T s_Outnet_AppRecvQ;

static CM_MUTEX_T s_Innet_AppRecv_M;
static STRU_CM_QUEUE_T s_Innet_AppRecvQ;

static CM_MUTEX_T s_Innet_RmRecv_M;
static STRU_CM_QUEUE_T s_Innet_RmRecvQ;

extern CM_UINT32 g_MSCP_SysCount;  /**< 系统周期号 */
extern CM_INT32 g_PFM_Check;

static CM_UINT32 s_txSn = 1u;
/**
* @breif 外网安全协议初始化(-1)
* @details
* 外网安全协议的初始化
* 初始化失败将宕机
*/
void SFM_PrtclOutInit(void)
{
    /*- 变量初始化 */
    CM_UINT8 rt = 0u; /* 函数返回值 */
    CM_UINT16 OutnetID = g_PFM_Cfg.OUTNET_ID; /* 外网ID */
    ENUM_CM_RETURN ret = ENUM_CM_FALSE;

    /*- @alias 外网安全协议初始化*/
    if (0x55u == g_PFM_Cfg.M_OutnetSafe_Enable)
    {
        s_OutnetPrtcl.cpuId = g_PFM_Cfg.CPU_ID - 1u;/* cpuId和应用输出数据与svc有关 */
        s_OutnetPrtcl.LocalID = (CM_UINT8)(OutnetID % 256u);
        s_OutnetPrtcl.LocalType = (CM_UINT8)(OutnetID / 256u);
        s_OutnetPrtcl.CycleNum = &g_MSCP_SysCount;
		s_OutnetPrtcl.InputSize = 7200u;
		s_OutnetPrtcl.OutputSize = 7200u;
        s_OutnetPrtcl.RecordArraySize = 30000u;
        s_OutnetPrtcl.MaxNumPerCycle = 35u; /* 以zc举例：包数*4*2*2*2 */
#if QNX
    	rt = ProtclInitFunc((CM_UINT8*)FS_FILE_PATH, (CM_UINT32)inParamLen, inParam, &s_OutnetPrtcl);
#else
    	CM_CHAR WIN32_profile[1024] = {0};
    	strcat(&WIN32_profile, p_exe_path);
    	strcat(&WIN32_profile, FS_FILE_PATH);
    	rt = ProtclInitFunc((CM_UINT8*)&WIN32_profile, (CM_UINT32)inParamLen, inParam, &s_OutnetPrtcl);
#endif
        /*- 检查外网安全协议初始化结果 */
        CM_ASSERT(1u == rt, PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_4);

        /*- 初始化应用外网接收、发送缓冲区 */
        (void)CM_Mutex_Init(&s_Outnet_AppSend_M);
        (void)CM_Mutex_Init(&s_Outnet_AppRecv_M);
        ret = CM_QueueInitial(&s_Outnet_AppSendQ, SFM_OUTNETSAFE_BUFF_SIZE);
        CM_ASSERT(ENUM_CM_TRUE == ret, PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_5);
        ret = CM_QueueInitial(&s_Outnet_AppRecvQ, SFM_OUTNETSAFE_BUFF_SIZE);
        CM_ASSERT(ENUM_CM_TRUE == ret, PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_6);

        /*fs_init(FS_FILE_PATH);*/
    }
    else
	{
		/*- 无处理*/
	}
}
/**
* @breif 内网安全协议初始化(sfp)
* @param p_SfpInnetPara内网协议buf
* @details
* 内网安全协议的初始化
* 初始化失败将宕机
*/
void SFM_PrtclInInit(CM_UINT8* p_SfpInnetPara)
{
    /*- 变量初始化 */
    CM_UINT8 rt = 0u; /* 函数返回值 */
    CM_UINT16 InnetID = g_PFM_Cfg.INNET_ID_RM;   /* 远程部署内网ID */
    ENUM_CM_RETURN ret = ENUM_CM_FALSE;
    CM_UINT16 InnetID1 = g_PFM_Cfg.INNET_ID;   /* 内网ID */
    /*- 入参是否为空 */
    if ((0x55u == g_PFM_Cfg.M_InnetSafe_Enable) && (NULL != p_SfpInnetPara))
    {
    	/*- 内网安全协议初始化*/
    	CM_NM_ASSERT(0u != InnetID1, PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_17, TSCP_DARK_ASSERT_9);
        s_InnetPrtcl.LocalID = (CM_UINT8)(InnetID1 % 256u);
        s_InnetPrtcl.LocalType = (CM_UINT8)(InnetID1 / 256u);
        s_InnetPrtcl.TimeCounter = &g_MSCP_SysCount;
        s_InnetPrtcl.RedundTimeout = 0xFFFFu;
        s_InnetPrtcl.OutputTimeout = 0xFFFFu;
        s_InnetPrtcl.DataBase = p_SfpInnetPara;
        s_InnetPrtcl.MaxNumLink = 10u;
        s_InnetPrtcl.MaxNumPerCycle = 5u;
        s_InnetPrtcl.InputSize = 5000u;
        s_InnetPrtcl.OutputSize = 5000u;
        s_InnetPrtcl.OutnetQueueSize = 65000u;
        s_InnetPrtcl.RecordArraySize = 65000u;
        s_InnetPrtcl.CycleNum = &g_MSCP_SysCount;
        rt = ProtclInit(0u, (CM_UINT32)0u, NULL, &s_InnetPrtcl);
        /*- 检查外网安全协议初始化结果 */
        CM_NM_ASSERT(1u == rt, PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_17, TSCP_DARK_ASSERT_6);

        /*- 初始化应用内网接收、发送缓冲区*/
        (void)CM_Mutex_Init(&s_Innet_AppSend_M);
        (void)CM_Mutex_Init(&s_Innet_AppRecv_M);
        ret = CM_QueueInitial(&s_Innet_AppSendQ, SFM_INNETSAFE_BUFF_SIZE);
        CM_NM_ASSERT(ENUM_CM_TRUE == ret, PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_17, TSCP_DARK_ASSERT_7);
        ret = CM_QueueInitial(&s_Innet_AppRecvQ, SFM_INNETSAFE_BUFF_SIZE);
        CM_NM_ASSERT(ENUM_CM_TRUE == ret, PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_17, TSCP_DARK_ASSERT_8);
    }
    else
    {
    	/*- 无处理*/
    }

    /*- 入参是否为空 */
    if ((0x55u == g_PFM_Cfg.M_RemoteUpdate_Enable) &&(0x00u != g_Maintenance_Id) && (NULL != p_SfpInnetPara))
    {
    	/*- 远程部署内网安全协议初始化*/
    	CM_NM_ASSERT(0u != InnetID, PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_17, TSCP_DARK_ASSERT_1);
        s_InnetPrtcl_RM.LocalID = (CM_UINT8)(InnetID % 256u);
        s_InnetPrtcl_RM.LocalType = (CM_UINT8)(InnetID / 256u);
        s_InnetPrtcl_RM.TimeCounter = &g_MSCP_SysCount;
        s_InnetPrtcl_RM.RedundTimeout = 0xFFFFu;
        s_InnetPrtcl_RM.OutputTimeout = 0xFFFFu;
        s_InnetPrtcl_RM.DataBase = p_SfpInnetPara;
        s_InnetPrtcl_RM.MaxNumLink = 10u;
        s_InnetPrtcl_RM.MaxNumPerCycle = 5u;
        s_InnetPrtcl_RM.InputSize = 5000u;
        s_InnetPrtcl_RM.OutputSize = 5000u;
        s_InnetPrtcl_RM.OutnetQueueSize = 65000u;
        s_InnetPrtcl_RM.RecordArraySize = 65000u;
        s_InnetPrtcl_RM.CycleNum = &g_MSCP_SysCount;
        rt = ProtclInit(0u, (CM_UINT32)0u, NULL, &s_InnetPrtcl_RM);
        /*- 检查外网安全协议初始化结果 */
        CM_NM_ASSERT(1u == rt, PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_17, TSCP_DARK_ASSERT_2);

        /*- 初始化应用内网接收、发送缓冲区*/
        (void)CM_Mutex_Init(&s_Innet_RmSend_M);
		(void)CM_Mutex_Init(&s_Innet_AppRmSend_M);
        (void)CM_Mutex_Init(&s_Innet_RmRecv_M);
        ret = CM_QueueInitial(&s_Innet_RmSendQ, SFM_INNETSAFE_RM_BUFF_SIZE);
        CM_NM_ASSERT(ENUM_CM_TRUE == ret,PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_17, TSCP_DARK_ASSERT_3);
		ret = CM_QueueInitial(&s_Innet_AppRmSendQ, SFM_INNETSAFE_RM_BUFF_SIZE);
		CM_NM_ASSERT(ENUM_CM_TRUE == ret,PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_17, TSCP_DARK_ASSERT_4);
        ret = CM_QueueInitial(&s_Innet_RmRecvQ, SFM_INNETSAFE_RM_BUFF_SIZE);
        CM_NM_ASSERT(ENUM_CM_TRUE == ret, PRTCL_MODE,DARK_FAULT_CODE_FUN_ORDER_17, TSCP_DARK_ASSERT_5);
    }
    else
    {
    	/*- 无处理*/
    }
}

/**
* @brief 内网安全数据接收
* @param Buf     接收内网安全数据指针
* @param BufSize 接收内网安全数据缓冲区大小
* @return 收到的内网安全数据总长度
* @details
* 从通信层获取本周期内网安全输入数据
* 按内网安全接收帧打包后交给平台层
*/
CM_INT32 SFM_RxInnetSafe(OUT CM_UINT8 Buf[], IN CM_UINT32 BufSize)
{
    /*- 变量初始化 */
    CM_INT32 rxLen = 0;     /* 接收报文长度 */
    CM_INT32 i = 0;         /* 循环变量 */
    CM_UINT32 srcIP = 0u;   /* 源IP */
    CM_UINT16 srcPort = 0u; /* 源ID */
    STRU_PFM_INNET_CFG_T* pCom = NULL; /* 内网通信配置 */
    CM_ASSERT(NULL != Buf, PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
    /*- 循环接收内网通信数据 */
    do
    {
        /*- 从通信层接收内网通信数据 */
        rxLen = CFM_InnetSafe_Recv(&Buf[i + 2u], CM_UNSIGNED_INT_EXP(BufSize - (CM_UINT32)i - 2u), &srcIP, &srcPort); /* parasoft-suppress MISRA2004-17_1 "指针运算提高代码执行效率" */
        /*- 收到的数据长度是否大于0 */
        if (0 < rxLen)
        {
            /*- 根据源IP、Port确定源ID */
            pCom = PFM_INI_InnetIP2Addr(srcIP, srcPort);
            CM_ASSERT(NULL != pCom, PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_2);

            /*- 打包成内网输入帧 */
            CM_ShortToChar((CM_UINT16)(rxLen), &Buf[i]); /* parasoft-suppress MISRA2004-17_1 "指针运算提高代码执行效率" */

            i += rxLen + 2;
        }
        else
    	{
    		/*- 无处理*/
    	}
    } while (0 < rxLen);
	(void)CFM_DarkLog_Storage(DARK_LOG_HEX, TSCP_DARK_CFMNET_INNETSAFE_RECVLEN, 4U, &i);
    /*- 返回内网输入帧总长度 */
    return i;
}

/**
* @brief 远程部署内网安全数据接收
* @param Buf     接收内网安全数据指针
* @param BufSize 接收内网安全数据缓冲区大小
* @return 收到的内网安全数据总长度
* @details
* 从通信层获取本周期内网安全输入数据
* 按内网安全接收帧打包后交给平台层
*/
CM_INT32 SFM_RxInnetSafeRm(OUT CM_UINT8 Buf[], IN CM_UINT32 BufSize)
{
    /*- 变量初始化 */
    CM_INT32 rxLen = 0;     /* 接收报文长度 */
    CM_INT32 i = 0;         /* 循环变量 */
    CM_UINT32 srcIP = 0u;   /* 源IP */
    CM_UINT16 srcPort = 0u; /* 源ID */
    STRU_PFM_INNET_CFG_T* pCom = NULL; /* 内网通信配置 */
    CM_NM_ASSERT(NULL != Buf, PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_18, TSCP_DARK_ASSERT_1);
    /*- 循环接收内网通信数据 */
    do
    {
        /*- 从通信层接收内网通信数据 */
        rxLen = CFM_InnetSafeRm_Recv(&Buf[i + 2u], CM_UNSIGNED_INT_EXP(BufSize - (CM_UINT32)i - 2u), &srcIP, &srcPort); /* parasoft-suppress MISRA2004-17_1 "指针运算提高代码执行效率" */
        /*- 收到的数据长度是否大于0 */
        if (0 < rxLen)
        {
            /*- 根据源IP、Port确定源ID */
            pCom = PFM_INI_InnetIP2Addr(srcIP, srcPort);
            CM_NM_ASSERT(NULL != pCom, PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_18, TSCP_DARK_ASSERT_2);

            /*- 打包成内网输入帧 */
            CM_ShortToChar((CM_UINT16)(rxLen), &Buf[i]); /* parasoft-suppress MISRA2004-17_1 "指针运算提高代码执行效率" */

            i = i + rxLen + 2;
        }
        else
    	{
    		/*- 无处理*/
    	}
    } while (0 < rxLen);
	(void)CFM_DarkLog_Storage(DARK_LOG_HEX, TSCP_DARK_CFMNET_INNETSAFERM_RECVLEN, 4U, &i);
    /*- 返回内网输入帧总长度 */
    return i;
}

/**
* @brief 内网远程部署安全数据接收
* @param Buf     接收内网安全数据指针
* @param BufSize 接收内网安全数据缓冲区大小
* @return 收到的内网安全数据总长度
* @details
* 从通信层获取本周期内网安全输入数据
* 按内网安全接收帧打包后交给平台层
*/
CM_INT32 SFM_RxInnetRemoteUpdate(OUT CM_UINT8 Buf[], IN CM_UINT32 BufSize)
{
    /*- 变量初始化 */
    CM_INT32 rxLen = 0;     /* 接收报文长度 */
    CM_INT32 i = 0;         /* 循环变量 */
    CM_UINT32 srcIP = 0u;   /* 源IP */
    CM_UINT16 srcPort = 0u; /* 源ID */
    STRU_PFM_INNET_CFG_T* pCom = NULL; /* 内网通信配置 */
	if (NULL != Buf)
	{
	    /*- 循环接收内网通信数据 */
	    do
	    {
	        /*- 从通信层接收内网通信数据 */
	        rxLen = CFM_InnetRemoteUpdate_Recv(&Buf[i + 2u], CM_UNSIGNED_INT_EXP(BufSize - (CM_UINT32)i - 2u), &srcIP, &srcPort); /* parasoft-suppress MISRA2004-17_1 "指针运算提高代码执行效率" */
	        /*- 收到的数据长度是否大于0 */
	        if (0 < rxLen)
	        {
	            /*- 根据源IP、Port确定源ID */
	            pCom = PFM_INI_RmInnetIP2Addr(srcIP, srcPort);
				if (NULL != pCom)
				{
		            /*- 打包成内网输入帧 */
		            CM_ShortToChar((CM_UINT16)(rxLen), &Buf[i]); /* parasoft-suppress MISRA2004-17_1 "指针运算提高代码执行效率" */
		            MSCP_LOG_MSG("SFM_RxInnetRemoteUpdate yes recv \n");
		            i = i + rxLen + 2;					
				}
				else
				{
					MSCP_LOG_MSG("SFM_RxInnetRemoteUpdate  PFM_INI_InnetIP2Addr Is Null!!! \n");
				}
	        }
	        else
	    	{
	        	MSCP_LOG_MSG("SFM_RxInnetRemoteUpdate no recv \n");
	    		/*- 无处理*/
	    	}
	    } while (0 < rxLen);
		(void)CFM_DarkLog_Storage(DARK_LOG_HEX, TSCP_DARK_CFMNET_INNETREMOTEUPDATE_RECVLEN, 4U, &i);		
	}
	else
	{
		MSCP_LOG_MSG("SFM_RxInnetRemoteUpdate  Buf Is Null!!! \n");
	}
    /*- 返回内网输入帧总长度 */
    return i;
}

/**
* @brief 外网安全数据接收
* @param Buf     接收外网安全数据指针
* @param BufSize 接收外网安全数据缓冲区大小
* @return 收到的外网安全数据帧长度
* @details
* 从通信层获取本周期外网安全输入数据
* 按外网接收帧打包后交给平台层
*/
CM_INT32 SFM_RxOutnetSafe(OUT CM_UINT8 buf[], IN CM_UINT32 bufSize)
{
    /*- 变量初始化 */
    ENUM_OUTNET_CHN_T ch = ENUM_OUTNET_ERROR; /* 通道类型 */
    CM_INT32 allLen = 0;     /* 报文总长 */
    CM_INT32 rxLen = 0;      /* 接收报文长度 */
    CM_UINT8 ccVer = 0u;     /* CC版本 */
    /*CM_UINT32 hlhtID = 0u;   互联互通ID */
    CM_UINT16 srcID = 0u;    /* 设备ID */
    CM_UINT16 logicID = 0u;  /* 逻辑ID */
    CM_UINT16 msgLen = 0u;   /* 报文长度 */
    CM_UINT16 appLen = 0u;   /* 用户数据长度 */
    CM_UINT32 redLen = 0u;   /* 红网报文总长 */
    CM_UINT32 blueLen = 0u;  /* 蓝网报文总长 */
    /* 来在通控的非法数据test mod */
    CM_UINT16 potoType = 0u;
    CM_UINT16 dataType = 0u;
    CM_UINT16 potycrc = 0u;
    CM_UINT16 potycrcdata = 0u;
    ENUM_CM_RETURN isTransformInFrame = ENUM_CM_FALSE; /*是否需要改变帧格式*/
    CM_UINT64 rxCtrlLen = 0u;
    /*- 对入参进行防空检查,如果为空则宕机 */
    CM_ASSERT(NULL != buf, PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_3, TSCP_DARK_ASSERT_1);
    /*- 循环接收外网数据 */
    do
    {
        /*- 从通信层接收外网数据 */
        rxLen = CFM_OutnetSafe_Recv(s_Prtcl_UDP_Cache, sizeof(s_Prtcl_UDP_Cache), &ch);
        (rxLen > 0)?(rxCtrlLen += rxLen):rxCtrlLen;
        if(rxCtrlLen > g_PFM_Cfg.OutnetSafePack_Len)
        {
        	CFM_ClearCache();
        	break;
        }

        /*- 接收长度是否大于0 */
        if (0 < rxLen)
        {
			/* TSL星链 主机-底座 用通信协议 */
			/*- 根据外网帧报文头确定源ID */
			/*
			CC外网输入帧
			2字节 长度
			1字节 协议版本
			2字节 设备id
			2字节 逻辑id(预留)
			4字节 目的互联互通ID
			2字节 协议类型 4 -1
			n字节 (安全协议保护的)用户数据
			4字节 CRC
			*/
			msgLen = CM_ShortFromChar(s_Prtcl_UDP_Cache);

			/*- 检查报文长度是否正确 */
			CM_RE_ASSERT((CM_INT32)msgLen == (rxLen - 2), PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_3, TSCP_DARK_ASSERT_2);
			ccVer = s_Prtcl_UDP_Cache[2];

			/*- 判断输入数据是否合法 */
			CM_RE_ASSERT(0u == ccVer, PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_3, TSCP_DARK_ASSERT_3);
			CM_RE_ASSERT(msgLen > 15u, PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_3, TSCP_DARK_ASSERT_4);
			appLen = msgLen - 15u;
			srcID = CM_ShortFromChar(s_Prtcl_UDP_Cache + 3);

			/*- 如果应用没有注册输入ats转车数据备用通道判断函数 */
			if(NULL == p_Serial_IN_VOBC_Func)
			{
				/*- 无处理 */
			}
			else
			{
				/*- 判断该数据是否是ats转车数据  */
				isTransformInFrame = (*p_Serial_IN_VOBC_Func)(srcID);
			}
			logicID = CM_ShortFromChar(s_Prtcl_UDP_Cache + 5);

			/* 来在通控的非法数据test mod */
			potoType = CM_ShortFromChar(s_Prtcl_UDP_Cache + 11);
			dataType = CM_ShortFromChar(s_Prtcl_UDP_Cache + 13);
			if(potoType == 4u)
			{
				potycrc = ComputeMsgCRC16_WL(s_Prtcl_UDP_Cache + 13,appLen-2);
				potycrcdata = CM_ShortFromCharLE(s_Prtcl_UDP_Cache + 13 + appLen - 2);

				if((!(dataType==0x0180U || dataType==0x0190U || dataType==0x0191U || dataType==0x0181U)) || (potycrc != potycrcdata))
				{
					MSCP_LOG_MSG("appLen = %d, dataType = %x, potycrc = %x, potycrcdata = %x \n",appLen,dataType,potycrc,potycrcdata);
				}

			}

			/*- @alias 打包到外网接收协议帧 */
			/*
			2字节 长度
			2字节 设备ID
			2字节 逻辑ID
			n字节 数据
			*/
			/*- 如果是来自红网数据 */
			if ((ENUM_OUTNET_RED == ch) || (ENUM_OUTNET_EXTEND_RED == ch))
			{
				/*- 是否来自ats转车的输入数据 */
				if(ENUM_CM_TRUE == isTransformInFrame)
				{
					/*- 根据ats的包格式解数据 */
					appLen = msgLen - 29u;
					srcID = CM_ShortFromChar(s_Prtcl_UDP_Cache + 19);
					logicID = CM_ShortFromChar(s_Prtcl_UDP_Cache + 21);
					CM_ShortToChar((CM_UINT16)(appLen + 4u), &buf[redLen + 4u]);/* parasoft-suppress MISRA2004-17_1 "指针运算提高代码执行效率" */
					CM_ShortToChar(srcID, &buf[redLen + 6u]);/* parasoft-suppress MISRA2004-17_1 "指针运算提高代码执行效率" */
					CM_ShortToChar(logicID, &buf[redLen + 8u]);/* parasoft-suppress MISRA2004-17_1 "指针运算提高代码执行效率" */
					(void)CM_Memcpy((void*)(&buf[redLen + 10u]), (CM_SIZE_T)CM_UNSIGNED_INT_EXP(bufSize - redLen - 10u), (void*)(s_Prtcl_UDP_Cache + 27), (CM_SIZE_T)(appLen));/* parasoft-suppress MISRA2004-17_1 "指针运算提高代码执行效率" */
				}
				else
				{
					/*- 解源设备逻辑id */
					CM_ShortToChar((CM_UINT16)(appLen + 4u), &buf[redLen + 4u]);/* parasoft-suppress MISRA2004-17_1 "指针运算提高代码执行效率" */
					CM_ShortToChar(srcID, &buf[redLen + 6u]);/* parasoft-suppress MISRA2004-17_1 "指针运算提高代码执行效率" */
					CM_ShortToChar(logicID, &buf[redLen + 8u]);/* parasoft-suppress MISRA2004-17_1 "指针运算提高代码执行效率" */
					(void)CM_Memcpy((void*)(&buf[redLen + 10u]), (CM_SIZE_T)CM_UNSIGNED_INT_EXP(bufSize - redLen - 10u), (void*)(s_Prtcl_UDP_Cache + 13), (CM_SIZE_T)(appLen));/* parasoft-suppress MISRA2004-17_1 "指针运算提高代码执行效率" */
				}
				redLen += (CM_UINT32)appLen + 6u;
			}
			else
			{
				/*- 是否来自ats转车的输入数据 */
				if(ENUM_CM_TRUE == isTransformInFrame)
				{
					/*- 根据ats的包格式解数据 */
					appLen = msgLen - 29u;
					srcID = CM_ShortFromChar(s_Prtcl_UDP_Cache + 19);
					logicID = CM_ShortFromChar(s_Prtcl_UDP_Cache + 21);
					CM_ShortToChar((CM_UINT16)(appLen + 4u), s_TmpCache + blueLen + 4u);
					CM_ShortToChar(srcID, s_TmpCache + blueLen + 6u);
					CM_ShortToChar(logicID, s_TmpCache + blueLen + 8u);
					(void)CM_Memcpy((void*)(s_TmpCache + blueLen + 10u), sizeof(s_TmpCache) - blueLen - 10u, (void*)(s_Prtcl_UDP_Cache + 27u), (CM_SIZE_T)(appLen));
					MSCP_LOG_MSG("srcID = %d, appLen = %d\n", srcID, appLen);
				}
				else
				{
					/*- 解源设备逻辑id */
					CM_ShortToChar((CM_UINT16)(appLen + 4u), s_TmpCache + blueLen + 4u);
					CM_ShortToChar(srcID, s_TmpCache + blueLen + 6u);
					CM_ShortToChar(logicID, s_TmpCache + blueLen + 8u);
					(void)CM_Memcpy((void*)(s_TmpCache + blueLen + 10u), sizeof(s_TmpCache) - blueLen - 10u, (void*)(s_Prtcl_UDP_Cache + 13u), (CM_SIZE_T)(appLen));
				}
				blueLen += (CM_UINT32)appLen + 6u;
			}
        }
        else
    	{
        	/* MSCP_LOG_MSG("No communication with the external network\n"); */
    	}
    } while (0 < rxLen);
    CFM_GetOSCache();
    /* 打包成外网接收帧
    4字节 红网报文总长
    n字节 p个外网协议帧
    4字节 蓝网报文总长
    m字节 q个外网协议帧
    */
    /*- 输出红蓝网的外网接收帧 */
    CM_RE_ASSERT((redLen + blueLen + 8u) <= bufSize, PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_3, TSCP_DARK_ASSERT_6);
    allLen = (CM_INT32)CM_UNSIGNED_INT_EXP(redLen + blueLen + 8u);
    CM_LongToChar(redLen, buf);
    CM_LongToChar(blueLen, &buf[4u + redLen]);     /* parasoft-suppress MISRA2004-17_1 "指针运算提高代码执行效率" */
    (void)CM_Memcpy((void*)(&buf[8u + redLen]), (CM_SIZE_T)CM_UNSIGNED_INT_EXP(bufSize - 8u - redLen), (void*)(s_TmpCache + 4), (CM_SIZE_T)blueLen); /* parasoft-suppress MISRA2004-17_1 "指针运算提高代码执行效率" */
    /*- 返回外网接收帧总长度 */
    return allLen;
}

/*把协议内网帧格式的数据写入协议层*/
void SFM_WriteInnetSafeInput(IN const CM_UINT8 buf[], IN CM_UINT32 len, IN ENUM_INNET_CHN_T ch)
{
	MSCP_LOG_MSG("SFM_WriteInnetSafeInput len = %d\n",len);
	(void)QueueWrite((CM_UINT32)len, buf, &s_InnetPrtcl.OutnetQueueA);
}

/*把远程部署协议内网帧格式的数据写入协议层*/
void SFM_WriteInnetSafeRmInput(IN const CM_UINT8 buf[], IN CM_UINT32 len, IN ENUM_INNET_CHN_T ch)
{
	CM_ASSERT_MAINTAIN(buf != NULL);
	MSCP_LOG_MSG("SFM_WriteInnetSafeRmInput len=%d\n",len);
	(void)QueueWrite((CM_UINT32)len, buf, &s_InnetPrtcl_RM.OutnetQueueA);

}

/**
* @brief 把协议外网帧格式的数据写入协议层
* @param Buf  协议外网接收报文指针
* @param len  协议外网接收报文长度
* @param ch   外网通道类型
*/
void SFM_WriteOutnetSafeInput(IN const CM_UINT8 buf[], IN CM_UINT32 len, IN ENUM_OUTNET_CHN_T ch)
{
	/*- 变量初始化 */
	CM_UINT32 surplusLen = 0u; //剩余数据
	CM_UINT32 currLenBef = 0u; //当前数据
	CM_UINT32 currLenAft = 0u; //当前数据
    /*- 是否为红网报文 */
    if (ENUM_OUTNET_RED == ch)
    {
        /*- 将输入写入协议的红网输入队列 */
    	currLenBef = QueueStatus(&s_OutnetPrtcl.OutnetQueueA);
    	surplusLen = QueueGetSpace(&s_OutnetPrtcl.OutnetQueueA);
    	MSCP_LOG_MSG("Red QueueWrite before:currLen=%d,surplusLen=%d\n",currLenBef,surplusLen);
    	(void)QueueWrite(len, buf, &s_OutnetPrtcl.OutnetQueueA);
    	surplusLen = QueueGetSpace(&s_OutnetPrtcl.OutnetQueueA);//队列剩余多少空间
    	currLenAft = QueueStatus(&s_OutnetPrtcl.OutnetQueueA);//里面多少数据
    	MSCP_LOG_MSG("Red QueueWrite after:currLen=%d,surplusLen=%d\n",currLenAft,surplusLen);
    }
    /*- 是否为蓝网报文 */
    else if (ENUM_OUTNET_BLUE == ch)
    {
        /*- 将输入写入协议的蓝网输入队列 */
    	currLenBef = QueueStatus(&s_OutnetPrtcl.OutnetQueueB);
    	surplusLen = QueueGetSpace(&s_OutnetPrtcl.OutnetQueueB);
    	MSCP_LOG_MSG("Blue QueueWrite before:currLen=%d,surplusLen=%d\n",currLenBef,surplusLen);
    	(void)QueueWrite(len, buf, &s_OutnetPrtcl.OutnetQueueB);
    	surplusLen = QueueGetSpace(&s_OutnetPrtcl.OutnetQueueB);//队列剩余多少空间
    	currLenAft = QueueStatus(&s_OutnetPrtcl.OutnetQueueB);//里面多少数据
    	MSCP_LOG_MSG("Blue QueueWrite after:currLen=%d,surplusLen=%d\n",currLenAft,surplusLen);
    }
    else
    {
        /*- 宕机 */
    	CM_RE_ASSERT(0, PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_4, TSCP_DARK_ASSERT_1);
    }
}

/**
* @brief 协议层解析收到的数据
*/
void SFM_UnPrtclProc(void)
{
	CM_UINT32 QueuelenDataToApp = 0;
    /*- 变量初始化 */
    PFM_CFC_Check(44);
    /*- @alias 外网安全通信协议解析 */
    if (0x55u == g_PFM_Cfg.M_OutnetSafe_Enable)
    {
    	(void)QueueClear(&s_OutnetPrtcl.DataToApp);
    	(void)ProtclReceiveDataFunc(&s_OutnetPrtcl);
    	(void)QueueClear(&s_OutnetPrtcl.OutnetQueueA);
    	(void)QueueClear(&s_OutnetPrtcl.OutnetQueueB);
    }
    else
	{
		/*- 无处理*/
	}
    
    PFM_CFC_Check(45);
    /*- @alias 内网安全通信协议解析 */
    if (0x55u == g_PFM_Cfg.M_InnetSafe_Enable)
    {
    	(void)QueueClear(&s_InnetPrtcl.DataToApp);
        s_InnetPrtcl.RadamSN = SFM_2x2_GetSysCount();
        (void)ProtclReceive(&s_InnetPrtcl);
        (void)QueueClear(&s_InnetPrtcl.OutnetQueueA);
        (void)QueueClear(&s_InnetPrtcl.OutnetQueueB);
    }
    else
	{
		/*- 无处理*/
	}
    PFM_CFC_Check(46);
	/*- @alias 远程部署内网安全通信协议解析 */
    if ((0x55u == g_PFM_Cfg.M_RemoteUpdate_Enable) &&(0x00u != g_Maintenance_Id))
    {
    	(void)QueueClear(&s_InnetPrtcl_RM.DataToApp);
        s_InnetPrtcl_RM.RadamSN = SFM_2x2_GetSysCount();
        (void)ProtclReceive(&s_InnetPrtcl_RM);
        (void)QueueClear(&s_InnetPrtcl_RM.OutnetQueueA);
        (void)QueueClear(&s_InnetPrtcl_RM.OutnetQueueB);

        QueuelenDataToApp = QueueStatus(&s_InnetPrtcl_RM.DataToApp);
        MSCP_LOG_MSG("QueuelenDataToApp = %d\n",QueuelenDataToApp);
    }
    else
	{
		/*- 无处理*/
	}
}

/**
* @brief 接收外网协议报文
* @param pSrcName 源设备ID
* @param pSrcLogicID 源逻辑ID
* @param pLifeTime 报文剩余有效期
* @param rxBuf 收到的应用报文数组
* @param rxSize 接收应用报文的缓冲区（rxBuf）大小，应不小于可能收到的最长应用报文长度
* @return 收到的应用报文长度
* @details
* 每次调用获得一条完整的应用报文
* 每周期应持续调用本函数直到获得的报文长度 *pRxLen == 0
*/
CM_UINT32 Prtcl_OutnetSafe_AppRecv(OUT CM_UINT16* pSrcName, OUT CM_UINT16* pSrcLogicID, OUT CM_UINT8* pLifeTime,
    OUT CM_UINT8* rxBuf, IN CM_UINT32 rxSize)
{
    /*- 变量初始化 */
    CM_UINT8 tmpBuf[2] = { 0u }; /* 临时变量 */
    CM_UINT16 msgLen = 0u;      /* 报文长度 */
    CM_UINT32 qStatus = 0u;     /* 队列状态 */
    CM_UINT32 rt = 0u;           /* 函数返回值 */

    CM_ASSERT(0x55u == g_PFM_Cfg.M_OutnetSafe_Enable, PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_5, TSCP_DARK_ASSERT_1);

    /*- 锁定接收队列 */
    (void)CM_Mutex_Lock(s_Outnet_AppRecv_M);

    qStatus = CM_QueueStatus(&s_Outnet_AppRecvQ);
    /*- 队列中是否有足够长的数据 */
    if (7u < qStatus)
    {
        /*
         * 协议适配层头：
         * 2字节 长度（不含自身）
         * 2字节 源ID
         * 2字节 逻辑ID
         * 1字节 生存时间
         * n字节 数据*/
         /*- 读取协议帧长度 */
    	(void)CM_QueueRead(2u, tmpBuf, &s_Outnet_AppRecvQ);/*长度*/
        msgLen = CM_ShortFromChar(tmpBuf);
        /*- 检查协议帧长度是否合法 */
        if ((msgLen <= (qStatus - 2u)) && (msgLen > 5u) && ((msgLen - 5u) < rxSize))
        {
            /*- 读取和输出协议帧头 */
        	(void)CM_QueueRead(2u, tmpBuf, &s_Outnet_AppRecvQ);/*源ID*/
            *pSrcName = CM_ShortFromChar(tmpBuf);

            (void)CM_QueueRead(2u, tmpBuf, &s_Outnet_AppRecvQ);/*逻辑ID*/
            *pSrcLogicID = CM_ShortFromChar(tmpBuf);

            (void)CM_QueueRead(1u, pLifeTime, &s_Outnet_AppRecvQ);/*生存时间*/

            /*- 读取应用数据 */
            (void)CM_QueueRead(msgLen - 5u, rxBuf, &s_Outnet_AppRecvQ);
            /*- 输出应用数据长度 */
            rt = (CM_UINT32)CM_UNSIGNED_SHORT_EXP(msgLen - 5u);
        }
        else
    	{
    		/*- 无处理*/
			MSCP_LOG_MSG("Outnet Recv, msglen:%d, qstatus:%d, rxsize:%d\n", msgLen, qStatus, rxSize);
    	}
    }
    else
	{
		/*- 无处理*/
		MSCP_LOG_MSG("Outnet Recv, msglen:%d, qstatus:%d, rxsize:%d\n", msgLen, qStatus, rxSize);
	}

    /*- 解锁接收队列 */
    (void)CM_Mutex_Unlock(s_Outnet_AppRecv_M);

    /*- 返回 */
    return rt;
}

/**
* @brief 发送外网协议报文
* @param dstName 目的设备ID
* @param dstLogicID 目的逻辑ID
* @param txBuf 发送的应用报文数组
* @param txLen 发送的应用报文长度
* @return 函数执行结果
* - 1 成功
* - 0 失败(输入非法)
* @details
* 每次调用发送一条完整的应用报文
* 应用每周期可多次调用本函数从而发送多个应用报文，
* 注意总发送长度不要超过周期通信总量限制
*/
CM_UINT8 Prtcl_OutnetSafe_AppSend(IN CM_UINT16 dstName, IN CM_UINT16 dstLogicID, IN const CM_UINT8* txBuf, IN CM_UINT32 txLen)
{
    /*- 变量初始化 */
    CM_UINT16 len = 0u;      /* 长度 */
    CM_UINT8 buf[2u] = { 0u }; /* 临时变量 */
    CM_UINT8 rt = 0u;         /* 函数返回值 */
    ENUM_CM_RETURN temprt = ENUM_CM_TRUE;     /* 临时返回值 */
    CM_ASSERT(0x55u == g_PFM_Cfg.M_OutnetSafe_Enable, PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_6, TSCP_DARK_ASSERT_1);

    /*- 输入长度检查 */
    CM_RE_ASSERT(txLen <= NET_20K_SIZE, PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_6, TSCP_DARK_ASSERT_2);
    /*
    2字节 长度(不含自身)
    2字节 目的ID
    2字节 目的逻辑ID
    n字节 数据
    */

    len = (CM_UINT16)(txLen + 4u);
    CM_ShortToChar(len, buf);

    /*- 锁定发送队列 */
    (void)CM_Mutex_Lock(s_Outnet_AppSend_M);

    /*- 填写协议输出帧头 */
    temprt &= CM_QueueWrite(2u, buf, &s_Outnet_AppSendQ);/*长度*/
    CM_ShortToChar(dstName, buf);
    temprt &= CM_QueueWrite(2u, buf, &s_Outnet_AppSendQ);/*目的ID*/
    CM_ShortToChar(dstLogicID, buf);
    temprt &= CM_QueueWrite(2u, buf, &s_Outnet_AppSendQ);/*目的逻辑ID*/
    /*- 填写应用输出报文 */
    temprt &= CM_QueueWrite(txLen, txBuf, &s_Outnet_AppSendQ);
    if(ENUM_CM_TRUE == temprt)
    {
        rt = 1u;/*成功*/
    }
    else
    {
        rt = 0u;/*失败*/
    }

    /*- 解锁发送队列 */
    (void)CM_Mutex_Unlock(s_Outnet_AppSend_M);

    /*- 返回 */
    return rt;
}

/**
* @brief 接收内网协议报文
* @param pSrcName 源设备ID
* @param pLifeTime 报文剩余有效期
* @param rxBuf 收到的应用报文数组
* @param rxSize 接收应用报文的缓冲区（rxBuf）大小，应不小于可能收到的最长应用报文长度
* @return 收到的应用报文长度
* @details
* 每次调用获得一条完整的应用报文
* 每周期应持续调用本函数直到获得的报文长度 *pRxLen == 0
*/
CM_UINT32 Prtcl_InnetSafe_AppRecv(OUT CM_UINT16* pSrcName, OUT CM_UINT8* pLifeTime, OUT CM_UINT8* rxBuf, IN CM_UINT32 rxSize)
{
    /*- 变量初始化 */
    CM_UINT8 headBuf[7u] = { 0u }; /* 临时变量 */
    CM_UINT16 msgLen = 0u;      /* 报文长度 */
    CM_UINT32 qStatus = 0u;     /* 队列状态 */
    CM_UINT32 rt = 0u;           /* 函数返回值 */

    CM_ASSERT(0x55u == g_PFM_Cfg.M_InnetSafe_Enable, PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_7, TSCP_DARK_ASSERT_1);

    /*- 锁定接收队列 */
    (void)CM_Mutex_Lock(s_Innet_AppRecv_M);

    qStatus = CM_QueueStatus(&s_Innet_AppRecvQ);
    /*- 队列中是否有足够长的数据 */
    if (7u < qStatus)
    {
        /*- 读取协议帧头 */
        /*
        2字节 长度(不含自身)
        2字节 预留
        2字节 源ID(小端)
        1字节 剩余有效时间
        n字节 数据
        */
    	(void)CM_QueueRead(7u, headBuf, &s_Innet_AppRecvQ);/*长度*/
        msgLen = CM_ShortFromChar(headBuf);
        /*- 检查协议帧长度是否合法 */
        if ((msgLen <= (qStatus - 2u)) && (msgLen > 5u) && ((msgLen - 5u) < rxSize))
        {
            *pSrcName = CM_ShortFromCharLE(headBuf + 4u);
            *pLifeTime = headBuf[6];
            (void)CM_QueueRead(msgLen - 5u, rxBuf, &s_Innet_AppRecvQ);
            rt = (CM_UINT32)CM_UNSIGNED_SHORT_EXP(msgLen - 5u);
        }
        else
    	{
    		/*- 无处理*/
			MSCP_LOG_MSG("Innet Recv, msglen:%d, qstatus:%d, rxsize:%d\n", msgLen, qStatus, rxSize);
    	}
    }
    else
	{
		/*- 无处理*/
		MSCP_LOG_MSG("Innet Recv, msglen:%d, qstatus:%d, rxsize:%d\n", msgLen, qStatus, rxSize);
	}

    /*- 解锁接收队列 */
    (void)CM_Mutex_Unlock(s_Innet_AppRecv_M);

    /*- 返回报文长度 */
    return rt;
}

/**
* @brief 发送内网安全协议报文
* @param dstName 目的设备ID
* @param dstLogicID 目的逻辑ID
* @param txBuf 发送的应用报文数组
* @param txLen 发送的应用报文长度
* @return 函数执行结果
* - 1 成功
* - 0 失败(输入非法)
* @details
* 每次调用发送一条完整的应用报文
* 每周期可多次调用本函数从而发送多个应用报文，
* 注意总发送长度不要超过周期通信总量限制
*/
CM_UINT8 Prtcl_InnetSafe_AppSend(IN CM_UINT16 dstName, IN const CM_UINT8* txBuf, IN CM_UINT32 txLen)
{
    /*- 变量初始化 */
    CM_UINT16 len = 0u;      /* 长度 */
    CM_UINT8 buf[2u] = { 0u }; /* 临时变量 */
    CM_UINT8 rt = 0u;         /* 函数返回值 */
    ENUM_CM_RETURN temprt = ENUM_CM_TRUE;     /* 临时返回值 */

    /*- 输入长度检查 */
	if (0x55u == g_PFM_Cfg.M_InnetSafe_Enable && txLen <= NET_20K_SIZE)
	{
	    /*
	    2字节 长度(不含自身)
	    2字节 目的ID(小端)
	    n字节 数据
	    */
	    /*- 锁定发送队列 */
	    (void)CM_Mutex_Lock(s_Innet_AppSend_M);

	    /*- 填写协议输出帧头 */
	    len = (CM_UINT16)(txLen + 4u);
	    CM_ShortToChar(len, buf);
	    temprt &= CM_QueueWrite(2u, buf, &s_Innet_AppSendQ);/*长度*/
	    CM_ShortToCharLE(0u, buf);
	    temprt &= CM_QueueWrite(2u, buf, &s_Innet_AppSendQ);/*2字节预留*/
	    CM_ShortToCharLE(dstName, buf);
	    temprt &= CM_QueueWrite(2u, buf, &s_Innet_AppSendQ);/*目的ID*/
	    /*- 填写应用输出报文 */
	    temprt &= CM_QueueWrite(txLen, txBuf, &s_Innet_AppSendQ);
	    if(ENUM_CM_TRUE == temprt)
	    {
	        rt = 1u;/*成功*/
	    }
	    else
	    {
	        rt = 0u;/*失败*/
	    }

	    /*- 解锁发送队列 */
	    (void)CM_Mutex_Unlock(s_Innet_AppSend_M);		
	}
	else
	{
		/*无处理*/
	}

    /*- 返回 */
    return rt;
}

/**
* @brief 接收远程部署内网协议报文（应用接收）
* @param pSrcName 源设备ID
* @param pLifeTime 报文剩余有效期
* @param rxBuf 收到的应用报文数组
* @param rxSize 接收应用报文的缓冲区（rxBuf）大小，应不小于可能收到的最长应用报文长度
* @return 收到的应用报文长度
* @details
* 每次调用获得一条完整的应用报文
* 每周期应持续调用本函数直到获得的报文长度 *pRxLen == 0
*/
CM_UINT32 Prtcl_InnetSafe_RmRecv(OUT CM_UINT16* pSrcName, OUT CM_UINT8* pLifeTime, OUT CM_UINT8* rxBuf, IN CM_UINT32 rxSize)
{
    /*- 变量初始化 */
    CM_UINT8 headBuf[7u] = { 0u }; /* 临时变量 */
    CM_UINT16 msgLen = 0u;      /* 报文长度 */
    CM_UINT32 qStatus = 0u;     /* 队列状态 */
    CM_UINT32 rt_len = 0u;      /* 函数返回长度值 */
    CM_UINT8 rt = 0u;           /* 函数返回值 */

	if ((0x55u == g_RMUP_Cfg.M_RemoteUpdate_Enable) &&(0x00u != g_Maintenance_Id))
	{
	    /*- 锁定接收队列 */
	    (void)CM_Mutex_Lock(s_Innet_RmRecv_M);

	    qStatus = CM_QueueStatus(&s_Innet_RmRecvQ);
	    MSCP_LOG_MSG("Prtcl_InnetSafe_RmRecv len = %d\n", qStatus);
    	do
    	{
			/*- 队列中是否有足够长的数据 */
			if (7u < qStatus)
			{

				/*- 读取协议帧头 */
				/*
				2字节 长度(不含自身)
				2字节 预留
				2字节 源ID(小端)
				1字节 剩余有效时间
				n字节 数据
				*/
				(void)CM_QueueRead(7u, headBuf, &s_Innet_RmRecvQ);/*长度*/
				msgLen = CM_ShortFromChar(headBuf);
				/*- 检查协议帧长度是否合法 */
				if ((msgLen <= (qStatus - 2u)) && (msgLen > 5u) && ((msgLen - 5u) < rxSize))
				{
					*pSrcName = CM_ShortFromCharLE(headBuf + 4u);
					*pLifeTime = headBuf[6];
					rt_len = (CM_UINT32)CM_UNSIGNED_SHORT_EXP(msgLen - 5u);
					(void)CM_QueueRead(rt_len, rxBuf, &s_Innet_RmRecvQ);

					/*- 解析通信协议，如果是重启或切系命令，执行重启或切系逻辑*/
					rt = PFM_RemoteRun_Data(rxBuf,rt_len);
					/*- 如果是重启命令*/
					if((0xA5 <= rt) && (0xA8 >= rt))
					{
						/*- 平台过滤重启命令*/
						qStatus -= rt_len;
						/*- 长度清零，不给到应用*/
						rt_len = 0u;
					}
					else
					{
						/*- 给到应用数据*/
						break;
					}
				}
				else
				{
					/*- 无处理*/
					MSCP_LOG_MSG("Rm Recv, msglen:%d, qstatus:%d, rxsize:%d\n", msgLen, qStatus, rxSize);
					break;
				}
			}
			else
			{
				/*- 无处理*/
				MSCP_LOG_MSG("Rm Recv, msglen:%d, qstatus:%d, rxsize:%d\n", msgLen, qStatus, rxSize);
				break;
			}
    	}while(1);
	    /*- 解锁接收队列 */
	    (void)CM_Mutex_Unlock(s_Innet_RmRecv_M);	
	}
	else
	{
		/*- 无处理*/
	}

    /*- 返回报文长度 */
    return rt_len;
}

/**
* @brief 接收远程部署内网协议报文（平台退出运营后接收）
* @param pSrcName 源设备ID
* @param pLifeTime 报文剩余有效期
* @param rxBuf 收到的应用报文数组
* @param rxSize 接收应用报文的缓冲区（rxBuf）大小，应不小于可能收到的最长应用报文长度
* @return 收到的应用报文长度
* @details
* 每次调用获得一条完整的应用报文
* 每周期应持续调用本函数直到获得的报文长度 *pRxLen == 0
*/
CM_UINT32 Prtcl_InnetSafe_PlatRmRecv(OUT CM_UINT16* pSrcName, OUT CM_UINT8* pLifeTime, OUT CM_UINT8* rxBuf, IN CM_UINT32 rxSize)
{
    /*- 变量初始化 */
    CM_UINT8 headBuf[7u] = { 0u }; /* 临时变量 */
    CM_UINT16 msgLen = 0u;      /* 报文长度 */
    CM_UINT32 qStatus = 0u;     /* 队列状态 */
    CM_UINT32 rt_len = 0u;      /* 函数返回长度值 */
 	if ((0x55u == g_RMUP_Cfg.M_RemoteUpdate_Enable) &&(0x00u != g_Maintenance_Id))
	{
	    /*- 锁定接收队列 */
	    (void)CM_Mutex_Lock(s_Innet_RmRecv_M);

	    qStatus = CM_QueueStatus(&s_Innet_RmRecvQ);
	    MSCP_LOG_MSG("Prtcl_InnetSafe_PlatRmRecv len = %d\n", qStatus);

		/*- 队列中是否有足够长的数据 */
		if (7u < qStatus)
		{

			/*- 读取协议帧头 */
			/*
			2字节 长度(不含自身)
			2字节 预留
			2字节 源ID(小端)
			1字节 剩余有效时间
			n字节 数据
			*/
			(void)CM_QueueRead(7u, headBuf, &s_Innet_RmRecvQ);/*长度*/
			msgLen = CM_ShortFromChar(headBuf);
			/*- 检查协议帧长度是否合法 */
			if ((msgLen <= (qStatus - 2u)) && (msgLen > 5u) && ((msgLen - 5u) < rxSize))
			{
				*pSrcName = CM_ShortFromCharLE(headBuf + 4u);
				*pLifeTime = headBuf[6];
				rt_len = (CM_UINT32)CM_UNSIGNED_SHORT_EXP(msgLen - 5u);
				(void)CM_QueueRead(rt_len, rxBuf, &s_Innet_RmRecvQ);
			}
			else
			{
				/*- 无处理*/
			}
		}
		else
		{
			/*- 无处理*/
		}
	    /*- 解锁接收队列 */
	    (void)CM_Mutex_Unlock(s_Innet_RmRecv_M);
	}
	else
	{
		/*- 无处理*/
	}

    /*- 返回报文长度 */
    return rt_len;
}


/**
* @brief 应用发送远程部署退出运营确认内网协议报文
* @param txBuf 发送的应用报文数组
* @param txLen 发送的应用报文长度
* @return 函数执行结果
* - 1 成功
* - 0 失败(输入非法)
* @details
*/
CM_UINT8 Prtcl_InnetSafe_AppRmSend(IN const CM_UINT8* txBuf, IN CM_UINT32 txLen)
{
    /*- 变量初始化 */
    CM_UINT8 buf[2u] = { 0u }; /* 临时变量 */
    CM_UINT8 rt = 0u;         /* 函数返回值 */
    ENUM_CM_RETURN temprt = ENUM_CM_TRUE;     /* 临时返回值 */
    CM_ASSERT_MAINTAIN(txBuf != NULL);
	/*- 输入长度检查 */
	if ((0x55u == g_RMUP_Cfg.M_RemoteUpdate_Enable) &&(0x00u != g_Maintenance_Id))
	{
		/*
		2字节 长度(不含自身)
		n字节 数据
		*/
		/*- 锁定发送队列 */
		(void)CM_Mutex_Lock(s_Innet_AppRmSend_M);

		/*- 填写协议输出帧头 */
		CM_ShortToChar(txLen, buf);
		temprt &= CM_QueueWrite(2u, buf, &s_Innet_AppRmSendQ);/*长度*/
		/*- 填写应用输出报文 */
		temprt &= CM_QueueWrite(txLen, txBuf, &s_Innet_AppRmSendQ);
		if(ENUM_CM_TRUE == temprt)
		{
			rt = 1u;/*成功*/
		}
		else
		{
			rt = 0u;/*失败*/
		}

		/*- 解锁发送队列 */
		(void)CM_Mutex_Unlock(s_Innet_AppRmSend_M);
	}
	else
	{
		/*无处理*/
	}
    /*- 返回 */
    return rt;
}

/**
* @brief 发送远程部署内网协议报文
* @param dstName 目的设备ID
* @param dstLogicID 目的逻辑ID
* @param txBuf 发送的应用报文数组
* @param txLen 发送的应用报文长度
* @return 函数执行结果
* - 1 成功
* - 0 失败(输入非法)
* @details
* 每次调用发送一条完整的应用报文
* 平台每周期只能调用本函数一次发送一个远程部署报文，
* 注意总发送长度不要超过周期通信总量限制
*/
CM_UINT8 Prtcl_InnetSafe_RmSend(IN CM_UINT16 dstName, IN const CM_UINT8* txBuf, IN CM_UINT32 txLen)
{
    /*- 变量初始化 */
    CM_UINT16 len = 0u;      /* 长度 */
	CM_UINT16 applen = 0u;      /* 长度 */
    CM_UINT8 buf[2u] = { 0u }; /* 临时变量 */
	CM_UINT8 Buftmp[128] = { 0u }; /* 临时变量 */
    CM_UINT8 rt = 0u;         /* 函数返回值 */
    ENUM_CM_RETURN temprt = ENUM_CM_TRUE;     /* 临时返回值 */

    /*- 输入长度检查 */
	if ((0x55u == g_RMUP_Cfg.M_RemoteUpdate_Enable) &&(0x00u != g_Maintenance_Id))
	{
	    /*- 锁定发送队列 */
	    (void)CM_Mutex_Lock(s_Innet_AppRmSend_M);
		/*- 读取应用帧头 */
		/*
		2字节 长度(不含自身)
		n字节 数据
		*/
		(void)CM_QueueRead(2u, buf, &s_Innet_AppRmSendQ);/*长度*/
		applen = CM_ShortFromChar(buf);

		(void)CM_QueueRead(applen, Buftmp, &s_Innet_AppRmSendQ);/*长度*/

	    /*- 解锁发送队列 */
	    (void)CM_Mutex_Unlock(s_Innet_AppRmSend_M);		
		
	    /*
	    2字节 长度(不含自身)
	    2字节 目的ID(小端)
	    n字节 数据
	    */
	    (void)CM_Mutex_Lock(s_Innet_RmSend_M);

	    /*- 填写协议输出帧头 */
	    len = (CM_UINT16)(txLen + 4u)+applen;
	    CM_ShortToChar(len, buf);
	    temprt &= CM_QueueWrite(2u, buf, &s_Innet_RmSendQ);/*长度*/
	    CM_ShortToCharLE(0u, buf);
	    temprt &= CM_QueueWrite(2u, buf, &s_Innet_RmSendQ);/*2字节预留*/
	    CM_ShortToCharLE(dstName, buf);
	    temprt &= CM_QueueWrite(2u, buf, &s_Innet_RmSendQ);/*目的ID*/
	    /*- 填写应用输出报文 */
	    temprt &= CM_QueueWrite(txLen, txBuf, &s_Innet_RmSendQ);
	    if(ENUM_CM_TRUE == temprt)
	    {
	       	temprt &= CM_QueueWrite(applen, Buftmp, &s_Innet_RmSendQ);
		    if(ENUM_CM_TRUE == temprt)
		    {
		        rt = 1u;/*成功*/
		    }
		    else
		    {
		        rt = 0u;/*失败*/
		    }
	    }
	    else
	    {
	        rt = 0u;/*失败*/
	    }

	    /*- 解锁发送队列 */
	    (void)CM_Mutex_Unlock(s_Innet_RmSend_M);		
	}
	else
	{
		/*无处理*/
	}

    /*- 返回 */
    return rt;
}

/**
* @brief 协议层封装待发送数据
*/
void SFM_EnPrtclProc(void)
{
    CM_UINT16 local_len = 0u;
    CM_UINT8 local_buf[1500u] = {0u};
    CM_UINT16 peer_len = 0u;
    CM_UINT8 p_peer_buf[1500u] = {0u};
    CM_UINT32 len1 = 0u;
    CM_UINT32 len2 = 0u;
    /*- 协议层封装待发送外网数据 */
    PFM_CFC_Check(3);
    if (0x55u == g_PFM_Cfg.M_OutnetSafe_Enable)
    {
        CM_LongToChar(0u, s_OutnetPrtcl.AppArray);
        CM_LongToChar(0u, s_OutnetPrtcl.RecordArray);
        (void)ProtclSendDataFunc(&s_OutnetPrtcl);
        (void)QueueClear(&s_OutnetPrtcl.OutputDataQueue);
        /*- 是否开启2oo2功能 */
        if (0x55u == g_PFM_Cfg.M_2oo2_Enable)
        {
            /*- 双CPU交换SVC */
            (void)ProtclGetSwapData(local_buf,1500u,&s_OutnetPrtcl);
            local_len = 2u + CM_ShortFromChar(local_buf);
            CM_RE_ASSERT(local_len <= sizeof(local_buf), PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_9, TSCP_DARK_ASSERT_1);
            peer_len = (CM_UINT16)SFM_2oo2_Exchange_Currency(local_buf, (CM_INT32)local_len, p_peer_buf, sizeof(p_peer_buf), ENUM_2oo2_OUTPUT_EX);
            (void)ProtclSetSwapData(p_peer_buf,&s_OutnetPrtcl);
        }
        else
    	{
    		/*- 无处理*/
    	}
    }
    else
	{
		/*- 无处理*/
	}

    /*- 内网安全协议封装 */
    PFM_CFC_Check(4);
    if (0x55u == g_PFM_Cfg.M_InnetSafe_Enable)
    {
        CM_LongToChar(0u, s_InnetPrtcl.PrtclSndBuff);
        CM_LongToChar(0u, s_InnetPrtcl.RecordArray);
        (void)ProtclOutput(&s_InnetPrtcl);
        (void)QueueClear(&s_InnetPrtcl.OutputDataQueue);
        /*- 是否开启2oo2功能 */
        if (0x55u == g_PFM_Cfg.M_2oo2_Enable)
        {
            /*- 双CPU交换SVC */
            (void)SfpGetSwapData(local_buf,1500u,&s_InnetPrtcl);
            local_len = 2u + CM_ShortFromChar(local_buf);
            CM_RE_ASSERT(local_len <= sizeof(local_buf), PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_9, TSCP_DARK_ASSERT_2);
            peer_len = (CM_UINT16)SFM_2oo2_Exchange_Currency(local_buf, (CM_INT32)local_len, p_peer_buf, sizeof(p_peer_buf), ENUM_2oo2_OUTPUT_EX);
            (void)SfpSetSwapData(p_peer_buf,&s_InnetPrtcl);
        }
        else
    	{
    		/*- 无处理*/
    	}
    }
    else
	{
		/*- 无处理*/
	}

	/*- 远程部署内网安全协议封装 */
    if ((0x55u == g_PFM_Cfg.M_RemoteUpdate_Enable) &&(0x00u != g_Maintenance_Id))
    {
        CM_LongToChar(0u, s_InnetPrtcl_RM.PrtclSndBuff);
        CM_LongToChar(0u, s_InnetPrtcl_RM.RecordArray);
        (void)ProtclOutput(&s_InnetPrtcl_RM);
        (void)QueueClear(&s_InnetPrtcl_RM.OutputDataQueue);

        len1 = CM_LongFromChar(s_InnetPrtcl_RM.PrtclSndBuff);
        len2 = CM_LongFromChar(s_InnetPrtcl_RM.RecordArray);
        MSCP_LOG_MSG("s_InnetPrtcl_RM.PrtclSndBuff = %d, s_InnetPrtcl_RM.RecordArray = %d\n",len1,len2);
        /*- 是否开启2oo2功能 */
        if (0x55u == g_PFM_Cfg.M_2oo2_Enable)
        {
            /*- 双CPU交换SVC */
            (void)SfpGetSwapData(local_buf,1500u,&s_InnetPrtcl_RM);
            local_len = 2u + CM_ShortFromChar(local_buf);
            CM_RE_ASSERT(local_len <= sizeof(local_buf), PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_9, TSCP_DARK_ASSERT_3);
            peer_len = (CM_UINT16)SFM_2oo2_Exchange_Currency(local_buf, (CM_INT32)local_len, p_peer_buf, sizeof(p_peer_buf), ENUM_2oo2_OUTPUT_EX);
            (void)SfpSetSwapData(p_peer_buf,&s_InnetPrtcl_RM);
        }
        else
    	{
    		/*- 无处理*/
    	}
    }
    else
	{
		/*- 无处理*/
	}
}

/**
* @brief 从协议适配层读取协议内网输出帧
* @param Buf 输出报文缓冲区指针
* @param BufSize 输出报文缓冲区大小
* @return 输出报文总长度
*/
CM_UINT32 SFM_ReadInnetCodedOutput(OUT CM_UINT8 Buf[], IN CM_UINT32 BufSize)
{
    /*
     * 格式：
     * 4字节总长度 | 4字节内网输出报文长度 | 内网输出帧1 | 内网输出帧2 …… 内网输出帧n | 4字节日志报文长度 | n字节日志报文 |
     * 内网输出帧: 2字节帧长度 + 1字节协议类型 + 2字节目的ID(大端) + 2字节预留 + n字节数据
     */
     /*- 获取输出报文总长度 */
    CM_UINT32 len = CM_LongFromChar(s_InnetPrtcl.PrtclSndBuff);
    CM_RE_ASSERT(BufSize >= 4u, PRTCL_MODE,DARK_FAULT_CODE_FUN_ORDER_19, TSCP_DARK_ASSERT_1);
    CM_RE_ASSERT(len <= (BufSize - 4u), PRTCL_MODE,DARK_FAULT_CODE_FUN_ORDER_19, TSCP_DARK_ASSERT_2);
    /*- 输出全部输出报文 */
    (void)CM_Memcpy((void*)Buf, (CM_SIZE_T)BufSize, (void*)s_InnetPrtcl.PrtclSndBuff, (CM_SIZE_T)CM_UNSIGNED_INT_EXP(len + 4u));

    /*- 返回输出报文总长度 */
    return len + 4u ;
}

/**
* @brief 从协议适配层读取协议内网远程部署输出帧
* @param Buf 输出报文缓冲区指针
* @param BufSize 输出报文缓冲区大小
* @return 输出报文总长度
*/
CM_UINT32 SFM_ReadInnetRmCodedOutput(OUT CM_UINT8 Buf[], IN CM_UINT32 BufSize)
{
    /*
     * 格式：
     * 4字节总长度 | 4字节内网输出报文长度 | 内网输出帧1 | 内网输出帧2 …… 内网输出帧n | 4字节日志报文长度 | n字节日志报文 |
     * 内网输出帧: 2字节帧长度 + 1字节协议类型 + 2字节目的ID(大端) + 2字节预留 + n字节数据
     */
     /*- 获取输出报文总长度 */
	CM_UINT32 len = 0u;
	if ((0x55u == g_PFM_Cfg.M_RemoteUpdate_Enable) &&(0x00u != g_Maintenance_Id))
	{
	    len = CM_LongFromChar(s_InnetPrtcl_RM.PrtclSndBuff);
	    CM_RE_ASSERT(BufSize >= 4u,PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_21, TSCP_DARK_ASSERT_1);
	    CM_RE_ASSERT(len <= (BufSize - 4u), PRTCL_MODE,DARK_FAULT_CODE_FUN_ORDER_21, TSCP_DARK_ASSERT_2);
	    /*- 输出全部输出报文 */
	    (void)CM_Memcpy((void*)Buf, (CM_SIZE_T)BufSize, (void*)s_InnetPrtcl_RM.PrtclSndBuff, (CM_SIZE_T)CM_UNSIGNED_INT_EXP(len + 4u));		
	}
	else
	{
        CM_Memset((void*)Buf,0u, 4u,(CM_SIZE_T)BufSize);
	}
    /*- 返回输出报文总长度 */
    return len + 4u ;
}

/**
* @brief 从协议适配层读取协议内网输出帧（宕机情况调用）
* @param Buf 输出报文缓冲区指针
* @param BufSize 输出报文缓冲区大小
* @return 输出报文总长度
*/
CM_UINT32 SFM_ReadInnetCodedOutputCrash(OUT CM_UINT8 Buf[], IN CM_UINT32 BufSize)
{
	ENUM_CM_RETURN ret = ENUM_CM_FALSE; /* 函数返回值 */
    /*
     * 格式：
     * 4字节总长度 | 4字节内网输出报文长度 | 内网输出帧1 | 内网输出帧2 …… 内网输出帧n | 4字节日志报文长度 | n字节日志报文 |
     * 内网输出帧: 2字节帧长度 + 1字节协议类型 + 2字节目的ID(大端) + 2字节预留 + n字节数据
     */
     /*- 获取输出报文总长度 */
    CM_UINT32 len = CM_LongFromChar(s_InnetPrtcl_RM.PrtclSndBuff);
    MSCP_LOG_MSG("SFM_ReadInnetCodedOutputCrash len3 = %d\n",len);
	if (BufSize >= 4u && len <= (BufSize - 4u))
	{
	    /*- 输出全部输出报文 */
		ret = CM_Memcpy((void*)Buf, (CM_SIZE_T)BufSize, (void*)s_InnetPrtcl_RM.PrtclSndBuff, (CM_SIZE_T)CM_UNSIGNED_INT_EXP(len + 4u));
		CM_ASSERT_MAINTAIN(ret == ENUM_CM_TRUE);
	}
	else
	{
		MSCP_LOG_MSG("SFM_ReadInnetCodedOutputCrash  BufSize is %u error!!! \n",BufSize);
	}
    /*- 返回输出报文总长度 */
    return len + 4u;
}

/**
* @brief 从协议适配层读取协议外网输出帧
* @param Buf 输出报文缓冲区指针
* @param BufSize 输出报文缓冲区大小
* @return 输出报文总长度
*/
CM_UINT32 SFM_ReadOutnetCodedOutput(OUT CM_UINT8 Buf[], IN CM_UINT32 BufSize)
{
    /*
     * 格式：
     * 4字节总长度 | 外网输出帧1 | 外网输出帧2 ……
     * 外网输出帧：2字节长度 + 1字节协议类型 + 2字节目的ID + 2字节逻辑ID + n字节数据
     */
     /*- 获取输出报文总长度 */
    CM_UINT32 len = CM_LongFromChar(s_OutnetPrtcl.AppArray);
    CM_RE_ASSERT(BufSize >= 4u, PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_11, TSCP_DARK_ASSERT_1);
    CM_RE_ASSERT(len <= (BufSize - 4u), PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_11, TSCP_DARK_ASSERT_2);
    /*- 输出全部输出报文 */
    (void)CM_Memcpy((void*)Buf, (CM_SIZE_T)BufSize, (void*)s_OutnetPrtcl.AppArray, (CM_SIZE_T)CM_UNSIGNED_INT_EXP(len + 4u));
    /*- 返回输出报文总长度 */
    return len + 4u;
}

/**
* @brief 发送内网安全通信数据
* @param buf 输出数据数组
* @param Len 输出数据长度
* @details 输出数据数组按照内网SFP协议输出报文结构组织
*/
void SFM_TxInnetSafe(IN CM_UINT8 Buf[], IN CM_UINT32 Len)
{
    /*- 变量初始化 */
    CM_UINT32 allLen = CM_LongFromChar(Buf); /*外网输出帧报文总长度*/
    CM_UINT32 dataLen = 0u;
    CM_UINT32 dataEnd = 0u;
    CM_UINT32 i = 0u;              /* 循环变量 */
    CM_UINT16 msgLen = 0u;         /* 外网输出帧长度 */
    CM_UINT16 dstID = 0u;          /* 目的设备ID */
    STRU_PFM_INNET_CFG_T* pCom = NULL;/* 通信配置 */

    CM_RE_ASSERT((allLen + 4u) == Len, PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_12, TSCP_DARK_ASSERT_1);

    dataLen = CM_LongFromChar(&Buf[4u]);
    dataEnd = dataLen + 8u;

    i = 8u;
    /*- 遍历输出队列 */
    while ((i + 7u) < dataEnd)
    {
        /*
        协议外网输出帧头
        2字节 长度
        1字节 协议类型
        2字节 目的ID
        2字节 预留
        n字节 数据
        */
        /*- 解析协议内网输出帧头 */
        msgLen = CM_ShortFromChar(&Buf[i]);           /* 2字节 帧长度 */      /* parasoft-suppress MISRA2004-17_1 "指针运算提高代码执行效率" */
        /* Buf[i + 2u]; */                            /* 1字节 协议类型 */
        dstID = CM_ShortFromChar(&Buf[i + 3u]);       /* 2字节 目的ID */     /* parasoft-suppress MISRA2004-17_1 "指针运算提高代码执行效率" */
        (void)CM_ShortFromChar(&Buf[i + 5u]);          /* 2字节 (逻辑id) */

        CM_RE_ASSERT(msgLen > 5u, PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_12, TSCP_DARK_ASSERT_2);
        CM_RE_ASSERT(msgLen <= (Len - i - 2u), PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_12, TSCP_DARK_ASSERT_3);
        CM_RE_ASSERT(msgLen <= NET_20K_SIZE, PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_12, TSCP_DARK_ASSERT_4);

        /*- 获取目的IP端口 */
        pCom = PFM_INI_InnetID2Addr(dstID);
        /*- 是否获取成功 */
        if (NULL != pCom)
        {
            /*- 本机是否为CPU1 */
            if (1u == g_PFM_Cfg.CPU_ID)
            {
                /*- 从绿网通道发送 */
                (void)CFM_InnetSafe_Send(&Buf[i + 7u], (CM_INT32)CM_UNSIGNED_SHORT_EXP(msgLen - 5u), pCom->IP_G, pCom->Port_Safe_G);   /* parasoft-suppress MISRA2004-17_1 "指针运算提高代码执行效率" */
            }
            else
            {
                /*- 从紫网通道发送 */
                (void)CFM_InnetSafe_Send(&Buf[i + 7u], (CM_INT32)CM_UNSIGNED_SHORT_EXP(msgLen - 5u), pCom->IP_P, pCom->Port_Safe_P);   /* parasoft-suppress MISRA2004-17_1 "指针运算提高代码执行效率" */
            }
        }
        else
    	{
    		/*- 无处理*/
    	}
        i += (CM_UINT32)CM_UNSIGNED_SHORT_EXP(msgLen + 2u);
    }
}
/**
* @brief 发送内网安全远程部署通信数据
* @param buf 输出数据数组
* @param Len 输出数据长度
* @details 输出数据数组按照内网SFP协议输出报文结构组织
*/
void SFM_TxInnetSafeRm(IN CM_UINT8 Buf[], IN CM_UINT32 Len)
{
    /*- 变量初始化 */
    CM_UINT32 allLen = 0u; /*外网输出帧报文总长度*/
    CM_UINT32 dataLen = 0u;
    CM_UINT32 dataEnd = 0u;
    CM_UINT32 i = 0u;              /* 循环变量 */
    CM_UINT16 msgLen = 0u;         /* 外网输出帧长度 */
    CM_UINT16 dstID = 0u;          /* 目的设备ID */
    STRU_PFM_INNET_CFG_T* pCom = NULL;/* 通信配置 */
    ENUM_CM_RETURN ret = ENUM_CM_FALSE;

	if ((0x55u == g_PFM_Cfg.M_RemoteUpdate_Enable) &&(0x00u != g_Maintenance_Id))
	{
		allLen = CM_LongFromChar(Buf); /*外网输出帧报文总长度*/
		CM_RE_ASSERT((allLen + 4u) == Len,PRTCL_MODE,DARK_FAULT_CODE_FUN_ORDER_20, TSCP_DARK_ASSERT_1);

		dataLen = CM_LongFromChar(&Buf[4u]);
		dataEnd = dataLen + 8u;

		i = 8u;
		/*- 遍历输出队列 */
		while ((i + 7u) < dataEnd)
		{
			/*
			协议外网输出帧头
			2字节 长度
			1字节 协议类型
			2字节 目的ID
			2字节 预留
			n字节 数据
			*/
			/*- 解析协议内网输出帧头 */
			msgLen = CM_ShortFromChar(&Buf[i]);           /* 2字节 帧长度 */      /* parasoft-suppress MISRA2004-17_1 "指针运算提高代码执行效率" */
			/* Buf[i + 2u]; */                            /* 1字节 协议类型 */
			dstID = CM_ShortFromChar(&Buf[i + 3u]);       /* 2字节 目的ID */     /* parasoft-suppress MISRA2004-17_1 "指针运算提高代码执行效率" */
			(void)CM_ShortFromChar(&Buf[i + 5u]);          /* 2字节 (逻辑id) */

			CM_RE_ASSERT(msgLen > 5u, PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_20, TSCP_DARK_ASSERT_2);
			CM_RE_ASSERT(msgLen <= (Len - i - 2u),PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_20, TSCP_DARK_ASSERT_3);
			CM_RE_ASSERT(msgLen <= NET_20K_SIZE,PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_20, TSCP_DARK_ASSERT_4);

			/*- 获取目的IP端口 */
			pCom = PFM_INI_InnetID2Addr(dstID);
			/*- 是否获取成功 */
			if (NULL != pCom)
			{
				if (g_Maintenance_Id == dstID)
				{
					/*- 远程部署维护终端设备 */
					/*- 本机是否为CPU1 */
					if (1u == g_PFM_Cfg.CPU_ID)
					{
						/*- 从绿网通道发送 */
						ret = CFM_InnetRemoteUpdate_Send(&Buf[i + 7u], (CM_INT32)CM_UNSIGNED_SHORT_EXP(msgLen - 5u), pCom->IP_G, pCom->Port_Safe_G);   /* parasoft-suppress MISRA2004-17_1 "指针运算提高代码执行效率" */
					}
					else
					{
						/*- 从紫网通道发送 */
						ret = CFM_InnetRemoteUpdate_Send(&Buf[i + 7u], (CM_INT32)CM_UNSIGNED_SHORT_EXP(msgLen - 5u), pCom->IP_P, pCom->Port_Safe_P);   /* parasoft-suppress MISRA2004-17_1 "指针运算提高代码执行效率" */
					}
					MSCP_LOG_MSG("plafm send innetsafeRm data ret = %#x\n",ret);
				}
				else
				{
					MSCP_LOG_MSG("SFM_TxInnetSafeRm  dstID =  %x error!!! \n",dstID);
				}
			}
			else
			{
				MSCP_LOG_MSG("Get dest IP and port fial!\n");
					/*- 无处理*/
			}
			i += (CM_UINT32)CM_UNSIGNED_SHORT_EXP(msgLen + 2u);
		}
	}
	else
	{
		/*- 无处理 */
	}
}

/**
* @brief 发送内网远程部署安全通信数据（宕机后使用）
* @param buf 输出数据数组
* @param Len 输出数据长度
* @details 输出数据数组按照内网SFP协议输出报文结构组织
*/
void SFM_TxInnetSafeRemoteUpdate(IN CM_UINT8 Buf[], IN CM_UINT32 Len)
{
    /*- 变量初始化 */
    CM_UINT32 allLen = CM_LongFromChar(Buf); /*外网输出帧报文总长度*/
    CM_UINT32 dataLen = 0u;
    CM_UINT32 dataEnd = 0u;
    CM_UINT32 i = 0u;              /* 循环变量 */
    CM_UINT16 msgLen = 0u;         /* 外网输出帧长度 */
    CM_UINT16 dstID = 0u;          /* 目的设备ID */
    STRU_PFM_INNET_CFG_T* pCom = NULL;/* 通信配置 */

	if ((allLen + 4u) == Len)
	{
		MSCP_LOG_MSG("\nSFM_TxInnetSafeRemoteUpdate : allLen=%d,Len=%d\n",allLen,Len);
	    dataLen = CM_LongFromChar(&Buf[4u]);
	    dataEnd = dataLen + 8u;

	    i = 8u;

	    MSCP_LOG_MSG("\nSFM_TxInnetSafeRemoteUpdate : i=%d,dataEnd=%d\n",i,dataEnd);
	    /*- 遍历输出队列 */
	    while ((i + 7u) < dataEnd)
	    {
	        /*
	        协议外网输出帧头
	        2字节 长度
	        1字节 协议类型
	        2字节 目的ID
	        2字节 预留
	        n字节 数据
	        */
	        /*- 解析协议内网输出帧头 */
	        msgLen = CM_ShortFromChar(&Buf[i]);           /* 2字节 帧长度 */      /* parasoft-suppress MISRA2004-17_1 "指针运算提高代码执行效率" */
	        /* Buf[i + 2u]; */                            /* 1字节 协议类型 */
	        dstID = CM_ShortFromChar(&Buf[i + 3u]);       /* 2字节 目的ID */     /* parasoft-suppress MISRA2004-17_1 "指针运算提高代码执行效率" */
	        (void)CM_ShortFromChar(&Buf[i + 5u]);          /* 2字节 (逻辑id) */
	        MSCP_LOG_MSG("\nSFM_TxInnetSafeRemoteUpdate : msgLen=%d,dstID=%d\n",msgLen,dstID);
			if (msgLen > 5u && msgLen <= (Len - i - 2u) && msgLen <= NET_20K_SIZE)
			{
		        /*- 获取目的IP端口 */
		        pCom = PFM_INI_RmInnetID2Addr(dstID);
		        /*- 是否获取成功 */
		        if (NULL != pCom)
		        {
					if (g_Maintenance_Id == dstID)
					{
						/*- 远程部署维护终端设备 */
			            /*- 本机是否为CPU1 */
			            if (1u == g_RMUP_Cfg.CPU_ID)
			            {
			                /*- 从绿网通道发送 */
			                (void)CFM_InnetRemoteUpdate_Send(&Buf[i + 7u], (CM_INT32)CM_UNSIGNED_SHORT_EXP(msgLen - 5u), pCom->IP_G, pCom->Port_Safe_G);   /* parasoft-suppress MISRA2004-17_1 "指针运算提高代码执行效率" */
			            }
			            else
			            {
			                /*- 从紫网通道发送 */
			                (void)CFM_InnetRemoteUpdate_Send(&Buf[i + 7u], (CM_INT32)CM_UNSIGNED_SHORT_EXP(msgLen - 5u), pCom->IP_P, pCom->Port_Safe_P);   /* parasoft-suppress MISRA2004-17_1 "指针运算提高代码执行效率" */
			            }					
					}
					else
					{
						MSCP_LOG_MSG("SFM_TxInnetSafeRemoteUpdate  dstID =  %x error!!! \n",dstID);
					}
		        }
		        else
		    	{
		    		/*- 无处理*/
		    	}
		        i += (CM_UINT32)CM_UNSIGNED_SHORT_EXP(msgLen + 2u);				
			}
			else
			{
				MSCP_LOG_MSG("SFM_TxInnetSafeRemoteUpdate  msgLen =  %u error!!! \n",msgLen);
			}
	    }		
	}
	else
	{
		MSCP_LOG_MSG("SFM_TxInnetSafeRemoteUpdate  allLen =  %u error!!! \n",allLen);
	}
}

/**
* @brief 发送外网安全通信数据
* @param buf 输出数据数组
* @param Len 输出数据长度
* @details 输出数据数组按照协议适配层外网输出报文结构组织
*/
void SFM_TxOutnetSafe(IN CM_UINT8 buf[], IN CM_UINT32 Len)
{
    /*- 变量初始化 */
    CM_UINT32 allLen = CM_LongFromChar(buf); /*外网输出帧报文总长度*/
    CM_UINT32 i = 0u;              /* 循环变量 */
    CM_UINT16 msgLen = 0u;         /* 外网输出帧长度 */
    CM_UINT16 appLen = 0u;         /* 应用通信数据长度 */
    CM_INT32 ccLen = 0;            /* 输出给CC的报文长度 */
    CM_UINT16 dstID = 0u;          /* 目的设备ID */
    CM_UINT16 logicID = 0u;        /* 目的逻辑ID */
    /* CM_UINT32 srcHlhtId = 0u; */   /* 源互联互通ID */
    /* CM_UINT32 dstHlhtId = 0u;  */   /* 目的互联互通ID */
    CM_UINT8 type = 0u;             /* 协议类型 */
    CM_UINT32 crc = 0u;            /* CRC */
    CM_UINT32 sysCount = SFM_2x2_GetSysCount();  /* 周期号 */
    ENUM_CM_RECCUSEB isSendExtendBoard = ENUM_CM_CC; /*是否发给扩展板*/
    ENUM_CM_RETURN isTransformOutFrame = ENUM_CM_FALSE; /*是否需要改变帧格式*/
    CM_UINT16 eAtsOutLen = 0;         /* 改变后的真实长度 */
    CM_UINT16 eTrueSrcID = 0;        /* 改变后的真实源设备类型ID */
    CM_UINT16 eTrueDstID = 0;        /* 改变后的真实目的设备类型ID */
    CM_UINT32 tx_sn = 0u;
    CM_RE_ASSERT((allLen + 4u) == Len, PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_13, TSCP_DARK_ASSERT_1);
    i = 4u;
    /*- 循环遍历输出队列 */
    while ((i + 7u) < Len)
    {
        /*
          协议外网输出帧头
           2字节 长度
           1字节 协议类型
           2字节 目的ID
           2字节 逻辑ID
           n字节 数据
           */
        /*- 解析协议外网输出帧头 */
        msgLen = CM_ShortFromChar(&buf[i]);            /*2字节 帧长度*/     /* parasoft-suppress MISRA2004-17_1 "指针运算提高代码执行效率" */
        type = buf[i + 2u];                            /*1字节 协议类型*/
        dstID = CM_ShortFromChar(&buf[i + 3u]);        /*2字节 目的设备ID*/     /* parasoft-suppress MISRA2004-17_1 "指针运算提高代码执行效率" */
        logicID = CM_ShortFromChar(&buf[i + 5u]);      /*2字节 逻辑ID*/
        appLen = msgLen - 5u;                           /* 外网通信数据长度为 msgLen - 5 */

        CM_RE_ASSERT(msgLen > 5u, PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_13, TSCP_DARK_ASSERT_2);
        CM_RE_ASSERT(msgLen <= (Len - i - 2u), PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_13, TSCP_DARK_ASSERT_3);
        CM_RE_ASSERT(msgLen <= NET_20K_SIZE, PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_13, TSCP_DARK_ASSERT_4);


		/* TSL星链 主机-底座 协议*/

		/*- 组CC外网输出帧头 */
		/*
		CC外网输出帧
		2字节 长度
		1字节 协议版本
		4字节 周期号
		2字节 目的设备id
		2字节 目的逻辑id
		2字节 协议类型
		n字节 数据
		4字节 CRC
		*/
		CM_ShortToChar((CM_UINT16)(appLen + 19u), s_Prtcl_UDP_Cache); /* 长度 */
		s_Prtcl_UDP_Cache[2] = 0u;                    				  /* 协议版本固定为0 */
#if 0
		CM_ShortToChar(0u, s_Prtcl_UDP_Cache + 3);                    /* 源目的设备ID */
		CM_ShortToChar(0u, s_Prtcl_UDP_Cache + 5);                    /* 源目的逻辑ID */
#else
		CM_LongToChar(sysCount, s_Prtcl_UDP_Cache + 3); 			  /* 序列号  */
#endif
		tx_sn = SFM_GetTxSn();                                        /* 获取帧序号*/
		CM_LongToChar(tx_sn, s_Prtcl_UDP_Cache + 7);					  /* 帧序号  */
		CM_ShortToChar(dstID, s_Prtcl_UDP_Cache + 11); 			      /* 目的设备ID  */
		CM_ShortToChar(logicID, s_Prtcl_UDP_Cache + 13);               /* 目的逻辑ID */

		CM_ShortToChar((CM_UINT16)type, s_Prtcl_UDP_Cache + 15);       /* 协议类型 */

		/*- 应用是否注册ats转车输出函数 */
		if(NULL == p_Serial_OUT_ATSVOBC_Func)
		{
			/*- 无处理 */
		}
		else
		{
			/*- 判断是否是ats转车输出数据 */
			isTransformOutFrame = (*p_Serial_OUT_ATSVOBC_Func)(dstID, &eTrueSrcID, &eTrueDstID);
		}

		/*- 应用是否注册转串口扩展板数据函数 */
		if(NULL == p_Serial_Id_Func)
		{
			/*- 无处理 */
			isSendExtendBoard = ENUM_CM_CC;
		}
		else
		{
			/*- 判断该数据是否是发送给串口扩展板 */
			isSendExtendBoard = (*p_Serial_Id_Func)(dstID);
		}

		if((ENUM_CM_FALSE == isTransformOutFrame)||/*无后备通道，发给通控或者串口板*/
			(ENUM_CM_CCSEB == isSendExtendBoard))/*主、备通道，发给通控*/
		{
			/*- 填写通信数据 */
			(void)CM_Memcpy((void*)(s_Prtcl_UDP_Cache + 17u), (CM_SIZE_T)(sizeof(s_Prtcl_UDP_Cache) - 17u), (void*)(buf + i + 7u), (CM_SIZE_T)appLen);  /* parasoft-suppress MISRA2004-17_1 "指针运算提高代码执行效率" */
			/* CRC */
			crc = CM_Crc32(s_Prtcl_UDP_Cache, appLen + 17u);//总长度为17 = 头+长度
			CM_LongToChar(crc, s_Prtcl_UDP_Cache + appLen + 17u);

			ccLen = (CM_INT32)CM_UNSIGNED_SHORT_EXP(appLen + (CM_UINT16)21u);/*发给CC的UDP报文长度*/
			/*- 如果是发送给串口扩展板 */
			if (ENUM_CM_SEB == isSendExtendBoard)
			{
				/*- 向红网SE发送SE外网帧 */
				(void)CFM_OutnetSafe_Send(s_Prtcl_UDP_Cache, ccLen, ENUM_OUTNET_EXTEND_RED);
				/*- 向红网SE发送SE外网帧 */
				(void)CFM_OutnetSafe_Send(s_Prtcl_UDP_Cache, ccLen, ENUM_OUTNET_EXTEND_BLUE);
			}
			else if((ENUM_CM_CC == isSendExtendBoard) || (ENUM_CM_CCSEB == isSendExtendBoard))
			{
				/*- 向红网CC发送CC外网帧 */
				(void)CFM_OutnetSafe_Send(s_Prtcl_UDP_Cache, ccLen, ENUM_OUTNET_RED);
				/*- 向蓝网CC发送CC外网帧 */
				(void)CFM_OutnetSafe_Send(s_Prtcl_UDP_Cache, ccLen, ENUM_OUTNET_BLUE);
			}
			else
			{
				/*无处理*/
			}
		}
		else
		{
			/*无处理*/
		}
		/*- 如果是ats转车输出数据 */
		if(ENUM_CM_TRUE == isTransformOutFrame)/*后备通道，发给串口板*/
		{
			/*- 按照ats转车输出数据帧格式进行组包 */
			CM_ShortToChar((CM_UINT16)(appLen + 33u), s_Prtcl_UDP_Cache);		 /* 长度 不包含自身2字节，但包含CRC */
			CM_ShortToChar(eTrueDstID, s_Prtcl_UDP_Cache + 11u);                  /* 目的设备ID */
			CM_ShortToChar(0u, s_Prtcl_UDP_Cache + 13u);                  		  /* 逻辑ID */
			eAtsOutLen = appLen + 12u;
			CM_ShortToChar(eAtsOutLen, s_Prtcl_UDP_Cache + 17u);                 /* ats解析数据包长度 */
			CM_LongToChar(sysCount, s_Prtcl_UDP_Cache + 19u);					/* 周期号,ats用来去冗余 */
			CM_ShortToChar(eTrueSrcID, s_Prtcl_UDP_Cache + 23u);                  /* 两字节真实源设备ID */
			CM_ShortToChar(0, s_Prtcl_UDP_Cache + 25u);                 			/* 两字节0 */
			CM_ShortToChar(dstID, s_Prtcl_UDP_Cache + 27u);                 		/* 两字节目的设备ID */
			CM_ShortToChar(logicID, s_Prtcl_UDP_Cache + 29u);                 	/* 两字节目的逻辑id*/
			/*- 填写通信数据 */
			(void)CM_Memcpy((void*)(s_Prtcl_UDP_Cache + 31u), (CM_SIZE_T)(sizeof(s_Prtcl_UDP_Cache) - 31u), (void*)(buf + i + 7u), (CM_SIZE_T)appLen);  /* parasoft-suppress MISRA2004-17_1 "指针运算提高代码执行效率" */
			/* CRC */
			crc = CM_Crc32(s_Prtcl_UDP_Cache, appLen + 31u);
			CM_LongToChar(crc, s_Prtcl_UDP_Cache + appLen + 31u);
			ccLen = (CM_INT32)CM_UNSIGNED_SHORT_EXP(appLen + (CM_UINT16)35u);/*发给CC/SEB的UDP报文长度*/
			/*- 如果是发送给串口扩展板 */
			if ((ENUM_CM_SEB == isSendExtendBoard) || (ENUM_CM_CCSEB == isSendExtendBoard))
			{
				/*- 向红网SE发送SE外网帧 */
				(void)CFM_OutnetSafe_Send(s_Prtcl_UDP_Cache, ccLen, ENUM_OUTNET_EXTEND_RED);
				/*- 向红网SE发送SE外网帧 */
				(void)CFM_OutnetSafe_Send(s_Prtcl_UDP_Cache, ccLen, ENUM_OUTNET_EXTEND_BLUE);
			}
			else
			{
				/*无处理*/
			}
		}
		else
		{
			/*- 无处理 */
		}
            
        /*- 索引偏移至下一输出报文 */
        i += (CM_UINT32)CM_UNSIGNED_SHORT_EXP(msgLen + 2u);
    }
}

void SFM_PrtclBufSwitch(void)
{
    /*- 变量初始化 */
    CM_UINT32 len = 0u;
    ENUM_CM_RETURN ret = ENUM_CM_FALSE;
    CM_UINT8 rslt = 0u;

    /*- 是否开启外网安全通信 */
    if (0x55u == g_PFM_Cfg.M_OutnetSafe_Enable)
    {
        /*- 读取应用外网发送缓冲 */
        len = CM_QueueStatus(&s_Outnet_AppSendQ);
        /*- 应用外网发送缓冲是否非空 */
        if (len > 0u)
        {
            /*- 从应用外网发送缓冲区读出数据，写入协议应用发送队列 */
            ret = CM_QueueRead(len, s_TmpCache, &s_Outnet_AppSendQ);
            CM_RE_ASSERT(ENUM_CM_TRUE == ret, PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_14, TSCP_DARK_ASSERT_1);
            rslt = QueueWrite(len, s_TmpCache, &s_OutnetPrtcl.OutputDataQueue);
            CM_RE_ASSERT(1u == rslt, PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_14, TSCP_DARK_ASSERT_2);
        }
        else
    	{
    		/*- 无处理*/
    	}

        /*- 清空应用外网发送缓冲区 */
        (void)CM_QueueClear(&s_Outnet_AppSendQ);

        /*- 清空应用外网接收缓冲区 */
        (void)CM_QueueClear(&s_Outnet_AppRecvQ);

        /*- 查询协议层外网接收队列 */
        len = QueueStatus(&s_OutnetPrtcl.DataToApp);
        /*- 是否有应用接收数据 */
        if (len > 0u)
        {
            /*- 从协议层应用接收队列读出数据，写入应用接收缓冲区*/
            rslt = QueueRead(len, s_TmpCache, &s_OutnetPrtcl.DataToApp);
            CM_RE_ASSERT(1u == rslt, PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_14, TSCP_DARK_ASSERT_3);
            ret = CM_QueueWrite(len, s_TmpCache, &s_Outnet_AppRecvQ);
            CM_RE_ASSERT(ENUM_CM_TRUE == ret, PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_14, TSCP_DARK_ASSERT_4);
        }
        else
    	{
    		/*- 无处理*/
    	}
    }
    else
	{
		/*- 无处理*/
	}

    /*- 是否开启内网安全通信 */
    if (0x55u == g_PFM_Cfg.M_InnetSafe_Enable)
    {
        /*- 读取应用内网发送缓冲 */
        len = CM_QueueStatus(&s_Innet_AppSendQ);
        /*- 应用内网发送缓冲是否非空 */
        if (len > 0u)
        {
            /*- 从应用发送缓冲区读出数据，写入协议应用发送队列 */
            ret = CM_QueueRead(len, s_TmpCache, &s_Innet_AppSendQ);
            CM_RE_ASSERT(ENUM_CM_TRUE == ret, PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_14, TSCP_DARK_ASSERT_5);
            rslt = QueueWrite(len, s_TmpCache, &s_InnetPrtcl.OutputDataQueue);
            CM_RE_ASSERT(1u == rslt, PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_14, TSCP_DARK_ASSERT_6);
        }
        else
    	{
    		/*- 无处理*/
    	}

        /*- 清空应用内网发送缓冲区 */
        (void)CM_QueueClear(&s_Innet_AppSendQ);

        /*- 清空应用内网接收缓冲区 */
        (void)CM_QueueClear(&s_Innet_AppRecvQ);

        /*- 查询协议层内网接收队列 */
        len = QueueStatus(&s_InnetPrtcl.DataToApp);
        /*- 是否有应用接收数据 */
        if (len > 0u)
        {
            /*- 从协议层应用接收队列读出数据，写入应用接收缓冲区*/
            rslt = QueueRead(len, s_TmpCache, &s_InnetPrtcl.DataToApp);
            CM_RE_ASSERT(1u == rslt, PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_14, TSCP_DARK_ASSERT_7);
            ret = CM_QueueWrite(len, s_TmpCache, &s_Innet_AppRecvQ);
            CM_RE_ASSERT(ENUM_CM_TRUE == ret, PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_14, TSCP_DARK_ASSERT_8);
        }
        else
    	{
    		/*- 无处理*/
    	}
    }
    else
	{
		/*- 无处理*/
	}

	/*- 是否开启远程部署内网安全通信 */
    if ((0x55u == g_PFM_Cfg.M_RemoteUpdate_Enable) &&(0x00u != g_Maintenance_Id))
    {
        /*- 读取远程部署内网发送缓冲 */
        len = CM_QueueStatus(&s_Innet_RmSendQ);
        /*- 应用内网发送缓冲是否非空 */
        if (len > 0u)
        {
            /*- 从应用发送缓冲区读出数据，写入协议应用发送队列 */
            ret = CM_QueueRead(len, s_TmpCache, &s_Innet_RmSendQ);
            CM_RE_ASSERT(ENUM_CM_TRUE == ret, PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_14, TSCP_DARK_ASSERT_9);
            MSCP_LOG_MSG("SFM_PrtclBufSwitch : %d\n",len);
            rslt = QueueWrite(len, s_TmpCache, &s_InnetPrtcl_RM.OutputDataQueue);

            len = QueueStatus(&s_InnetPrtcl_RM.OutputDataQueue);
            MSCP_LOG_MSG("&s_InnetPrtcl_RM.OutputDataQueue len = %d\n",len);

            CM_RE_ASSERT(1u == rslt, PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_14, TSCP_DARK_ASSERT_10);
        }
        else
    	{
    		/*- 无处理*/
    	}

        /*- 清空远程部署内网发送缓冲区 */
        (void)CM_QueueClear(&s_Innet_RmSendQ);

        /*- 清空远程部署内网发送缓冲区 */
        (void)CM_QueueClear(&s_Innet_AppRmSendQ);

        /*- 清空远程部署内网接收缓冲区 */
        (void)CM_QueueClear(&s_Innet_RmRecvQ);

        /*- 查询协议层内网接收队列 */
        len = QueueStatus(&s_InnetPrtcl_RM.DataToApp);
        MSCP_LOG_MSG("&s_InnetPrtcl_RM.DataToApp len = %d\n",len);
        /*- 是否远程部署内网接收数据 */
        if (len > 0u)
        {
            /*- 从协议层应用接收队列读出数据，写入远程部署内网接收缓冲区*/
            rslt = QueueRead(len, s_TmpCache, &s_InnetPrtcl_RM.DataToApp);
            CM_RE_ASSERT(1u == rslt, PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_14, TSCP_DARK_ASSERT_11);
            ret = CM_QueueWrite(len, s_TmpCache, &s_Innet_RmRecvQ);
            CM_RE_ASSERT(ENUM_CM_TRUE == ret, PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_14, TSCP_DARK_ASSERT_12);
        }
        else
    	{
    		/*- 无处理*/
    	}
    }
    else
	{
		/*- 无处理*/
	}
}

/**
* @brief 获取适配层协议(-1)跟随数据
* @param Buf 输出跟随数据数组指针
* @param BufSize 输出数组空间大小
* @return 输出跟随数据长度
*/
CM_UINT32 SFM_GetPrtclFollowData(OUT CM_UINT8* Buf, IN CM_UINT32 BufSize)
{
    /*- 获取协议跟随数据长度 */
    CM_UINT32 len = (CM_UINT32)CM_ShortFromChar(s_OutnetPrtcl.VarArray);
    /*- 输出跟随数据 */
    CM_RE_ASSERT((BufSize >= 2u) && (len <= (BufSize - 2u)), PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_15, TSCP_DARK_ASSERT_1);
    (void)CM_Memcpy((void*)Buf, (CM_SIZE_T)BufSize, (void*)s_OutnetPrtcl.VarArray, (CM_SIZE_T)CM_UNSIGNED_INT_EXP(len + 2u));

    /*- 返回数据长度 */
    return len + 2u;
}

/**
* @brief 获取sfp跟随数据
* @param Buf 输出跟随数据数组指针
* @param BufSize 输出数组空间大小
* @return 输出跟随数据长度
*/
CM_UINT32 SFM_GetSfpPrtclFollowData(OUT CM_UINT8* Buf, IN CM_UINT32 BufSize)
{
	/*- 入参防空 */
	CM_ASSERT(NULL != Buf, PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_22, TSCP_DARK_ASSERT_2);
    /*- 获取协议跟随数据长度 */
    CM_UINT32 sfpTotalLen = CM_LongFromChar(&s_InnetPrtcl.PrtclSndBuff[0]);
    CM_UINT32 sfpDataLen = CM_LongFromChar(&s_InnetPrtcl.PrtclSndBuff[4]);
    CM_UINT32 sfpOffset = 4 + 4 + sfpDataLen;
    CM_UINT32 sfpLinkLen = sfpTotalLen - sfpDataLen - 4;

    /*- 输出跟随数据 */
    CM_RE_ASSERT(sfpLinkLen <= BufSize - 4, PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_22, TSCP_DARK_ASSERT_1);

    CM_LongToChar(sfpLinkLen, &Buf[0]);
    (void)CM_Memcpy((void*)&Buf[4], (CM_SIZE_T)BufSize, (void*)(s_InnetPrtcl.PrtclSndBuff+sfpOffset), (CM_SIZE_T)sfpLinkLen);

    /*- 返回数据长度 */
    return sfpLinkLen + 4u;
}

/**
* @brief 设置适配层协议(-1)跟随数据
* @param Buf 跟随数据指针 取值范围：非空
*/
void SFM_SetPrtclFollowData(IN CM_UINT8* Buf)
{
    CM_UINT8 ret = 0u;
	/*- 入参防空 */
	CM_ASSERT(NULL != Buf, PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_16, TSCP_DARK_ASSERT_2);
    /*- 设置跟随数据 */
    ret = ProtclReFreshFunc(Buf, &s_OutnetPrtcl);
    CM_RE_ASSERT(1u == ret, PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_16, TSCP_DARK_ASSERT_1);
}

/**
* @brief 设置sfp跟随数据
* @param Len 跟随数据长度  取值范围：0~0xffffffff
* @param Buf 跟随数据指针  取值范围：非空
*/
void SFM_SetSfpPrtclFollowData(IN CM_UINT32 Len, IN CM_UINT8* Buf)
{
    CM_UINT8 ret = 0u;
	/*- 入参防空 */
	CM_ASSERT(NULL != Buf, PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_23, TSCP_DARK_ASSERT_2);
    /*- 设置跟随数据 */
    ret = ProtclFreshLnkMngr(Len, Buf, &s_InnetPrtcl);
    CM_RE_ASSERT(1u == ret, PRTCL_MODE, DARK_FAULT_CODE_FUN_ORDER_23, TSCP_DARK_ASSERT_1);
}

/**
* @brief 断开指定的外网安全通信链接
* @param devID 设备ID
* @param logicID 逻辑ID
* @return 执行结果
* - 1 成功
* - 0 失败
*/
CM_UINT8 SFM_OutnetDisconnect(IN CM_UINT16 devID, IN CM_UINT16 logicID)
{
    CM_UINT8 type = (CM_UINT8)(devID / 256u);
    CM_UINT8 id = (CM_UINT8)(devID % 256u);
    CM_UINT8 ret = 0u;
    ret = ProtclDeleteLnkFunc(type, id, logicID, &s_OutnetPrtcl);
    return ret;
}

/**
* @brief -1安全协议日志打印
*/
void SFM_LogOutPrtcl(void)
{
	/*- -1安全协议日志打印 */
    CM_UINT16 len = CM_ShortFromChar(s_OutnetPrtcl.RecordArray);
	MSCP_LOG_MSG("-1 SFM_LogOutPrtcl RecordArray len= %d\n",len);
    MSCP_LOG_BIN(s_OutnetPrtcl.RecordArray, len);
}

/**
* @brief 内网安全协议日志打印
*/
void SFM_LogInPrtcl(void)
{
    CM_UINT16 len = CM_ShortFromChar(s_InnetPrtcl.RecordArray);
	MSCP_LOG_MSG("SFM_LogInPrtcl RecordArray len= %d\n",len);
    MSCP_LOG_BIN(s_InnetPrtcl.RecordArray, len);
}

/**
* @brief 远程内网安全协议日志打印
*/
void SFM_LogRmInPrtcl(void)
{
    CM_UINT16 len = CM_ShortFromChar(s_InnetPrtcl_RM.RecordArray);
	MSCP_LOG_MSG("RM sfp SFM_LogInPrtcl RecordArray len= %d\n",len);
    MSCP_LOG_BIN(s_InnetPrtcl_RM.RecordArray, len);
}


/**
* @brief 维护模式协议层解析收到的数据(无宕机函数)
*/
void SFM_UnPrtclProc_Crash(void)
{
	CM_UINT8 ret = 0;
    /*- @alias 内网安全通信协议解析 */
    if ((0x55u == g_RMUP_Cfg.M_RemoteUpdate_Enable) &&(0x00u != g_Maintenance_Id))
    {
    	g_PFM_Check = PFM_CFC_PROC_NUM + 6;
    	CM_UINT32 QueuelenA = QueueStatus(&s_InnetPrtcl_RM.OutnetQueueA);
    	CM_UINT32 QueuelenB = QueueStatus(&s_InnetPrtcl_RM.OutnetQueueB);
    	MSCP_LOG_MSG("QueuelenA = %d, QueuelenB = %d\n",QueuelenA,QueuelenB);
    	g_PFM_Check = PFM_CFC_PROC_NUM + 7;
    	(void)QueueClear(&s_InnetPrtcl_RM.DataToApp);
        s_InnetPrtcl_RM.RadamSN = SFM_2x2_GetSysCount();
        ret = ProtclReceive(&s_InnetPrtcl_RM);
        MSCP_LOG_MSG("ProtclReceive ret = %d\n",ret);
        (void)QueueClear(&s_InnetPrtcl_RM.OutnetQueueA);
        (void)QueueClear(&s_InnetPrtcl_RM.OutnetQueueB);
        g_PFM_Check = PFM_CFC_PROC_NUM + 8;
        CM_UINT32 QueuelenDataToApp = QueueStatus(&s_InnetPrtcl_RM.DataToApp);
        MSCP_LOG_MSG("s_InnetPrtcl.DataToApp = %d\n",QueuelenDataToApp);

        MSCP_LOG_MSG("s_InnetPrtcl.LocalType = %d, s_InnetPrtcl.LocalID = %d\n",s_InnetPrtcl.LocalType,s_InnetPrtcl.LocalID);

    }
    else
	{
		/*- 无处理*/
	}
	/*- 过了sfp协议数据写入应用队列  */
	SFM_PrtclBufToApp_InnetSafeCrash();
}

/**
* @brief 维护模式协议层封装待发送数据(无宕机函数)
*/
void SFM_EnPrtclProc_Crash(void)
{
	/*- 变量初始化 */
    CM_UINT16 local_len = 0u;
    CM_UINT8 local_buf[1500u] = {0u};
    CM_UINT16 peer_len = 0u;
    CM_UINT8 p_peer_buf[1500u] = {0u};
	/*- 应用将sfp协议数据写到协议队列 */
	SFM_AppToPrtclBuf_InnetSafeCrash();
	
    /*- 内网安全协议封装 */
    if ((0x55u == g_RMUP_Cfg.M_RemoteUpdate_Enable) &&(0x00u != g_Maintenance_Id))
    {
		MSCP_LOG_MSG("SFM_EnPrtclProc_Crash Queuelen1 = %d\n",QueueStatus(&s_InnetPrtcl_RM.OutputDataQueue));
        CM_LongToChar(0u, s_InnetPrtcl_RM.PrtclSndBuff);
        CM_LongToChar(0u, s_InnetPrtcl_RM.RecordArray);
        (void)ProtclOutput(&s_InnetPrtcl_RM);
        (void)QueueClear(&s_InnetPrtcl_RM.OutputDataQueue);
        MSCP_LOG_MSG("SFM_ReadInnetCodedOutputCrash len = %d, s_InnetPrtcl.LocalType = %d, s_InnetPrtcl.LocalID = %d\n",CM_LongFromChar(s_InnetPrtcl_RM.PrtclSndBuff),s_InnetPrtcl.LocalType,s_InnetPrtcl.LocalID);
        /*- 是否开启2oo2功能 */
		if (0x55u == g_PFM_Cfg.M_2oo2_Enable)
		{
			/*- 双CPU交换SVC */
			(void)SfpGetSwapData(local_buf,1500u,&s_InnetPrtcl_RM);
			local_len = 2u + CM_ShortFromChar(local_buf);
			CM_ASSERT_MAINTAIN(local_len <= sizeof(local_buf));
			peer_len = (CM_UINT16)SFM_2oo2_Exchange_FullDuplex_Crash(local_buf, (CM_INT32)local_len, p_peer_buf, sizeof(p_peer_buf), ENUM_2oo2_SHUTDOWNQUIT);
			(void)SfpSetSwapData(p_peer_buf,&s_InnetPrtcl_RM);
		}
		else
		{
			/*- 无处理*/
		}
    }
    else
	{
		/*- 无处理*/
	}
}

/**
* @brief 维护模式下sfp协议数据写入应用队列(无宕机函数)
*/
void SFM_PrtclBufToApp_InnetSafeCrash(void)
{
    /*- 变量初始化 */
    CM_UINT32 len = 0u;
    ENUM_CM_RETURN ret = ENUM_CM_FALSE;
    CM_UINT8 rslt = 0u;
	 /*- 是否开启内网安全通信 */
	if ((0x55u == g_RMUP_Cfg.M_RemoteUpdate_Enable) &&(0x00u != g_Maintenance_Id))
	{
		/*- 清空应用内网接收缓冲区 */
		(void)CM_QueueClear(&s_Innet_RmRecvQ);

		/*- 查询协议层内网接收队列 */
		len = QueueStatus(&s_InnetPrtcl_RM.DataToApp);
		MSCP_LOG_MSG("SFM_PrtclBufToApp_InnetSafeCrash len = %d\n",len);
		/*- 是否有应用接收数据 */
		if (len > 0u)
		{
			/*- 从协议层应用接收队列读出数据，写入应用接收缓冲区*/
			rslt = QueueRead(len, s_TmpCache, &s_InnetPrtcl_RM.DataToApp);
			CM_ASSERT_MAINTAIN(1u == rslt);
			ret = CM_QueueWrite(len, s_TmpCache, &s_Innet_RmRecvQ);
			CM_ASSERT_MAINTAIN(ENUM_CM_TRUE == ret);
		}
		else
		{
			/*- 无处理*/
		}
	}
	else
	{
		/*- 无处理*/
	}
}
/**
* @brief 维护模式下应用将sfp协议数据写到协议队列(无宕机函数)
*/
void SFM_AppToPrtclBuf_InnetSafeCrash(void)
{
    /*- 变量初始化 */
    CM_UINT32 len = 0u;
    ENUM_CM_RETURN ret = ENUM_CM_FALSE;
    CM_UINT8 rslt = 0u;
    CM_UINT32 Queuelen = 0u;
	 /*- 是否开启内网安全通信 */
	if ((0x55u == g_PFM_Cfg.M_RemoteUpdate_Enable) &&(0x00u != g_Maintenance_Id))
	{
		/*- 读取应用内网发送缓冲 */
		len = CM_QueueStatus(&s_Innet_RmSendQ);
		MSCP_LOG_MSG("SFM_AppToPrtclBuf_InnetSafeCrash len1 = %d\n",len);
		/*- 应用内网发送缓冲是否非空 */
		if (len > 0u)
		{
			/*- 从应用发送缓冲区读出数据，写入协议应用发送队列 */
			ret = CM_QueueRead(len, s_TmpCache, &s_Innet_RmSendQ);
			CM_ASSERT_MAINTAIN(ENUM_CM_TRUE == ret);
			MSCP_LOG_MSG("SFM_AppToPrtclBuf_InnetSafeCrash len2 = %d\n",len);
			rslt = QueueWrite(len, s_TmpCache, &s_InnetPrtcl_RM.OutputDataQueue);
			Queuelen = QueueStatus(&s_InnetPrtcl_RM.OutputDataQueue);
			MSCP_LOG_MSG("Queuelen = %d\n",Queuelen);
#if 0
			for(int i = 0 ; i < len; i++)
			{
				(void)printf("0x%0.2x ",s_TmpCache[i]);
			}
			(void)printf("\n");
#endif
			CM_ASSERT_MAINTAIN(1u == rslt);
		}
		else
		{
			/*- 无处理*/
		}

		/*- 清空应用内网发送缓冲区 */
		(void)CM_QueueClear(&s_Innet_RmSendQ);
	}
	else
	{
		/*- 无处理*/
	}
}


/**
* @brief 去重-1协议数据
* @param data1 去重队列a 取值范围:非空
* @param data1Len 队列a长度 取值范围:0~0xffffffff
* @param data2 去重队列b 取值范围:非空
* @param data2Len 队列b长度 取值范围:0~0xffffffff
* @return 执行结果
* - 1 成功
* - 0 失败
* @details 将两个数组传入其中，每个数组的格式需要为总长度 红网数据长度 红网数据 篮网数据长度 篮网数据
* 		      之后相同数据会将b数组中的数据去掉，保留a的数据.
*/
CM_UINT8 SFM_OutProtclTwoRepeat(INOUT CM_UINT8* data1, IN CM_UINT32 data1Len,INOUT CM_UINT8* data2,INOUT CM_UINT32* data2Len)
{
	/*- 变量初始化 */
	CM_UINT8 TempBuf[1024 * 300] = {0};
	CM_UINT8 ret = 0;
	/*- 如果入参不为空 */
	if((NULL != data1) && (NULL != data2) && (NULL != data2Len))
	{
	    MSCP_LOG_MSG("before data1Len = %d\n", data1Len);
	    MSCP_LOG_MSG("before data2Len = %d\n\n", *data2Len);

		/*- 去重-1协议数据 */
	    ret = ProtclTwoRepeat(&s_OutnetPrtcl, data1, data1Len, data2, data2Len, TempBuf, 1024 * 300);
	    MSCP_LOG_MSG("after data1Len = %d\n", data1Len);
	    MSCP_LOG_MSG("after data2Len = %d\n\n", *data2Len);

	    /*- 如果去重失败  */
	    if(1 != ret)
	    {
	    	/*- 将队列数据发送至维护机 */
	    	MSCP_LOG_MSG("SFM_OutProtclTwoRepeat error ret = %d\n",ret);
	    	MSCP_LOG_DATALEN(data1,data1Len,"data1");
	    	MSCP_LOG_DATALEN(data2,*data2Len,"data2");
	    }
	    else
	    {
	    	/*- 无处理 */
	    }
	}
	else
	{
		/*- 无处理 */
		ret = 0;
		MSCP_LOG_MSG("SFM_OutProtclTwoRepeat param is NULL\n");
	}

	/*- 返回结果 */
    return ret;
}


/**
* @brief 查询链路状态
* @param destType 对方设备类型 取值范围：0~0xff
* @param destId 对方设备ID 取值范围：0~0xff
* @param logId 逻辑id(若卡斯柯的CI与VOBC通信，需要填写VOBC的站台号。其他的系统填0。) 取值范围：0~0xff
* @return 安全通道链路状态
* 	  0：不存在该条链路，返回错误
*     0x17：链路在数据传输正常状态
*     0x2b：链路在通信中断状态
*     0x33：链路在准备建立链接状态
*     0x4e：链路在等待建立链接状态
*     0x01: 表示刷新无用的链路
*/
CM_UINT8 SFM_GetLnkStatus(CM_UINT8 destType,CM_UINT8 destId,CM_UINT16 logId)
{
	/*- 获取安全通道链路状态 */
	return ProtclGetLnkStatus(destType, destId, logId, &s_OutnetPrtcl);
}
/**
* @brief 设置外网数据的帧序号
* @param sn 需要设置的序号：0~0xffff
* @return 无
*/
void SFM_SetTxSn(CM_UINT32 sn)
{
	s_txSn = sn;
}
/**
* @brief 获取外网数据发送序列号
* @param 无
* @return 获取到的外网数据序列号
*/
CM_UINT32 SFM_GetTxSn(void)
{
	/*- 变量初始化*/
	CM_UINT32 tmpsn = 0u;
	/*-翻转防护*/
	(s_txSn == (CM_UINT32_MAX-1u))?(s_txSn = 1u):s_txSn;  /* 预计跑149天会翻转一次,需要防护 */
	/*- 返回值赋值*/
	tmpsn = s_txSn;
	/*- 更新sn号*/
	s_txSn++;
	/*- 返回sn号*/
	return tmpsn;
}

