/**
* @file CFM_Net.c
* @brief Communication Function Module: 网络通信功能
* @details
* 2oo2、2x2、内网、外网、校时、同步等的以太网通信实现
* @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 "CFM_Net.h"
#include "CM_Convert.h"
#include "CM_Memory.h"
#include "CM_MQ.h"
#include "CM_UDP.h"
#include "CM_TCP.h"
#include "CM_MultiThread.h"
#include "CM_Mutex.h"
#include "CM_Atomic.h"
#include "CM_CRC32.h"
#include "CM_Time.h"
#include "DFM_Time.h"
#include "DFM_DRV.h"
#include "PFM_Cfg.h"
#include "PFM_Log.h"
#include "SFM_2x2.h"
#include "SFM_2oo2.h"
#include "CM_Com.h"
#include "CM_Sem.h"
#include "CM_Queue.h"
#include "MSCP_APP_Interface.h"
#include "PFM_RemoteUpdate.h"
#include "MSCP_Define.h"
#include <stdarg.h>

#define CFM_2oo2_MSG_NUM_MAX (200u)
#define CFM_2X2_MSG_NUM_MAX (200u)
#define CFM_OUTNET_MSG_NUM_MAX (5000u)
#define CFM_OUTHEART_MSG_NUM_MAX (20u)
#define CFM_INNET_SAFE_MSG_NUM_MAX (40u)


#define CFM_INNET_SAFE_MSG_SIZE (5120u)
#define CFM_INNET_RAW_MSG_SIZE  (2048u)
#define CFM_OUTNET_SAFE_MSG_SIZE (6144u)
#define CFM_OUTNET_RAW_MSG_SIZE (5120u)
#define CFM_OUTNET_HEART_MSG_SIZE (1000u)
#define CFM_SYN_MSG_SIZE (1000u)

/*暗文临时日志大小 和 ctrl队列大小*/
#define CFM_INNET_LOG_MSG_SIZE_DARK  (1024u * 80u) /* 暗文日志大小，ZC要求是80000(78*1024)字节 */
#define CFM_INNET_LOG_MSG_SIZE (5120u) 	 /* 明文消息队列大小 */
/*日志攒包发送 攒包大小*/
#define LOG_MAX (5120u)

/** 接收线程控制 */
typedef struct
{
    CM_CHAR IP[32];          /**< 本机IP */
    CM_UINT16 port;          /**< 本机端口 */
    CM_SOCKET* pSock;        /**< socket */
    CM_UINT32 rmtIP;     /**< 对端IP，0表示不指定 */
    CM_UINT32 rmtPort;   /**< 对端端口*/
    CM_UINT8 cache_buf[NET_UDP_BUF_SIZE]; /**< udp接收缓冲区 */
    CM_MQ_Struct_T MsgQ; /**< 接收消息队列 */
    /*通过透传算法选配*/
    CM_INT32 ch;          /**< 通道ID */
    CM_MQ_Struct_T InfoQ; /**< 埃弗瑞雷达报文用 */
    CM_MUTEX_T mutex;       /**< 互斥信号量，用来保护MsgQ和InfoQ */
    CM_MUTEX_T clear_mutex; /**< 互斥信号量，用来清空保护MsgQ和InfoQ */
    RAW_ALGORITHM ALGORITHM_Fun;	/** 时间戳解析算法注册指针*/
    /*通过tcp使能开关选配*/
	CM_UINT16 Tcpid;		  /**< TcpID */
	CM_INT32 Offset;		  /**< tcp接收缓冲区偏移量 */
	CM_UINT8 threadNumBer;    /* 线程号 */
}STRU_CFM_RECV_CTRL_T;
/** LOG线程结构体 */
typedef struct
{
	CM_CHAR rmtIP[32];     /**< 对端IP，0表示不指定 */
	CM_UINT16 rmtPort;     /**< 对端端口*/
    CM_SOCKET* pSock;      /**< socket */
    CM_MQ_Struct_T MsgQ;   /**< 接收消息队列 */
}STRU_CFM_SEND_LOG;
/** 暗文LOG线程结构体 */
typedef struct
{
	CM_CHAR rmtIP[32];     /**< 对端IP，0表示不指定 */
	CM_UINT16 rmtPort;     /**< 对端端口*/
    CM_SOCKET* pSock;      /**< socket */
    STRU_CM_QUEUE_T MsgQ;   /**< 接收消息队列 */
}STRU_CFM_SEND_DARKLOG;

/** 2乘线程控制*/
static STRU_CFM_RECV_CTRL_T s_CFM_Rx2x2;         		/**<  2x2数据通信接收线程控制 */
static STRU_CFM_RECV_CTRL_T s_CFM_State2x2;         		/**<  2x2数据通信接收线程控制 */
/** 2取线程控制*/
static STRU_CFM_RECV_CTRL_T s_CFM_Rx2oo2;        		/**< 2oo2数据通信接收线程控制 */
static STRU_CFM_RECV_CTRL_T s_CFM_Rx2oo2_App;        /**< 应用2oo2数据通信接收线程控制 */
static STRU_CFM_RECV_CTRL_T s_CFM_Rx2oo2Mainteance;      /**< 2oo2维护数据通信接收线程控制 */
static STRU_CFM_RECV_CTRL_T s_CFM_Rx2oo2_State;      /**< 2oo2维护数据通信接收线程控制 */
/** 其他通信线程控制*/
static STRU_CFM_RECV_CTRL_T s_CFM_RxInnetSafe;   		/**< 内网安全通信接收线程控制 */
static STRU_CFM_RECV_CTRL_T s_CFM_RxRemoteUpdate;   	/**< 内网远程部署安全通信接收线程控制 */
static STRU_CFM_RECV_CTRL_T s_CFM_RxInnetRaw[INNET_RAW_DOUBLE_PASS_NUM];    	/**< 内网透传通信接收线程控制 */
static STRU_CFM_RECV_CTRL_T s_CFM_RxOutnetSafe;  		/**< 外网安全通信接收线程控制 */
static STRU_CFM_RECV_CTRL_T s_CFM_RxOutnetRaw;  		/**< 外网透传通信接收线程控制 */
static STRU_CFM_RECV_CTRL_T s_CFM_RxOutnetHeart;  		/**< 外网心跳通信接收线程控制 */

static STRU_CFM_SEND_LOG s_CFM_Send_LogStr;     /**< 日志队列管理 */
/* 暗文log管理信息 */
STRU_LOG_CTRL_T ciphertextCtrl;
static STRU_CFM_SEND_DARKLOG s_Log_CtrlQ;

/*注册透传算法函数指针数组*/
RAW_ALGORITHM p_ALGORITHM_Fun[INNET_RAW_DOUBLE_PASS_NUM] = {NULL};
/** 时钟同步控制 */
typedef struct
{
    CM_CHAR IP[32];    /* 本机IP */
    CM_UINT16 port;    /* 本机端口 */
    CM_SOCKET* pSock;  /* 本地socket */

    /*
    * delay和offset受互斥信号量mutex保护，
    * 读写delay和offset时需要先取得互斥信号量
    */
    CM_MUTEX_T mutex;       /* 互斥信号量 */
    ENUM_CM_RETURN isOK;  /* 校时成功标志 */
    CM_INT64 delay;       /* 延迟时间 */
    CM_INT64 offset;      /* 偏移时间 */

}STRU_CFM_TIME_CTRL_T;

/** 周期同步控制 */
typedef struct
{
    CM_CHAR IP[32];    /* 本机IP */
    CM_UINT16 port;    /* 本机端口 */
    CM_SOCKET* pSock;  /* 本地socket */

    CM_MUTEX_T mutex;       /* 互斥信号量 */
    /*以下变量受互斥信号量保护*/
    CM_INT32 rxLen;       /* 接收报文长度 */
    CM_UINT8 rxBuf[CFM_SYN_MSG_SIZE]; /* 接收报文 */
    CM_UINT64 rxTick;     /* 同步报文接收时刻 */
    /*以上变量受互斥信号量保护*/
}STRU_CFM_SYN_CTRL_T;

/** 通信层socket管理 */
typedef struct
{
    CM_SOCKET Sock_2oo2_Time;        /**< 2oo2校时socket */
    CM_SOCKET Sock_2oo2_Data;        /**< 2oo2数据通信socket */
	CM_SOCKET Sock_2oo2_Data_App;    /**< 应用2oo2数据通信socket */
	CM_SOCKET Sock_2oo2_Maintenance; /**< 2oo2维护模式socket */
	CM_SOCKET Sock_2oo2_2x2_State;   /**< 2oo2上电同步socket */

    CM_SOCKET Sock_2x2_Time;       /**< 2x2校时socket */
    CM_SOCKET Sock_2x2_Data;       /**< 2x2数据通信socket */
    CM_SOCKET Sock_2x2_Syn;        /**< 2x2周期同步socket */
    CM_SOCKET Sock_2x2_State;      /**< 2x2状态切换socket */

    CM_SOCKET Sock_InnetSafe;      /**< 内网安全通信socket */
    CM_SOCKET Sock_OutnetSafe;     /**< 外网安全通信socket */
	CM_SOCKET Sock_OutnetRaw;      /**< 外网透传通信socket */
	CM_SOCKET Sock_OutnetHeart;    /**< 外网心跳通信socket */

    CM_INT32  num_InnetRaw;       /**< 内网透传端口数量 */
    CM_INT32  num_InnetRaw_Extend;/**< 内网透传扩展端口数量 */
    CM_SOCKET Sock_InnetRaw[INNET_RAW_DOUBLE_PASS_NUM];  /**< 内网透传通信socket */

    CM_SOCKET Sock_LogBase;    /**< 平台明文socket */
    CM_SOCKET Sock_LogCiphertext;    /**< 平台应用暗文日志socket */

	CM_SOCKET Sock_Remote_Update;  /**< 远程部署socket */
}STRU_CFM_SOCKS_T;

static STRU_CFM_SOCKS_T s_CFM_Sock; /**< 通信层socket管理 */

static STRU_CFM_TIME_CTRL_T s_CFM_2oo2_Time; 	/**< 2oo2时钟同步控制 */
static STRU_CFM_TIME_CTRL_T s_CFM_2x2_Time;  	/**< 2x2时钟同步控制 */
static STRU_CFM_SYN_CTRL_T s_CFM_2x2_Syn; 		/**< 2x2周期同步控制 */

static CM_UINT8 s_CFM_UDP_Cache[65535]; /**< 临时缓冲区 */

static CM_UINT16  g_CFM_OSCache_ClearNum;
static CM_UINT32 g_CFM_OSCache_Len;
/*硬重启通信状态结构体*/
STRU_HARDWARE_BOOT_COM_T g_Hardware_boot_com_state;
/**
* @brief 2oo2相关网络通信初始化
*/
static void s_NetInit_2oo2(void);
/**
* @brief 通用2oo2数据发送
* @param pBuf 发送报文指针 取值范围：非空
* @param BufLen 发送报文长度 取值范围：0~0x7FFFFFFF
* @return 发送结果
* - ENUM_CM_TRUE 成功
* - ENUM_CM_FALSE 失败
*/
static ENUM_CM_RETURN CFM_2oo2_Send_Currency(IN CM_SOCKET sock,IN const CM_UINT8* pBuf, IN CM_INT32 BufLen,IN CM_UINT16 nPortDest);

/**
* @brief 2oo2重传请求与应答ACK发送
* @param pBuf 发送报文指针
* @param BufLen 发送报文长度
* @return 发送结果
* - ENUM_CM_TRUE 成功
* - ENUM_CM_FALSE 失败
*/
static ENUM_CM_RETURN CFM_2oo2_SendARQ_Currency(STRU_2OO2_NET_NO_PACK_T *p_2oo2_Ctrl,ENUM_2oo2_NET_T msgType);

/**
* @brief 2x2相关网络通信初始化
*/
static void s_NetInit_2x2(void);

/**
* @brief 周期同步线程
* @param arg 指向STRU_CFM_SYN_CTRL的指针
* @return 线程函数返回值（实际永远不会返回）
* @details
* 创建本线程之前应先配置好STRU_CFM_SYN_CTRL，包括创建阻塞通信的socket
* 本线程将以阻塞方式接收周期同步报文、并记录收到报文的精确时间
* @see :: CFM_2x2_SyncSend
* @see :: CFM_2x2_SyncRecv
*/
static CM_THREAD_FUNC_T t_SyncThread(IN CM_Thread_Arg_Struct_T* arg);

/*********************************内网通信相关*****************************************/

/**
* @brief 内网通信初始化
*/
static void s_NetInit_Innet(void);

/**
* @brief UDP透传接收线程
* @param arg 指向STRU_CFM_RECV_CTRL的指针
* @details
* 创建本线程之前应先配置好STRU_CFM_RECV_CTRL，包括创建阻塞通信的socket
* 本线程将以阻塞方式接收UDP报文并写入线程接收队列
*/
static CM_THREAD_FUNC_T t_UdpRawRecvThread(IN CM_Thread_Arg_Struct_T* arg);

/**
* @brief TCP接收线程
* @param arg 指向STRU_CFM_RECV_CTRL的指针
* @details
* 创建本线程之前应先配置好STRU_CFM_RECV_CTRL，包括创建阻塞通信的socket
* 本线程将以非阻塞方式接收TCP报文并写入线程接收队列
*/
static CM_THREAD_FUNC_T t_TcpRecvThread(IN CM_Thread_Arg_Struct_T* arg);

/*********************************外网通信相关*****************************************/

/**
* @brief 外网通信初始化
*/
static void s_NetInit_Outnet(void);

/* 维护网通信初始化 */
static void s_NetInit_Maintain(void);

/**
* @brief 日志发送线程
* @param arg 指向STRU_CFM_TIME_CTRL的指针
* @return 线程函数返回值（实际永远不会返回）
* @details
*/
static CM_THREAD_FUNC_T t_LogSendThread(IN CM_Thread_Arg_Struct_T* arg);

/* 远程部署通信初始化 */
static void s_NetInit_RemoteUpdate(void);

/**
* @brief UDP接收线程
* @param arg 指向STRU_CFM_RECV_CTRL的指针
* @details
* 创建本线程之前应先配置好STRU_CFM_RECV_CTRL，包括创建阻塞通信的socket
* 本线程将以阻塞方式接收UDP报文并写入线程接收队列
*/
static CM_THREAD_FUNC_T t_UdpRecvThread(IN CM_Thread_Arg_Struct_T* arg);
/**
* @brief 维护模式下UDP接收线程
* @param arg 指向STRU_CFM_RECV_CTRL的指针
* @details
* 创建本线程之前应先配置好STRU_CFM_RECV_CTRL，包括创建阻塞通信的socket
* 本线程将以阻塞方式接收UDP报文并写入线程接收队列
*/
static CM_THREAD_FUNC_T t_UdpRecvMaintenanceThread(IN CM_Thread_Arg_Struct_T* arg);

/**
* @brief 时钟同步线程
* @param arg 指向STRU_CFM_TIME_CTRL的指针
* @return 线程函数返回值（实际永远不会返回）
* @details
* 创建本线程之前应先配置好STRU_CFM_TIME_CTRL，包括创建阻塞通信的socket
* 本线程将以阻塞方式接收时钟同步报文并作出应答
* 收到请求报文时立即给出应答
* 收到应答报文时记录并计算延迟时间、偏移时间
* @see :: CFM_2oo2_TimeReq
* @see :: CFM_2oo2_TimeGet
*/
static CM_THREAD_FUNC_T t_TimeThread(IN CM_Thread_Arg_Struct_T* arg);

/**
* @brief 远程部署接收线程
* @param arg 指向STRU_CFM_RECV_CTRL的指针
* @details
* 创建本线程之前应先配置好STRU_CFM_RECV_CTRL，包括创建阻塞通信的socket
* 本线程将以阻塞方式接收远程部署命令UDP报文，然后进行相关处理
*/
static CM_THREAD_FUNC_T t_RemoteUpdateThread(IN CM_Thread_Arg_Struct_T* arg);

static CM_THREAD_FUNC_T t_ClearArpThread(void);
/*********************************2取相关*****************************************/
/**
* @brief 2oo2相关网络通信初始化
*/
static void s_NetInit_2oo2(void)
{
    /*- 变量初始化 */
    ENUM_CM_RETURN rt = ENUM_CM_FALSE;  /* 临时变量 */
    CM_INT32 val = 0;                   /* 临时变量 */
    CM_BOOL rtCheck = CM_FALSE;         /* 临时变量 */

    /*- 创建时间同步socket */
    rt = CM_UDP_Socket_Create(&s_CFM_Sock.Sock_2oo2_Time, 		CM_FALSE,(CM_UINT32)inet_addr(g_PFM_Cfg.Local_Cfg.IP_2oo2), g_PFM_Cfg.Local_Cfg.Port_2oo2_Time, 	0u, (CM_UINT8)0u);
    CM_NM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE,DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);
    /*- 创建平台数据2取socket */
    rt = CM_UDP_Socket_Create(&s_CFM_Sock.Sock_2oo2_Data, 		CM_FALSE, (CM_UINT32)inet_addr(g_PFM_Cfg.Local_Cfg.IP_2oo2), g_PFM_Cfg.Local_Cfg.Port_2oo2_Data, 	0u, (CM_UINT8)0u);
    CM_NM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE,DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_2);
    /*- 创建应用数据2取socket */
	rt = CM_UDP_Socket_Create(&s_CFM_Sock.Sock_2oo2_Data_App, 	CM_FALSE, (CM_UINT32)inet_addr(g_PFM_Cfg.Local_Cfg.IP_2oo2), g_PFM_Cfg.Local_Cfg.Port_2oo2_Data_App, 0u, (CM_UINT8)0u);
	CM_NM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE,DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_3);
    /*- 创建2x状态2取socket */
    rt = CM_UDP_Socket_Create(&s_CFM_Sock.Sock_2oo2_2x2_State, 	CM_FALSE, (CM_UINT32)inet_addr(g_PFM_Cfg.Local_Cfg.IP_2oo2), g_PFM_Cfg.Local_Cfg.Port_2oo2_2x2_State,0u, (CM_UINT8)0u);
    CM_NM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE,DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_6);

	if ((0x55u == g_PFM_Cfg.M_RemoteUpdate_Enable) &&(0x00u != g_Maintenance_Id))
	{
		/*- 创建维护模式下的2取socket */
	    rt = CM_UDP_Socket_Create(&s_CFM_Sock.Sock_2oo2_Maintenance, CM_FALSE, (CM_UINT32)inet_addr(g_PFM_Cfg.Local_Cfg.IP_2oo2), g_PFM_Cfg.Local_Cfg.Port_2oo2_Maintenance, 0u, (CM_UINT8)0u);
	    CM_NM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_18);
	}
	else
	{
		/*- 无处理 */
	}

    /*- 配置socket */
    val = (CM_INT32)NET_UDP_BUF_DOUBLESIZE;
    (void)setsockopt(s_CFM_Sock.Sock_2oo2_Data, SOL_SOCKET, SO_RCVBUF, (void*)(&val), (unsigned int)sizeof(val));
    (void)setsockopt(s_CFM_Sock.Sock_2oo2_Data, SOL_SOCKET, SO_SNDBUF, (void*)(&val), (unsigned int)sizeof(val));
    (void)setsockopt(s_CFM_Sock.Sock_2oo2_Data_App, SOL_SOCKET, SO_RCVBUF, (void*)(&val), (unsigned int)sizeof(val));
    (void)setsockopt(s_CFM_Sock.Sock_2oo2_Data_App, SOL_SOCKET, SO_SNDBUF, (void*)(&val), (unsigned int)sizeof(val));
    /*- 初始化控制信息 */
    CM_NM_ASSERT(s_CFM_2oo2_Time.IP != NULL, NET_MODE,DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_7);
    (void)sprintf(s_CFM_2oo2_Time.IP, "%s", g_PFM_Cfg.Local_Cfg.IP_2oo2);
    s_CFM_2oo2_Time.port = g_PFM_Cfg.Local_Cfg.Port_2oo2_Time;
    s_CFM_2oo2_Time.pSock = &s_CFM_Sock.Sock_2oo2_Time;
    rt = CM_Mutex_Init(&s_CFM_2oo2_Time.mutex);
    CM_NM_ASSERT(ENUM_CM_TRUE == rt,NET_MODE,DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_8);

    /*- 启动2oo2时钟同步线程 */
    rtCheck = CM_Thread_Create((CM_THREAD_T*)NULL, (CM_THREAD_FUNC_T)t_TimeThread, "2oo2_T", 0, CM_TASK_PRIORITY_72, (CM_Thread_Arg_Struct_T*)&s_CFM_2oo2_Time);
    CM_NM_ASSERT(CM_TRUE == rtCheck, NET_MODE,DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_11);

    /*- 配置接收线程 */
    CM_NM_ASSERT(s_CFM_Rx2oo2.IP != NULL, NET_MODE,DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_9);
    (void)sprintf(s_CFM_Rx2oo2.IP, "%s", g_PFM_Cfg.Local_Cfg.IP_2oo2);
    s_CFM_Rx2oo2.port = g_PFM_Cfg.Local_Cfg.Port_2oo2_Data;
    s_CFM_Rx2oo2.pSock = &s_CFM_Sock.Sock_2oo2_Data;
    s_CFM_Rx2oo2.rmtIP = inet_addr(g_PFM_Cfg.Peer_Cfg.IP_2oo2);
    s_CFM_Rx2oo2.rmtPort = g_PFM_Cfg.Peer_Cfg.Port_2oo2_Data;
    rt = CM_MQ_Init(&s_CFM_Rx2oo2.MsgQ, (CM_UINT16)CFM_2oo2_MSG_NUM_MAX, (CM_UINT16)NET_UDP_2OO2_BUF_SIZE);
    CM_NM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE,DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_10);
    /*- 启动2oo2接收线程 */
	rtCheck = CM_Thread_Create((CM_THREAD_T*)NULL, (CM_THREAD_FUNC_T)t_UdpRecvThread, "2oo2_Rx", 0, CM_TASK_PRIORITY_73, (CM_Thread_Arg_Struct_T*)&s_CFM_Rx2oo2);
	CM_NM_ASSERT(CM_TRUE == rtCheck, NET_MODE,DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_12);

	if ((0x55u == g_PFM_Cfg.M_RemoteUpdate_Enable) &&(0x00u != g_Maintenance_Id))
	{
		CM_NM_ASSERT(s_CFM_Rx2oo2Mainteance.IP != NULL, NET_MODE,DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_19);
		(void)sprintf(s_CFM_Rx2oo2Mainteance.IP, "%s", g_PFM_Cfg.Local_Cfg.IP_2oo2);
		s_CFM_Rx2oo2Mainteance.port = g_PFM_Cfg.Local_Cfg.Port_2oo2_Maintenance;
		s_CFM_Rx2oo2Mainteance.pSock = &s_CFM_Sock.Sock_2oo2_Maintenance;
		s_CFM_Rx2oo2Mainteance.rmtIP = inet_addr(g_PFM_Cfg.Peer_Cfg.IP_2oo2);
		s_CFM_Rx2oo2Mainteance.rmtPort = g_PFM_Cfg.Peer_Cfg.Port_2oo2_Maintenance;
		rt = CM_MQ_Init(&s_CFM_Rx2oo2Mainteance.MsgQ, (CM_UINT16)CFM_2oo2_MSG_NUM_MAX, (CM_UINT16)NET_UDP_MAINTENANCE_BUF_SIZE);
		CM_NM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE,DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_20);
		/*- 启动2oo2维护接收线程 */
		rtCheck = CM_Thread_Create((CM_THREAD_T*)NULL, (CM_THREAD_FUNC_T)t_UdpRecvMaintenanceThread, "2oo2_Maintenance", 0, CM_TASK_PRIORITY_89, (CM_Thread_Arg_Struct_T*)&s_CFM_Rx2oo2Mainteance);
		CM_NM_ASSERT(CM_TRUE == rtCheck, NET_MODE,DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_21);
	}
	else
	{
		/*- 无处理 */
	}

	/*- 配置接收线程 */
	CM_NM_ASSERT(s_CFM_Rx2oo2_App.IP != NULL, NET_MODE,DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_14);
	(void)sprintf(s_CFM_Rx2oo2_App.IP, "%s", g_PFM_Cfg.Local_Cfg.IP_2oo2);
	s_CFM_Rx2oo2_App.port = g_PFM_Cfg.Local_Cfg.Port_2oo2_Data_App;
	s_CFM_Rx2oo2_App.pSock = &s_CFM_Sock.Sock_2oo2_Data_App;
	s_CFM_Rx2oo2_App.rmtIP = inet_addr(g_PFM_Cfg.Peer_Cfg.IP_2oo2);
	s_CFM_Rx2oo2_App.rmtPort = g_PFM_Cfg.Peer_Cfg.Port_2oo2_Data_App;
	s_CFM_Rx2oo2_App.threadNumBer = (CM_UINT8)ENUM_THREAD_2oo2_AppRecv;
	rt = CM_MQ_Init(&s_CFM_Rx2oo2_App.MsgQ, (CM_UINT16)CFM_2oo2_MSG_NUM_MAX, (CM_UINT16)NET_UDP_2OO2_BUF_SIZE);
	CM_NM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE,DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_15);
	/*- 启动2oo2接收线程 */
	rtCheck = CM_Thread_Create((CM_THREAD_T*)NULL, (CM_THREAD_FUNC_T)t_UdpRecvThread, "2oo2_Rx_App", 0, CM_TASK_PRIORITY_73, (CM_Thread_Arg_Struct_T*)&s_CFM_Rx2oo2_App);
	CM_NM_ASSERT(CM_TRUE == rtCheck, NET_MODE,DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_16);

	/*- 配置接收线程 */
	CM_NM_ASSERT(s_CFM_Rx2oo2_State.IP != NULL, NET_MODE,DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_22);
	(void)sprintf(s_CFM_Rx2oo2_State.IP, "%s", g_PFM_Cfg.Local_Cfg.IP_2oo2);
	s_CFM_Rx2oo2_State.port = g_PFM_Cfg.Local_Cfg.Port_2oo2_2x2_State;
	s_CFM_Rx2oo2_State.pSock = &s_CFM_Sock.Sock_2oo2_2x2_State;
	s_CFM_Rx2oo2_State.rmtIP = inet_addr(g_PFM_Cfg.Peer_Cfg.IP_2oo2);
	s_CFM_Rx2oo2_State.rmtPort = g_PFM_Cfg.Peer_Cfg.Port_2oo2_2x2_State;
	rt = CM_MQ_Init(&s_CFM_Rx2oo2_State.MsgQ, (CM_UINT16)CFM_2oo2_MSG_NUM_MAX, (CM_UINT16)CFM_INNET_RAW_MSG_SIZE);
	CM_NM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE,DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_23);
	/*- 启动2oo2接收线程 */
	rtCheck = CM_Thread_Create((CM_THREAD_T*)NULL, (CM_THREAD_FUNC_T)t_UdpRecvThread, "2oo2_Rx", 0, CM_TASK_PRIORITY_73, (CM_Thread_Arg_Struct_T*)&s_CFM_Rx2oo2_State);
	CM_NM_ASSERT(CM_TRUE == rtCheck, NET_MODE,DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_24);
	CM_Sleep(100u);/* 延时等待线程启动 */
}
/**
* @brief 2oo2上电同步
* @details
*/
ENUM_CM_RETURN CFM_2oo2_InitSync(void)
{
    /*- 变量初始化 */


    CM_UINT8 syn[10] = "SYN"; /* 同步报文 */
    CM_UINT8 rxBuf[1500];     /* 接收缓冲区 */
    CM_INT32 rxLen = 0;       /* 接收长度 */
    ENUM_CM_RETURN SyncFlag = ENUM_CM_FALSE; /* 同步标记 */
    CM_UINT64 costStart = 0u; /* 60000*/
    CM_UINT64 costEnd = 0u;
    CM_UINT64 timeResult = 0u;
    /*
    为提高执行效率和精度，所有同步、校时报文都是短小的无保护报文，
    而周期逻辑中的同步校验报文是有充分安全保护的，
    从而确保程序执行的安全性
    */
    costStart = CM_GetTick();
    MSCP_LOG_MSG("costStart == %lld\n",costStart);
    /*- 与邻机交换校验帧 */
    rxLen = SFM_2oo2_Exchange_Currency(syn, 3, rxBuf, (CM_UINT8)sizeof(rxBuf), NUM_2oo2_FIRSTSYNC);
    /*- 校验帧长度是否相同 */
	costEnd = CM_GetTick();
	/*- 超过了1分钟未收到邻机数据 */
	if(costEnd - costStart > 60000000000u)
	{
		/*- 置为同步失败 */
		timeResult = (costEnd - costStart)/1000000000u;
		(void)CFM_DarkLog_Storage(DARK_LOG_HEX, TSCP_DARK_CFMNET_ININTSYNC_TIMEOUT, 8U, &timeResult);
		MSCP_LOG_MSG("timeResult == %lld\n", timeResult);
		CM_ASSERT(0, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_32, TSCP_DARK_ASSERT_1);
	}
	/*- 收到了正确的上电同步报文 */
	else if((3 == rxLen) && (0 == CM_Memcmp(rxBuf, syn, (CM_SIZE_T)3)))
	{
		/*- 置位同步成功 */
		SyncFlag = ENUM_CM_TRUE;
	}
	/*- 未收到正确数据 */
	else
	{
		/*- 接收数据错误宕机 */
		CM_ASSERT(0, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_32, TSCP_DARK_ASSERT_2);
	}
    /*- 返回同步结果 */
    return SyncFlag;
}

/**
* @brief 发起一次2oo2时钟同步
* @details
* 发送一个2oo2时钟同步请求报文
* 由双方的时钟同步线程完成一次NTP校时操作
* 操作完成后本方的时钟同步线程会记录到延迟时间和偏移时间
* @see :: CFM_2oo2_TimeGet
* @see :: t_TimeThread
*/
void CFM_2oo2_TimeReq(void)
{
    /*- 变量初始化 */
    CM_UINT8 buf[100];
    CM_INT32 len = 0;
    CM_ATOMIC CM_UINT64 tick = 0u;

    /*- 生成时钟同步请求报文 */
    len = 9;
    buf[0] = (CM_UINT8)ENUM_TIME_REQ;

    tick = DFM_GetCycTick();

    CM_64ToChar(tick, buf + 1);
    /*- 发送时钟同步请求报文 */
    (void)CM_UDP_Send_Msg(s_CFM_Sock.Sock_2oo2_Time, buf, len, inet_addr(g_PFM_Cfg.Peer_Cfg.IP_2oo2),g_PFM_Cfg.Peer_Cfg.Port_2oo2_Time);
}

/**
* @brief 读取时钟同步结果
* @param pDelay 延迟时间
* @param pOffset 偏移时间
* @return 执行结果
* - ENUM_CM_TRUE 成功
* - ENUM_CM_FALSE 失败
*/
ENUM_CM_RETURN CFM_2oo2_TimeGet(OUT CM_INT64* pDelay, OUT CM_INT64* pOffset)
{
    /*- 变量初始化 */
    ENUM_CM_RETURN rt = ENUM_CM_FALSE;
	ENUM_CM_RETURN ret = ENUM_CM_FALSE;

    /*- 锁定互斥锁 */
    rt = CM_Mutex_Lock(s_CFM_2oo2_Time.mutex);
    CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_15, TSCP_DARK_ASSERT_1);
    /*- 是否保存了时钟同步结果 */
    if (ENUM_CM_TRUE == s_CFM_2oo2_Time.isOK)
    {
        /*- 读取时钟同步结果 */
        *pDelay = s_CFM_2oo2_Time.delay;
        *pOffset = s_CFM_2oo2_Time.offset;
        /*- 清除时钟同步结果 */
        s_CFM_2oo2_Time.isOK = ENUM_CM_FALSE;
		ret = ENUM_CM_TRUE;
    }
    else
	{
		/*- 无处理 */
	}
    /*- 释放互斥锁 */
    rt = CM_Mutex_Unlock(s_CFM_2oo2_Time.mutex);
    CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_15, TSCP_DARK_ASSERT_2);
    /*- 返回执行结果 */
	return ret;
}
/**
* @brief 通用2oo2数据发送
* @param pBuf 发送报文指针 取值范围：非空
* @param BufLen 发送报文长度 取值范围：0~0x7FFFFFFF
* @return 发送结果
* - ENUM_CM_TRUE 成功
* - ENUM_CM_FALSE 失败
*/
static ENUM_CM_RETURN CFM_2oo2_Send_Currency(IN CM_SOCKET sock,IN const CM_UINT8* pBuf, IN CM_INT32 BufLen,IN CM_UINT16 nPortDest)
{
    /*- 变量初始化 */
    ENUM_CM_RETURN rt = ENUM_CM_FALSE;
    /*- 入参指针防空 */
    if(NULL != pBuf)
    {
		/*- UDP方式通过2oo2数据通信通道向邻机发送 */
    	rt = CM_UDP_Send_Msg(sock, pBuf, BufLen, inet_addr(g_PFM_Cfg.Peer_Cfg.IP_2oo2),nPortDest);
    }
    else
    {
    	/*空指针返回失败*/
    }
    /*- 返回发送结果 */
    return rt;
}
/**
* @brief 2oo2重传请求与应答ACK发送
* @param pBuf 发送报文指针
* @param BufLen 发送报文长度
* @return 发送结果
* - ENUM_CM_TRUE 成功
* - ENUM_CM_FALSE 失败
*/
static ENUM_CM_RETURN CFM_2oo2_SendARQ_Currency(STRU_2OO2_NET_NO_PACK_T *p_2oo2_Ctrl,ENUM_2oo2_NET_T msgType)
{
	CM_UINT8 sendbuf[20] = {0};
	CM_UINT32 SysCyc = DFM_GetBirthCount(); /*平台周期号*/
	/*
	2oo2通信帧格式：
	4字节 长度(不含自身)
	4字节 周期号
	4字节 序列号
	1字节 类型
	*/
	CM_LongToChar(9u, &sendbuf[0]);        /* 长度（暂时填写满帧） */
	CM_LongToChar(SysCyc, &sendbuf[4]);              /* 周期号 */
	CM_LongToChar(p_2oo2_Ctrl->SN, &sendbuf[8]);      /* 序列号 */
	sendbuf[12] = (CM_UINT8)msgType;                  /* 类型 */

    /*- 返回发送结果 */
    return p_2oo2_Ctrl->DataSend(sendbuf,13u);
}
/**
* @brief 2oo2数据发送
* @param pBuf 发送报文指针
* @param BufLen 发送报文长度
* @return 发送结果
* - ENUM_CM_TRUE 成功
* - ENUM_CM_FALSE 失败
*/
ENUM_CM_RETURN CFM_2oo2_DataSend(IN const CM_UINT8* pBuf, IN CM_INT32 BufLen)
{
	/*- 指针防空*/
    CM_ASSERT(NULL != pBuf, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_31, TSCP_DARK_ASSERT_1);
    /*- 返回发送结果 */
    return CFM_2oo2_Send_Currency(s_CFM_Sock.Sock_2oo2_Data,pBuf, BufLen,g_PFM_Cfg.Peer_Cfg.Port_2oo2_Data);
}

/**
* @brief 2oo2数据接收
* @param pBuf 接收报文指针
* @param BufLen 接收报文缓冲区大小
* @return 接收报文长度
* - 正整数 接收报文长度
* - 0 接收失败
*/
CM_INT32 CFM_2oo2_DataRecv(OUT CM_UINT8* pBuf, IN CM_UINT32 BufSize)
{
    /*- 指针防空*/
    /*- 变量初始化 */
	CM_UINT16 len = (CM_UINT16)((BufSize > 65535u) ? 65535u : BufSize);
	ENUM_CM_RETURN rt = ENUM_CM_FALSE;
	/*- 指针防空*/
	CM_ASSERT(NULL != pBuf, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_19, TSCP_DARK_ASSERT_1);
	/*- 从接收线程获取输入报文 */
	rt = CM_MQ_Read(&s_CFM_Rx2oo2.MsgQ, s_CFM_Rx2oo2.cache_buf, &len);
	/*- 是否获取成功 */
	if ((ENUM_CM_TRUE == rt) && (6u < len))
	{
		/*- 输出接收数据 */
		len -= 6u;
		rt = CM_Memcpy((void*)pBuf, (CM_SIZE_T)BufSize, (void*)(s_CFM_Rx2oo2.cache_buf + 6), (CM_SIZE_T)len);
		CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_19, TSCP_DARK_ASSERT_2);
	}
	else
	{
		/*- 接收长度为0 */
		len = 0u;
	}
	/*- 返回接收长度 */
	return (CM_INT32)len;
}

/**
* @brief 2oo2数据发送
* @param pBuf 发送报文指针 取值范围：非空
* @param BufLen 发送报文长度 取值范围：0~0x7FFFFFFF
* @return 发送结果
* - ENUM_CM_TRUE 成功
* - ENUM_CM_FALSE 失败
*/
ENUM_CM_RETURN CFM_2oo2_DataSend_App(IN const CM_UINT8* pBuf, IN CM_INT32 BufLen)
{
    /*- 入参指针防空 */
    CM_ASSERT(NULL != pBuf, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_34, TSCP_DARK_ASSERT_1);
    /*- 返回发送结果 */
    return CFM_2oo2_Send_Currency(s_CFM_Sock.Sock_2oo2_Data_App,pBuf, BufLen,g_PFM_Cfg.Peer_Cfg.Port_2oo2_Data_App);
}

/**
* @brief 2oo2数据接收
* @param pBuf 接收报文指针 取值范围：非空
* @param BufLen 接收报文缓冲区大小 取值范围：0~0xFFFFFFFF
* @return 接收报文长度
* - 1~0xFFFFFFFF 接收报文长度
* - 0 接收失败
*/
CM_INT32 CFM_2oo2_DataRecv_App(OUT CM_UINT8* pBuf, IN CM_UINT32 BufSize)
{
    /*- 指针防空*/
    /*- 变量初始化 */
	CM_UINT16 len = (CM_UINT16)((BufSize > 65535u) ? 65535u : BufSize);
	ENUM_CM_RETURN rt = ENUM_CM_FALSE;
	/*- 指针防空*/
	CM_ASSERT(NULL != pBuf, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_33, TSCP_DARK_ASSERT_1);
	/*- 从接收线程获取输入报文 */
	rt = CM_MQ_Read(&s_CFM_Rx2oo2_App.MsgQ, s_CFM_Rx2oo2_App.cache_buf, &len);
	/*- 是否获取成功 */
	if ((ENUM_CM_TRUE == rt) && (6u < len))
	{
		/*- 输出接收数据 */
		len -= 6u;
		rt = CM_Memcpy((void*)pBuf, (CM_SIZE_T)BufSize, (void*)(s_CFM_Rx2oo2_App.cache_buf + 6), (CM_SIZE_T)len);
		CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_33, TSCP_DARK_ASSERT_2);
	}
	else
	{
		/*- 接收长度为0 */
		len = 0u;
	}
	/*- 返回接收长度 */
	return (CM_INT32)len;
}
/**
* @brief 2oo2数据发送
* @param pBuf 发送报文指针
* @param BufLen 发送报文长度
* @return 发送结果
* - ENUM_CM_TRUE 成功
* - ENUM_CM_FALSE 失败
*/
ENUM_CM_RETURN CFM_2oo2_2xStateSend(IN const CM_UINT8* pBuf, IN CM_INT32 BufLen)
{
	/*- 指针防空*/
    CM_ASSERT(NULL != pBuf, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_38, TSCP_DARK_ASSERT_1);
    /*- 返回发送结果 */
    return CFM_2oo2_Send_Currency(s_CFM_Sock.Sock_2oo2_2x2_State,pBuf, BufLen,g_PFM_Cfg.Peer_Cfg.Port_2oo2_2x2_State);
}

/**
* @brief 2oo2数据接收
* @param pBuf 接收报文指针
* @param BufLen 接收报文缓冲区大小
* @return 接收报文长度
* - 正整数 接收报文长度
* - 0 接收失败
*/
CM_INT32 CFM_2oo2_2xStateRecv(OUT CM_UINT8* pBuf, IN CM_UINT32 BufSize)
{
    /*- 指针防空*/
    /*- 变量初始化 */
	CM_UINT16 len = (CM_UINT16)((BufSize > 65535u) ? 65535u : BufSize);
	ENUM_CM_RETURN rt = ENUM_CM_FALSE;
	/*- 指针防空*/
	CM_ASSERT(NULL != pBuf, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_39, TSCP_DARK_ASSERT_1);
	/*- 从接收线程获取输入报文 */
	rt = CM_MQ_Read(&s_CFM_Rx2oo2_State.MsgQ, s_CFM_Rx2oo2_State.cache_buf, &len);
	/*- 是否获取成功 */
	if ((ENUM_CM_TRUE == rt) && (6u < len))
	{
		/*- 输出接收数据 */
		len -= 6u;
		rt = CM_Memcpy((void*)pBuf, (CM_SIZE_T)BufSize, (void*)(s_CFM_Rx2oo2_State.cache_buf + 6), (CM_SIZE_T)len);
		CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_39, TSCP_DARK_ASSERT_2);
	}
	else
	{
		/*- 接收长度为0 */
		len = 0u;
	}
	/*- 返回接收长度 */
	return (CM_INT32)len;
}
/**
* @brief 2oo2数据发送(维护模式)
* @param pBuf 发送报文指针
* @param BufLen 发送报文长度
* @return 发送结果
* - ENUM_CM_TRUE 成功
* - ENUM_CM_FALSE 失败
*/
ENUM_CM_RETURN CFM_2oo2_DataSend_Crash(IN const CM_UINT8* pBuf, IN CM_INT32 BufLen)
{
    /*- 返回发送结果 */
    return CFM_2oo2_Send_Currency(s_CFM_Sock.Sock_2oo2_Maintenance,pBuf, BufLen,g_PFM_Cfg.Peer_Cfg.Port_2oo2_Maintenance);
}


/**
* @brief 2oo2数据接收(维护模式)
* @param pBuf 接收报文指针
* @param BufLen 接收报文缓冲区大小
* @return 接收报文长度
* - 正整数 接收报文长度
* - 0 接收失败
*/
CM_INT32 CFM_2oo2_DataRecv_Crash(OUT CM_UINT8* pBuf, IN CM_UINT32 BufSize)
{
    /*- 变量初始化 */
    CM_UINT16 len = (CM_UINT16)((BufSize > 65535u) ? 65535u : BufSize);
    ENUM_CM_RETURN rt = ENUM_CM_FALSE;
    /*- 指针防空*/
    CM_ASSERT_MAINTAIN(NULL != pBuf);
    /*- 从接收线程获取输入报文 */
    rt = CM_MQ_Read(&s_CFM_Rx2oo2Mainteance.MsgQ, s_CFM_Rx2oo2Mainteance.cache_buf, &len);

    /*- 是否获取成功 */
    if ((ENUM_CM_TRUE == rt) && (6u < len))
    {
        /*- 输出接收数据 */
        len -= 6u;
        rt = CM_Memcpy((void*)pBuf, (CM_SIZE_T)BufSize, (void*)(s_CFM_Rx2oo2Mainteance.cache_buf + 6), (CM_SIZE_T)len);
        CM_ASSERT_MAINTAIN(ENUM_CM_TRUE == rt);
    }
    else
    {
        /*- 接收长度为0 */
        len = 0u;
    }
    /*- 返回接收长度 */
    return (CM_INT32)len;
}
/**
* @brief 2oo2数据发送(宕机状态)
* @param pBuf 发送报文指针
* @param BufLen 发送报文长度
* @return 发送结果
* - ENUM_CM_TRUE 成功
* - ENUM_CM_FALSE 失败
*/
ENUM_CM_RETURN CFM_2oo2_DataSend_ASSERT(IN const CM_UINT8* pBuf, IN CM_INT32 BufLen)
{
    /*- 返回发送结果 */
    return CFM_2oo2_Send_Currency(s_CFM_Sock.Sock_2oo2_Data,pBuf, BufLen,g_PFM_Cfg.Peer_Cfg.Port_2oo2_Data);
}

/**
* @brief 2oo2数据接收(宕机状态)
* @param pBuf 接收报文指针
* @param BufLen 接收报文缓冲区大小
* @return 接收报文长度
* - 正整数 接收报文长度
* - 0 接收失败
*/
CM_INT32 CFM_2oo2_DataRecv_ASSERT(OUT CM_UINT8* pBuf, IN CM_UINT32 BufSize)
{
    /*- 变量初始化 */
    CM_UINT16 len = (CM_UINT16)((BufSize > 65535u) ? 65535u : BufSize);
    ENUM_CM_RETURN rt = ENUM_CM_FALSE;
    /*- 指针防空*/
    CM_ASSERT_MAINTAIN(NULL != pBuf);
    /*- 从接收线程获取输入报文 */
    rt = CM_MQ_Read(&s_CFM_Rx2oo2.MsgQ, s_CFM_Rx2oo2.cache_buf, &len);
    /*- 是否获取成功 */
    if ((ENUM_CM_TRUE == rt) && (6u < len))
    {
        /*- 输出接收数据 */
        len -= 6u;
        (void)CM_Memcpy((void*)pBuf, (CM_SIZE_T)BufSize, (void*)(s_CFM_Rx2oo2.cache_buf + 6), (CM_SIZE_T)len);
    }
    else
    {
        /*- 接收长度为0 */
        len = 0u;
    }
    /*- 返回接收长度 */
    return (CM_INT32)len;
}

/**
* @breif 全双工不分包2oo2数据交换，支持重传
* @param pMyData 本机数据指针
* @param DataLen 本剧数据长度
* @param pPeerData 邻机数据指针
* @param DataSize 邻机数据缓冲区大小
* @param msgTye 2oo2交换数据类型
* @return 收到的邻机数据长度
*/
CM_INT32 CFM_2oo2_Currency_NoSplit(STRU_2OO2_NET_NO_PACK_T *p_2oo2_Ctrl,IN const CM_UINT8 * pMyData, IN CM_INT32 DataLen, OUT CM_UINT8 * pPeerData, IN CM_UINT32 DataSize)
{
    /*- 变量初始化 */
    CM_INT32 	rxLen 			= -1;
    CM_INT32 	allLen 			= -1;      /* 收到的报文总长度 */
    CM_UINT8 	recvBuf[1500] 	= {0u};
    CM_UINT32 	msgLen	 		= 0u;
    CM_UINT8 	msgType 		= 0u;
    CM_UINT32 	msgSN 			= 0u;
    CM_UINT32 	msgCyc 			= 0u;
    CM_BOOL 	mineRcvFlag 	= CM_FALSE;/*本机接收完成标志*/
    CM_BOOL 	peerRcvFlag 	= CM_FALSE;/*对系接收完成标志*/
    /*发送相关*/
    CM_UINT8 	sendBuf[1500] 	= {0u};
    CM_UINT32 	sysCyc 			= DFM_GetBirthCount(); /*平台周期号*/

    CM_UINT64 curTick = 0u; /* 当前时刻 */
    CM_UINT64 sTick = 0u; /* 起始Tick */
    /*- 入口检查 */
    if((p_2oo2_Ctrl != NULL) && (pMyData != NULL) && (DataLen < 1490) && (pPeerData != NULL))
    {
    	/*- 更新2oo2通信序列号 */
		p_2oo2_Ctrl->SN++;
		/*
		2oo2通信帧格式：
		4字节 长度(不含自身)
		4字节 周期号
		4字节 序列号
		1字节 类型
		*/
		CM_LongToChar((CM_UINT32)DataLen + 9u, &sendBuf[0]);         /* 长度（暂时填写满帧） */
		CM_LongToChar(sysCyc, &sendBuf[4]);               /* 周期号 */
		CM_LongToChar(p_2oo2_Ctrl->SN, &sendBuf[8]);      /* 序列号 */
		sendBuf[12] = (CM_UINT8)ENUM_2oo2_NET_DATA;       /* 类型 */
		(void)CM_Memcpy((void*)(&sendBuf[13]),1490u,pMyData,(CM_SIZE_T)DataLen);

		/*- 发送2oo2数据 */
		(void)p_2oo2_Ctrl->DataSend(sendBuf, DataLen + 13);
		/*- 记录起始时间*/
		sTick = CM_GetTick();
		while(1)
		{
			rxLen = p_2oo2_Ctrl->DataRecv(recvBuf,1500u);
			if(rxLen >= 13)
			{
				msgLen = CM_LongFromChar(&recvBuf[0]);
				msgCyc = CM_LongFromChar(&recvBuf[4]);
				msgSN = CM_LongFromChar(&recvBuf[8]);
				msgType = recvBuf[12];
				if(((msgLen + 4u) == (CM_UINT32)rxLen)
					&& (msgCyc == sysCyc)
					&& (msgSN == p_2oo2_Ctrl->SN))
				{
					switch((ENUM_2oo2_NET_T)msgType)
					{
					case ENUM_2oo2_NET_ARQ:
						/*- 发送2oo2数据 */
						(void)p_2oo2_Ctrl->DataSend(sendBuf, DataLen + 13);
						if(CM_TRUE == mineRcvFlag)
						{
							(void)CFM_2oo2_SendARQ_Currency(p_2oo2_Ctrl,ENUM_2oo2_NET_RCV_SUCCESS);
						}
						break;
					case ENUM_2oo2_NET_RCV_SUCCESS:
						peerRcvFlag = CM_TRUE;
						break;
					case ENUM_2oo2_NET_DATA:
						if(CM_FALSE == mineRcvFlag)
						{
							/*接收成功*/
							allLen = (CM_INT32)(msgLen - 9u);
							(void)CM_Memcpy((void*)pPeerData,DataSize,&recvBuf[13],(CM_SIZE_T)allLen);
							mineRcvFlag = CM_TRUE;
							(void)CFM_2oo2_SendARQ_Currency(p_2oo2_Ctrl,ENUM_2oo2_NET_RCV_SUCCESS);
							(void)CFM_2oo2_SendARQ_Currency(p_2oo2_Ctrl,ENUM_2oo2_NET_RCV_SUCCESS);
							(void)CFM_2oo2_SendARQ_Currency(p_2oo2_Ctrl,ENUM_2oo2_NET_RCV_SUCCESS);
						}
						else
						{
							/*重复接收无处理*/
						}
						break;
					default:
						/*- 类型错误*/
						break;
					}
				}
				else
				{
					/*校验错误需要宕机-重传*/
				}
			}
			else
			{
				/*- 记录当前时间*/
				CM_Sleep(1);
				curTick = CM_GetTick();
				/*- 超时重传，接收成功标志不响应*/
				if((CM_UNSIGNED_MILLION*10u) < (curTick-sTick))
				{
					/*发送重传请求*/
					(void)CFM_2oo2_SendARQ_Currency(p_2oo2_Ctrl,ENUM_2oo2_NET_ARQ);
					/*- 重置起始时间*/
					sTick = CM_GetTick();
				}
				else
				{
					/*- 无处理 */
				}
			}
	        if((CM_TRUE == mineRcvFlag) && (CM_TRUE == peerRcvFlag))
	        {
	        	/*- 结束接收 */
	        	rxLen = (CM_INT32)msgLen - 9;
	        	break;
	        }
	        else
	        {
	        	/*- 无处理 */
	        }
		}/*while*/
    }
    else
    {
    	rxLen = -1;
    }
    /*- 返回收到的报文长度 */
    return allLen;
}


/*********************************2X相关*****************************************/

/**
* @brief 2x2相关网络通信初始化
*/
static void s_NetInit_2x2(void)
{
    /*- 变量初始化 */
    ENUM_CM_RETURN rt = ENUM_CM_FALSE; /* 临时变量 */
    CM_INT32 val = 0;                  /* 临时变量 */
    CM_BOOL rtCheck = CM_FALSE;         /* 临时变量 */
    /*- 创建socket */
    rt = CM_UDP_Socket_Create(&s_CFM_Sock.Sock_2x2_Time, CM_FALSE, (CM_UINT32)inet_addr(g_PFM_Cfg.Local_Cfg.IP_2x2), g_PFM_Cfg.Local_Cfg.Port_2x2_Time, 0u, (CM_UINT8)0);
    CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);

    rt = CM_UDP_Socket_Create(&s_CFM_Sock.Sock_2x2_Data, CM_FALSE, (CM_UINT32)inet_addr(g_PFM_Cfg.Local_Cfg.IP_2x2), g_PFM_Cfg.Local_Cfg.Port_2x2_Data, 0u, (CM_UINT8)0);
    CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_2);
    rt = CM_UDP_Socket_Create(&s_CFM_Sock.Sock_2x2_Syn, CM_FALSE, (CM_UINT32)inet_addr(g_PFM_Cfg.Local_Cfg.IP_2x2), g_PFM_Cfg.Local_Cfg.Port_2x2_Syn, 0u, (CM_UINT8)0);
    CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_3);
    /*- 创建2x状态切换独立线程socket */
    rt = CM_UDP_Socket_Create(&s_CFM_Sock.Sock_2x2_State, CM_FALSE, (CM_UINT32)inet_addr(g_PFM_Cfg.Local_Cfg.IP_2x2), g_PFM_Cfg.Local_Cfg.Port_2x2_State, 0u, (CM_UINT8)0);
    CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_13);

    /*- 初始化控制信息 */
    CM_ASSERT(s_CFM_2x2_Time.IP != NULL, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_4);
	(void)sprintf(s_CFM_2x2_Time.IP, "%s", g_PFM_Cfg.Local_Cfg.IP_2x2);
	s_CFM_2x2_Time.port = g_PFM_Cfg.Local_Cfg.Port_2x2_Time;
	s_CFM_2x2_Time.pSock = &s_CFM_Sock.Sock_2x2_Time;
	rt = CM_Mutex_Init(&s_CFM_2x2_Time.mutex);
	CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_5);

    /*- 配置socket */
    val = (CM_INT32)(NET_UDP_BUF_DOUBLESIZE);
    (void)setsockopt(s_CFM_Sock.Sock_2x2_Data, SOL_SOCKET, SO_RCVBUF, (void*)(&val), (unsigned int)sizeof(val));
    (void)setsockopt(s_CFM_Sock.Sock_2x2_Data, SOL_SOCKET, SO_SNDBUF, (void*)(&val), (unsigned int)sizeof(val));

    CM_ASSERT(s_CFM_2x2_Syn.IP != NULL, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_6);
    (void)sprintf(s_CFM_2x2_Syn.IP, "%s", g_PFM_Cfg.Local_Cfg.IP_2x2);
    s_CFM_2x2_Syn.port = g_PFM_Cfg.Local_Cfg.Port_2x2_Syn;
    s_CFM_2x2_Syn.pSock = &s_CFM_Sock.Sock_2x2_Syn;
    rt = CM_Mutex_Init(&s_CFM_2x2_Syn.mutex);
    CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_7);

    /*- 配置接收线程 */
    CM_ASSERT(s_CFM_Rx2x2.IP != NULL, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_8);
    (void)sprintf(s_CFM_Rx2x2.IP, "%s", g_PFM_Cfg.Local_Cfg.IP_2x2);
    s_CFM_Rx2x2.port = g_PFM_Cfg.Local_Cfg.Port_2x2_Data;
    s_CFM_Rx2x2.pSock = &s_CFM_Sock.Sock_2x2_Data;
    s_CFM_Rx2x2.rmtIP = inet_addr(g_PFM_Cfg.Partner_Cfg.IP_2x2);
    s_CFM_Rx2x2.rmtPort = g_PFM_Cfg.Partner_Cfg.Port_2x2_Data;
    rt = CM_MQ_Init(&s_CFM_Rx2x2.MsgQ, (CM_UINT16)CFM_2X2_MSG_NUM_MAX, (CM_UINT16)NET_UDP_2X2_BUF_SIZE);
    CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_9);

    /*-配置状态切换线程 */
    CM_ASSERT(s_CFM_State2x2.IP != NULL, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_14);
    (void)sprintf(s_CFM_State2x2.IP, "%s", g_PFM_Cfg.Local_Cfg.IP_2x2);
    s_CFM_State2x2.port = g_PFM_Cfg.Local_Cfg.Port_2x2_State;
    s_CFM_State2x2.pSock = &s_CFM_Sock.Sock_2x2_State;
    s_CFM_State2x2.rmtIP = inet_addr(g_PFM_Cfg.Partner_Cfg.IP_2x2);
    s_CFM_State2x2.rmtPort = g_PFM_Cfg.Partner_Cfg.Port_2x2_State;
    s_CFM_State2x2.threadNumBer = (CM_UINT8)ENUM_THREAD_2x2_StateRecv;
    rt = CM_MQ_Init(&s_CFM_State2x2.MsgQ, (CM_UINT16)CFM_2X2_MSG_NUM_MAX, (CM_UINT16)CFM_2X2_MSG_NUM_MAX);
    CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_15);

    /*- 启动2x2时钟同步线程 */
    rtCheck = CM_Thread_Create((CM_THREAD_T*)NULL, (CM_THREAD_FUNC_T)t_TimeThread, "2x2_T", 0, CM_TASK_PRIORITY_76, (CM_Thread_Arg_Struct_T*)&s_CFM_2x2_Time);
    CM_ASSERT(CM_TRUE == rtCheck,NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_10);
    CM_Sleep(100u);/* 延时等待线程启动 */
    /*- 启动2x2周期同步线程 */
    rtCheck = CM_Thread_Create((CM_THREAD_T*)NULL, (CM_THREAD_FUNC_T)t_SyncThread, "2x2_Syn", 0, CM_TASK_PRIORITY_77, (CM_Thread_Arg_Struct_T*)&s_CFM_2x2_Syn);
    CM_ASSERT(CM_TRUE == rtCheck, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_16);
    CM_Sleep(100u);/* 延时等待线程启动 */

    /*- 启动2x2平台数据接收线程 */
    rtCheck = CM_Thread_Create((CM_THREAD_T*)NULL, (CM_THREAD_FUNC_T)t_UdpRecvThread, "2x2_Rx", 0, CM_TASK_PRIORITY_77, (CM_Thread_Arg_Struct_T*)&s_CFM_Rx2x2);
    CM_ASSERT(CM_TRUE == rtCheck, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_11);
    /*- 启动2x2平台数据接收线程 */
    rtCheck = CM_Thread_Create((CM_THREAD_T*)NULL, (CM_THREAD_FUNC_T)t_UdpRecvThread, "2x2_RxState", 0, CM_TASK_PRIORITY_77, (CM_Thread_Arg_Struct_T*)&s_CFM_State2x2);
    CM_ASSERT(CM_TRUE == rtCheck, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_12);
    CM_Sleep(100u);/* 延时等待线程启动 */

}

/**
* @brief 2x2状态数据发送
* @param pBuf 发送报文指针 取值范围：非空
* @param BufLen 发送报文长度 取值范围：0~0x7FFFFFFF
* @return 发送结果
* - ENUM_CM_TRUE 成功
* - ENUM_CM_FALSE 失败
*/
ENUM_CM_RETURN CFM_2x2_StateChange_Send(IN const CM_UINT8* pBuf, IN CM_INT32 BufLen)
{
    /*- 变量初始化 */
    ENUM_CM_RETURN rt = ENUM_CM_FALSE;
    /*- 入参指针防空 */
    if(NULL != pBuf)
    {
		/*- 2x状态切换UDP通信通道向对系发送 */
    	rt = CM_UDP_Send_Msg(s_CFM_Sock.Sock_2x2_State, pBuf, BufLen, inet_addr(g_PFM_Cfg.Partner_Cfg.IP_2x2),g_PFM_Cfg.Partner_Cfg.Port_2x2_State);
    }
    else
    {
    	/*空指针返回失败*/
    }
    /*- 返回发送结果 */
    return rt;
}

/**
* @brief 通用2x2状态数据接收
* @param pBuf 接收报文指针 取值范围：非空
* @param BufLen 接收报文缓冲区大小 取值范围：0~0xFFFFFFFF
* @return 接收报文长度
* - 1~0xFFFFFFFF 接收报文长度
* - 0 接收失败
*/
CM_INT32 CFM_2x2_StateChange_Recv(CM_UINT8* pBuf, IN CM_UINT32 BufSize)
{
    /*- 变量初始化 */
    CM_UINT16 len = (BufSize > 65535u) ? (CM_UINT16)(65535u) : (CM_UINT16)(BufSize);
    ENUM_CM_RETURN rt = ENUM_CM_FALSE;
    CM_UINT8  tempBuf[200] = {0};
    CM_RE_ASSERT(NULL != pBuf, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_40, TSCP_DARK_ASSERT_1);
    /*- 从接收线程获取输入报文 */
    rt = CM_MQ_Read(&s_CFM_State2x2.MsgQ, tempBuf, &len);
    /*- 是否获取成功 */
    if ((rt == ENUM_CM_TRUE) && (len > 6u))
    {
        /*- 输出接收数据 */
        rt = CM_Memcpy((void*)pBuf, (CM_SIZE_T)BufSize, (void*)(tempBuf), (CM_SIZE_T)len);
        CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_40, TSCP_DARK_ASSERT_2);
    }
    else
    {
        /*- 接收长度为0 */
        len = 0u;
    }
    /*- 返回接收长度 */
    return (CM_INT32)len;
}
/**
* @brief 发起一次2x2时钟同步
* @details
* 发送一个2x2时钟同步请求报文
* 由双方的时钟同步线程完成一次NTP校时操作
* 操作完成后本方的时钟同步线程会记录到延迟时间和偏移时间
* @see :: CFM_2x2_TimeGet
* @see :: t_TimeThread
*/
void CFM_2x2_TimeReq(void)
{
    /*- 变量初始化 */
    CM_UINT8 buf[100];
    CM_INT32 len = 0;
    CM_ATOMIC CM_UINT64 tick = 0u;
    ENUM_CM_RETURN rt = ENUM_CM_FALSE;
    /*- 生成时钟同步请求报文 */
    len = 9;
    buf[0] = (CM_UINT8)ENUM_TIME_REQ;

    tick = DFM_GetCycTick();

    CM_64ToChar(tick, buf + 1);
    /*- 发送时钟同步请求报文 */
    rt = CM_UDP_Send_Msg(s_CFM_Sock.Sock_2x2_Time, buf, len, inet_addr(g_PFM_Cfg.Partner_Cfg.IP_2x2), g_PFM_Cfg.Partner_Cfg.Port_2x2_Time);
    if(ENUM_CM_TRUE != rt)
    {
    	(void)CFM_DarkLog_Storage(DARK_LOG_HEX, TSCP_DARK_WARNING, 4U, DARK_FAULT_CODE_MERGE(NET_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1));
    	MSCP_LOG_MSG("CFM_2x2_TimeReq UDP_SEND Error!\n");
    }
    else
    {
    	 /*- 不处理 */
    }
}
/**
* @brief 读取2x2时钟同步结果
* @param pDelay 延迟时间
* @param pOffset 偏移时间
* @return 执行结果
* - ENUM_CM_TRUE 成功
* - ENUM_CM_FALSE 失败
*/
ENUM_CM_RETURN CFM_2x2_TimeGet(OUT CM_INT64* pDelay, OUT CM_INT64* pOffset)
{

    /*- 变量初始化 */
    ENUM_CM_RETURN rt = ENUM_CM_FALSE;
	ENUM_CM_RETURN ret = ENUM_CM_FALSE;
    /*- 指针不为空 */
	if((NULL != pDelay) && (NULL != pOffset))
	{
		/*- 锁定互斥锁 */
		rt = CM_Mutex_Lock(s_CFM_2x2_Time.mutex);
		CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_16, TSCP_DARK_ASSERT_1);
		/*- 是否保存了时钟同步结果 */
		if (ENUM_CM_TRUE == s_CFM_2x2_Time.isOK)
		{
			/*- 读取时钟同步结果 */
			*pDelay = s_CFM_2x2_Time.delay;
			*pOffset = s_CFM_2x2_Time.offset;
			/*- 清除时钟同步结果 */
			s_CFM_2x2_Time.isOK = ENUM_CM_FALSE;
			ret = ENUM_CM_TRUE;
		}
		else
		{
			//TSCP_DARK_CFMNET_2x2TIMEGET_REDERROR
			(void)CFM_DarkLog_Storage(DARK_LOG_HEX, TSCP_DARK_WARNING, 4U, DARK_FAULT_CODE_MERGE(NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1));
			MSCP_LOG_MSG("s_CFM_2x2_Time.isOK != ENUM_CM_TRUE\n");
		}
		/*- 释放互斥锁 */
		rt = CM_Mutex_Unlock(s_CFM_2x2_Time.mutex);
		CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_16, TSCP_DARK_ASSERT_2);
	}
	else
	{
		//TSCP_DARK_CFMNET_2x2TIMEGET_REDNULL
		(void)CFM_DarkLog_Storage(DARK_LOG_HEX, TSCP_DARK_WARNING, 4U, DARK_FAULT_CODE_MERGE(NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_2));
		MSCP_LOG_MSG("pDelay == NULL || pOffset == NULL\n");
	}
    /*- 返回执行结果 */
	return ret;
}
/**
* @brief 周期同步线程
* @param arg 指向STRU_CFM_SYN_CTRL的指针
* @return 线程函数返回值（实际永远不会返回）
* @details
* 创建本线程之前应先配置好STRU_CFM_SYN_CTRL，包括创建阻塞通信的socket
* 本线程将以阻塞方式接收周期同步报文、并记录收到报文的精确时间
* @see :: CFM_2x2_SyncSend
* @see :: CFM_2x2_SyncRecv
*/
static CM_THREAD_FUNC_T t_SyncThread(IN CM_Thread_Arg_Struct_T* arg)
{
    /*- 变量初始化 */
    STRU_CFM_SYN_CTRL_T* pCtrl = (STRU_CFM_SYN_CTRL_T*)arg; /* 线程参数 */
    CM_UINT32 srcIP = 0u;         /* 源IP */
    CM_UINT16 srcPort = 0u;       /* 源端口 */
    CM_UINT8 buf[1000] = { 0u };  /* 接收缓冲区 */
    CM_INT32 len;                 /* 数据长度 */
    CM_UINT64 tick = 0u;          /* 精确时间 */
    ENUM_CM_RETURN rt = ENUM_CM_FALSE;
#if QNX
    void* pmask = NULL;
    /*- 本线程锁定在 A53 core 1 */
    pmask = (void*)(0x01u|0x02u);
    (void)ThreadCtl(_NTO_TCTL_RUNMASK, pmask);
#endif
    MSCP_LOG_MSG("IP:%s:%d Sync Service Start\n", pCtrl->IP, (CM_INT32)pCtrl->port);
    /*- 循环接收同步报文 */
    while (1)
    {
        /*- 阻塞接收周期同步报文 */
        len = CM_UDP_Recv_Msg(*(pCtrl->pSock), buf, (CM_INT32)sizeof(buf), &srcIP, &srcPort);
        tick = CM_GetTick();
        /*- 是否收到有效报文 */
        if (len > 0)
        {
            /*- 记录报文内容和接收时刻 */
        	rt = CM_Mutex_Lock(pCtrl->mutex);
        	CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_17, TSCP_DARK_ASSERT_1);

            pCtrl->rxLen = len;
            rt = CM_Memcpy((void*)pCtrl->rxBuf, sizeof(pCtrl->rxBuf), (void*)buf, (CM_SIZE_T)len);
            CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_17, TSCP_DARK_ASSERT_2);
            pCtrl->rxTick = tick;

            rt = CM_Mutex_Unlock(pCtrl->mutex);
            CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_17, TSCP_DARK_ASSERT_3);
        }
        else
        {
            /*- 不处理 */
        }
    }
    return NULL;
}

/**
* @brief 2x2同步发送
* @param pBuf 发送报文指针
* @param BufLen 发送报文长度
* @return 发送结果
* - ENUM_CM_TRUE 成功
* - ENUM_CM_FALSE 失败
*/
ENUM_CM_RETURN CFM_2x2_SyncSend(IN const CM_UINT8* pBuf, IN CM_INT32 BufLen)
{
    /*- 变量初始化 */
    ENUM_CM_RETURN rt = ENUM_CM_FALSE;
    /* UDP方式从2x2周期同步通道发送 */
    rt = CM_UDP_Send_Msg(s_CFM_Sock.Sock_2x2_Syn, pBuf, BufLen, inet_addr(g_PFM_Cfg.Partner_Cfg.IP_2x2),g_PFM_Cfg.Partner_Cfg.Port_2x2_Syn);
    /*- 返回发送结果 */
    return rt;
}

/**
* @brief 2x2同步接收
* @param pBuf 接收报文指针
* @param bufSize 接收缓冲区大小
* @param pRxTick 接收时刻
* @return 接收报文长度
* - 正整数 接收报文长度
* - 0或负数 接收失败
*/
CM_INT32 CFM_2x2_SyncRecv(OUT CM_UINT8* pBuf, IN CM_UINT32 bufSize, OUT CM_UINT64* pRxTick)
{
    /*- 变量初始化 */
    CM_INT32 len = 0;
    ENUM_CM_RETURN rt = ENUM_CM_FALSE;
    /*- 锁定互斥信号量 */
    rt = CM_Mutex_Lock(s_CFM_2x2_Syn.mutex);
    CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_18, TSCP_DARK_ASSERT_1);
    /*- 是否报文长度大于0且接收缓冲区足够大 */
    if ((s_CFM_2x2_Syn.rxLen > 0) && ((CM_UINT32)s_CFM_2x2_Syn.rxLen <= bufSize))
    {
        /*- 输出接收报文 */
        len = s_CFM_2x2_Syn.rxLen;
        rt = CM_Memcpy((void*)pBuf, (CM_SIZE_T)bufSize, (void*)s_CFM_2x2_Syn.rxBuf, (CM_SIZE_T)s_CFM_2x2_Syn.rxLen);
        CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_18, TSCP_DARK_ASSERT_2);
        *pRxTick = s_CFM_2x2_Syn.rxTick;

        /*- 清除报文长度 */
        s_CFM_2x2_Syn.rxLen = 0;
    }
    else
	{
		/*- 无处理 */
	}
    /*- 释放互斥信号量 */
    rt = CM_Mutex_Unlock(s_CFM_2x2_Syn.mutex);
    CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_18, TSCP_DARK_ASSERT_3);
    /*- 返回报文长度 */
    return len;
}



/**
* @brief 2x2数据发送
* @param pBuf 发送报文指针
* @param BufLen 发送报文长度
* @return 发送结果
* - ENUM_CM_TRUE 成功
* - ENUM_CM_FALSE 失败
*/
ENUM_CM_RETURN CFM_2x2_DataSend(IN const CM_UINT8* pBuf, IN CM_INT32 BufLen)
{
    /*- 变量初始化 */
    ENUM_CM_RETURN rt = ENUM_CM_FALSE;
    /*- UDP方式从2x2数据通道发送报文 */
    rt = CM_UDP_Send_Msg(s_CFM_Sock.Sock_2x2_Data, pBuf, BufLen, inet_addr(g_PFM_Cfg.Partner_Cfg.IP_2x2), g_PFM_Cfg.Partner_Cfg.Port_2x2_Data);
    /*- 返回发送结果 */
    return rt;
}
/**
* @brief 2x2串口数据发送
* @param pBuf 发送报文指针 取值范围(非空)
* @param BufLen 发送报文长度 取值范围(0~0xffffffff)
* @param msgType 发送报文类型
* @return 发送结果
* - ENUM_CM_TRUE 成功
* - ENUM_CM_NULL 发送条件不满足
* - ENUM_CM_FALSE 失败
*/
ENUM_CM_RETURN CFM_2x2_UartDataSend(IN CM_UINT8* pBuf, IN CM_UINT16 BufLen)
{
	ENUM_CM_RETURN rtnval = ENUM_CM_FALSE;
#ifdef QNX
	/*- 返回发送结果 */
	rtnval = CM_Com_LocalDataSend((CM_UINT8*)pBuf, BufLen);
#else
    rtnval = ENUM_CM_TRUE;
#endif
    return rtnval;
}
/**
* @brief 2x2数据接收
* @param pBuf 接收报文指针
* @param BufLen 接收报文缓冲区大小
* @return 接收报文长度
* - 正整数 接收报文长度
* - 0或负数 接收失败
*/
CM_INT32 CFM_2x2_DataRecv(OUT CM_UINT8* pBuf, IN CM_UINT32 BufSize)
{
    /*- 变量初始化 */
    CM_UINT16 len = (BufSize > 65535u) ? (CM_UINT16)(65535u) : (CM_UINT16)(BufSize);
    ENUM_CM_RETURN rt = ENUM_CM_FALSE;
    /*- 从接收线程获取输入报文 */
    rt = CM_MQ_Read(&s_CFM_Rx2x2.MsgQ, s_CFM_UDP_Cache, &len);
    /*- 是否获取成功 */
    if ((rt == ENUM_CM_TRUE) && (len > 6u))
    {
        /*- 输出接收数据 */
        len -= 6u;
        rt = CM_Memcpy((void*)pBuf, (CM_SIZE_T)BufSize, (void*)(s_CFM_UDP_Cache + 6), (CM_SIZE_T)len);
        CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_20, TSCP_DARK_ASSERT_1);
    }
    else
    {
        /*- 接收长度为0 */
        len = 0u;
    }
    /*- 返回接收长度 */
    return (CM_INT32)len;
}
/**
* @brief 2x2串口数据接收
* @param pBuf 接收报文指针(非空)
* @param BufLen 接收报文缓冲区大小(0~0xffffffff)
* @return 接收报文长度
* - 正整数 接收报文长度
* - 0或负数 接收失败
*/
CM_UINT16 CFM_2x2_UartDataRecv(OUT CM_UINT8* pBuf, IN CM_UINT32 BufSize)
{
#ifdef QNX

    /*- 返回发送结果 */
    return CM_Com_OtherDataRecv(pBuf, BufSize);
#else
    return 0;
#endif
}

/*********************************内网通信相关*****************************************/

/**
* @brief 内网通信初始化
*/
static void s_NetInit_Innet(void)
{
    /*- 变量初始化 */
    ENUM_CM_RETURN rt = ENUM_CM_FALSE; /* 临时变量 */
    CM_INT32 rcv_val = 0;     /* 临时变量 */
    CM_INT32 send_val = 0;     /* 临时变量 */
    CM_INT32 i = 0;     /* 循环变量 */
    CM_INT32 bCast = 1;
    CM_CHAR *p_tmpIPCom;
    CM_BOOL rtCheck = CM_FALSE;
    rcv_val = (CM_INT32)NET_UDP_BUF_SIZE;
    send_val = (CM_INT32)(NET_UDP_BUF_SIZE);
	STRU_PFM_INNET_CFG_T *pCom = NULL;

    /*- 创建安全通信socket */
    rt = CM_UDP_Socket_Create(&s_CFM_Sock.Sock_InnetSafe, CM_FALSE, (CM_UINT32)inet_addr(g_PFM_Cfg.Local_Cfg.IP_Com), g_PFM_Cfg.Local_Cfg.Port_Innet_Safe, 0u, (CM_UINT8)0);
    CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_3, TSCP_DARK_ASSERT_1);
    (void)setsockopt(s_CFM_Sock.Sock_InnetSafe, SOL_SOCKET, SO_RCVBUF, (void*)(&rcv_val), (unsigned int)sizeof(rcv_val));
    (void)setsockopt(s_CFM_Sock.Sock_InnetSafe, SOL_SOCKET, SO_SNDBUF, (void*)(&send_val), (unsigned int)sizeof(send_val));

    /*- 配置和启动内网安全通信接收线程 */
    CM_ASSERT(s_CFM_RxInnetSafe.IP != NULL, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_3, TSCP_DARK_ASSERT_2);
    (void)sprintf(s_CFM_RxInnetSafe.IP, "%s", g_PFM_Cfg.Local_Cfg.IP_Com);
    s_CFM_RxInnetSafe.port = g_PFM_Cfg.Local_Cfg.Port_Innet_Safe;
    s_CFM_RxInnetSafe.pSock = &s_CFM_Sock.Sock_InnetSafe;
    s_CFM_RxInnetSafe.rmtIP = 0u;
    rt = CM_MQ_Init(&s_CFM_RxInnetSafe.MsgQ, (CM_UINT16)CFM_INNET_SAFE_MSG_NUM_MAX, (CM_UINT16)(CFM_INNET_SAFE_MSG_SIZE));
    CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_3, TSCP_DARK_ASSERT_3);
    rtCheck = CM_Thread_Create((CM_THREAD_T*)NULL, (CM_THREAD_FUNC_T)t_UdpRecvThread, "InnetS_Rx", 0, CM_TASK_PRIORITY_77, (CM_Thread_Arg_Struct_T*)&s_CFM_RxInnetSafe);
    CM_ASSERT(CM_TRUE == rtCheck, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_3, TSCP_DARK_ASSERT_4);
    CM_Sleep(100u);/* 延时等待线程启动 */

    s_CFM_Sock.num_InnetRaw = g_PFM_Cfg.Local_Cfg.Port_Innet_Raw_Num;
    s_CFM_Sock.num_InnetRaw_Extend = g_PFM_Cfg.Local_Cfg.Port_Innet_Raw_Extend_Num;
    /*- @alias 创建透传通信socket */
    for (i = 1; i <= (s_CFM_Sock.num_InnetRaw + s_CFM_Sock.num_InnetRaw_Extend); i++)
    {
    	if(i <= s_CFM_Sock.num_InnetRaw)
    	{
    		p_tmpIPCom = g_PFM_Cfg.Local_Cfg.IP_Com;
    	}
    	else
    	{
    		p_tmpIPCom = g_PFM_Cfg.Local_Cfg.IP_Com_Extend;
    	}
    	if(RAW_COM_DISENABLE == g_PFM_Cfg.Local_Cfg.Innet_Raw_Parameter[i].Port_Type_Enable)
    	{
    		/*未使能该通道*/
    	}
    	/*是否使能TCP*/
    	else if (RAW_COM_TCP == g_PFM_Cfg.Local_Cfg.Innet_Raw_Parameter[i].Port_Type_Enable)
		{
			/*- 查询服务端IP、端口 */
			pCom = PFM_INI_InnetID2Addr(g_PFM_Cfg.Local_Cfg.Innet_Raw_Parameter[i].Server_DevId);
			CM_ASSERT(NULL != pCom, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_3, TSCP_DARK_ASSERT_5);
			/*- 创建tcp socket */
			if (1u == g_PFM_Cfg.CPU_ID)
			{
				rt = CM_TCP_Socket_Create(&s_CFM_Sock.Sock_InnetRaw[i], (CM_UINT32)inet_addr(p_tmpIPCom),
										g_PFM_Cfg.Local_Cfg.Innet_Raw_Parameter[i].Port_Innet_Raw,
										g_PFM_Cfg.Local_Cfg.Innet_Raw_Parameter[i].Server_DevId,pCom->IP_G,pCom->Port_Raw_G);
			}
			else
			{
				rt = CM_TCP_Socket_Create(&s_CFM_Sock.Sock_InnetRaw[i], (CM_UINT32)inet_addr(p_tmpIPCom),
										g_PFM_Cfg.Local_Cfg.Innet_Raw_Parameter[i].Port_Innet_Raw,
										g_PFM_Cfg.Local_Cfg.Innet_Raw_Parameter[i].Server_DevId,pCom->IP_P,pCom->Port_Raw_P);
			}
			CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_3, TSCP_DARK_ASSERT_6);
		}
		else
		{
			/*UDP通信*/
			if (RAW_COM_BROADCAST == g_PFM_Cfg.Local_Cfg.Innet_Raw_Parameter[i].Port_Type_Enable)
			{
				bCast = 1;/*广播模式*/
			}
			else
			{
				bCast = 0;/*默认单播组播模式*/
			}
			rt = CM_UDP_Socket_Create(&s_CFM_Sock.Sock_InnetRaw[i],
				CM_FALSE,
				(CM_UINT32)inet_addr(p_tmpIPCom),
				g_PFM_Cfg.Local_Cfg.Innet_Raw_Parameter[i].Port_Innet_Raw,
				(CM_UINT32)inet_addr(g_PFM_Cfg.Local_Cfg.Innet_Raw_Parameter[i].IP_InnetRaw_maddr), (CM_UINT8)bCast);
			CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_3, TSCP_DARK_ASSERT_7);
			rcv_val = (CM_INT32)NET_UDP_BUF_SIZE*60;/*此处必须开大，用于接收GIGE大数据*/
			(void)setsockopt(s_CFM_Sock.Sock_InnetRaw[i], SOL_SOCKET, SO_RCVBUF, (void*)(&rcv_val), (unsigned int)sizeof(rcv_val));
			(void)setsockopt(s_CFM_Sock.Sock_InnetRaw[i], SOL_SOCKET, SO_SNDBUF, (void*)(&send_val), (unsigned int)sizeof(send_val));
		}
    }  

    /*- @alias 配置和启动内网透传通信接收线程 */
    for (i = 1; i <= (s_CFM_Sock.num_InnetRaw + s_CFM_Sock.num_InnetRaw_Extend); i++)
    {
    	if(i <= s_CFM_Sock.num_InnetRaw)
		{
			p_tmpIPCom = g_PFM_Cfg.Local_Cfg.IP_Com;
		}
		else
		{
			p_tmpIPCom = g_PFM_Cfg.Local_Cfg.IP_Com_Extend;
		}
    	if(RAW_COM_DISENABLE == g_PFM_Cfg.Local_Cfg.Innet_Raw_Parameter[i].Port_Type_Enable)
		{
			/*未使能该通道-不开启线程*/
		}
    	/*是否使能TCP*/
    	else if (RAW_COM_TCP == g_PFM_Cfg.Local_Cfg.Innet_Raw_Parameter[i].Port_Type_Enable)
		{
		    /*- 配置接收线程 */
            CM_ASSERT(s_CFM_RxInnetRaw[i].IP != NULL, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_3, TSCP_DARK_ASSERT_8);
		    (void)sprintf(s_CFM_RxInnetRaw[i].IP, "%s", p_tmpIPCom);
		    s_CFM_RxInnetRaw[i].port = g_PFM_Cfg.Local_Cfg.Innet_Raw_Parameter[i].Port_Innet_Raw;
		    s_CFM_RxInnetRaw[i].pSock = &s_CFM_Sock.Sock_InnetRaw[i];
		    s_CFM_RxInnetRaw[i].ch = i;
			if (1u == g_PFM_Cfg.CPU_ID)
			{
			    s_CFM_RxInnetRaw[i].rmtIP = pCom->IP_G;
				s_CFM_RxInnetRaw[i].rmtPort = pCom->Port_Raw_G;
			}
			else
			{
			    s_CFM_RxInnetRaw[i].rmtIP = pCom->IP_P;
				s_CFM_RxInnetRaw[i].rmtPort = pCom->Port_Raw_P;
			}
			s_CFM_RxInnetRaw[i].Tcpid = g_PFM_Cfg.Local_Cfg.Innet_Raw_Parameter[i].Server_DevId;
			s_CFM_RxInnetRaw[i].Offset = (CM_INT32)0;
			/*2取使能时间戳队列和解析算法*/
			if((0x55u == (CM_UINT16)g_PFM_Cfg.Local_Cfg.Innet_Raw_Parameter[i].INNET_2oo2_RAW) && (0x55u == (CM_UINT16)g_PFM_Cfg.Local_Cfg.Innet_Raw_Parameter[i].TIME_STAMP_ENABLE))
			{
				rt = CM_MQ_Init(&s_CFM_RxInnetRaw[i].InfoQ, (CM_UINT16)CFM_INNET_RAW_MSG_NUM_MAX, (CM_UINT16)(16));
				CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_3, TSCP_DARK_ASSERT_9);
				rt = CM_Mutex_Init(&s_CFM_RxInnetRaw[i].mutex);
				rt &= CM_Mutex_Init(&s_CFM_RxInnetRaw[i].clear_mutex);
				CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_3, TSCP_DARK_ASSERT_10);
				s_CFM_RxInnetRaw[i].ALGORITHM_Fun = p_ALGORITHM_Fun[i];/*算法注册表*/
			}
			else
			{
				s_CFM_RxInnetRaw[i].ALGORITHM_Fun = NULL;/*未注册空指针*/
				MSCP_LOG_MSG("TCP[%d]-ALGORITHM_Fun is NULL\n",i);
			}
		    rt = CM_MQ_Init(&s_CFM_RxInnetRaw[i].MsgQ, (CM_UINT16)CFM_INNET_RAW_MSG_NUM_MAX, (CM_UINT16)(CFM_INNET_RAW_MSG_SIZE));
		    CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_3, TSCP_DARK_ASSERT_11);

		    /*- 启动外网安全通信接收线程 */
		    rtCheck = CM_Thread_Create((CM_THREAD_T*)NULL, (CM_THREAD_FUNC_T)t_TcpRecvThread, "InnetS_Rx_Tcp", 0, CM_TASK_PRIORITY_73, (CM_Thread_Arg_Struct_T*)&s_CFM_RxInnetRaw[i]);
		    CM_ASSERT(CM_TRUE == rtCheck, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_3, TSCP_DARK_ASSERT_17);
		    CM_Sleep(100u);/* 延时等待线程启动 */			
		}
		else
		{
			/*UDP通信*/
            CM_ASSERT(s_CFM_RxInnetRaw[i].IP != NULL, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_3, TSCP_DARK_ASSERT_12);
	        (void)sprintf(s_CFM_RxInnetRaw[i].IP, "%s", p_tmpIPCom);
	        s_CFM_RxInnetRaw[i].port = g_PFM_Cfg.Local_Cfg.Innet_Raw_Parameter[i].Port_Innet_Raw;
	        s_CFM_RxInnetRaw[i].pSock = &s_CFM_Sock.Sock_InnetRaw[i];
	        s_CFM_RxInnetRaw[i].rmtIP = 0u;
	        s_CFM_RxInnetRaw[i].ch = i;

	        rt = CM_MQ_Init(&s_CFM_RxInnetRaw[i].MsgQ, (CM_UINT16)CFM_INNET_RAW_MSG_NUM_MAX, (CM_UINT16)(CFM_INNET_RAW_MSG_SIZE));
	        CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_3, TSCP_DARK_ASSERT_13);
	        /*2取使能时间戳队列和解析算法*/
	        if((0x55u == (CM_UINT16)g_PFM_Cfg.Local_Cfg.Innet_Raw_Parameter[i].INNET_2oo2_RAW) && (0x55u == (CM_UINT16)g_PFM_Cfg.Local_Cfg.Innet_Raw_Parameter[i].TIME_STAMP_ENABLE))
	        {
				rt = CM_MQ_Init(&s_CFM_RxInnetRaw[i].InfoQ, (CM_UINT16)CFM_INNET_RAW_MSG_NUM_MAX, (CM_UINT16)(16));
				CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_3, TSCP_DARK_ASSERT_14);
				rt = CM_Mutex_Init(&s_CFM_RxInnetRaw[i].mutex);
				rt &= CM_Mutex_Init(&s_CFM_RxInnetRaw[i].clear_mutex);
				CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_3, TSCP_DARK_ASSERT_15);
		        s_CFM_RxInnetRaw[i].ALGORITHM_Fun = p_ALGORITHM_Fun[i];/*算法注册表*/
		        MSCP_LOG_MSG("Init s_CFM_RxInnetRaw[%d]:addr:0x%x\n",i,p_ALGORITHM_Fun[i]);
	        }
	        else
	        {
	        	MSCP_LOG_MSG("UDP[%d]-ALGORITHM_Fun is NULL\n",i);
	        	s_CFM_RxInnetRaw[i].ALGORITHM_Fun = NULL;/*未注册空指针*/
	        }

	        rtCheck = CM_Thread_Create((CM_THREAD_T*)NULL, (CM_THREAD_FUNC_T)t_UdpRawRecvThread, "InnetR_Rx", 0, CM_TASK_PRIORITY_73, (CM_Thread_Arg_Struct_T*)&s_CFM_RxInnetRaw[i]);
	        CM_ASSERT(CM_TRUE == rtCheck, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_3, TSCP_DARK_ASSERT_16);
	        CM_Sleep(100u);/* 延时等待线程启动 */
		}
    }
}
/**
* @brief UDP透传接收线程
* @param arg 指向STRU_CFM_RECV_CTRL的指针
* @details
* 创建本线程之前应先配置好STRU_CFM_RECV_CTRL，包括创建阻塞通信的socket
* 本线程将以阻塞方式接收UDP报文并写入线程接收队列
*/
static CM_THREAD_FUNC_T t_UdpRawRecvThread(IN CM_Thread_Arg_Struct_T* arg)
{
    /*- 变量初始化 */
    STRU_CFM_RECV_CTRL_T* pCtrl = (STRU_CFM_RECV_CTRL_T*)arg; /* 线程控制信息 */
    ENUM_CM_RETURN rt = ENUM_CM_FALSE; /* 函数返回值 */
    CM_UINT8* rcvBuf = NULL;
    CM_INT32 len; /* 报文长度 */
    CM_UINT32 srcIP;/* 源IP */
    CM_UINT16 srcPort;/* 源端口 */

    CM_UINT32 calccrc = 0u; /* 校验和 */

    CM_UINT8 *info = NULL;/* 雷达特征信息 */
    CM_UINT8 CompareEnable = 0u;/* 平台比较雷达特征信息 */
#if QNX
    void* pmask = NULL;
    /*- 本线程锁定在 A53 core 1 */
	pmask = (void*)(0x01u|0x02u);
	(void)ThreadCtl(_NTO_TCTL_RUNMASK, pmask);

#endif
    MSCP_LOG_MSG("IP:%s:%d UDP Raw recv Start\n", pCtrl->IP, pCtrl->port);
    /*- 循环接收UDP数据 */
    while (1)
    {
        /*- UDP阻塞接收 */
    	rcvBuf = CM_MQ_Get_BufAddr(&pCtrl->MsgQ);
    	if(NULL != rcvBuf)
    	{
    		len = CM_UDP_Recv_Msg(*(pCtrl->pSock), &rcvBuf[6u], (CM_INT32)CM_UNSIGNED_SHORT_EXP(pCtrl->MsgQ.maxMsgSize - 6u), &srcIP, &srcPort);
    		if (len > 0)
    		{
    			/*- 源IP端口是否合法 */
				if ((pCtrl->rmtIP == 0u)
					|| ((srcIP == pCtrl->rmtIP) && (srcPort== pCtrl->rmtPort)))
				{
					/*- @alias 将收到的报文写入线程接收队列 */
					CM_LongToChar(srcIP, rcvBuf);
					CM_ShortToChar(srcPort, &rcvBuf[4u]);
					info = CM_MQ_Get_BufAddr(&pCtrl->InfoQ);
					if((NULL != (RAW_ALGORITHM)(*pCtrl->ALGORITHM_Fun)) && (NULL != info))
					{
						/*解析时间戳等二取数据*/
						rt = (*pCtrl->ALGORITHM_Fun)(&rcvBuf[6u],len,info,&CompareEnable);
	                	if(ENUM_CM_TRUE == rt)
						{
							if(1u == CompareEnable)
							{
								/*写入CRC*/
								calccrc = CM_Crc32(&rcvBuf[6u], (CM_UINT32)len);
								CM_LongToChar(calccrc, &info[8u]);
								(void)CM_Mutex_Lock(pCtrl->mutex);
								rt = CM_MQ_UpData(&pCtrl->InfoQ, (CM_UINT16)(12u));
								if (ENUM_CM_TRUE == rt)
								{
									/*- 保存通信数据 */
									rt = CM_MQ_UpData(&pCtrl->MsgQ,(CM_UINT16)(len + 6));
									if (ENUM_CM_TRUE == rt)
									{
										/*- 无处理*/
									}
									else
									{
										/*- 防御性清空*/
										(void)CFM_DarkLog_Multiple(DARK_LOG_HEX, TSCP_DARK_CFMNET_UDPRAWRECVTHREAD_UPDATAEOR1, 2, \
												sizeof(CM_UINT16),pCtrl->port,
												sizeof(CM_INT32),len);
										MSCP_LOG_MSG("port %d rx overflow(msgLen=%d)\n", pCtrl->port, len);
										(void)CM_MQ_RollbackData(&pCtrl->InfoQ);
									}
								}
								else
								{
									/*- 防御性清空*/
									(void)CFM_DarkLog_Multiple(DARK_LOG_HEX, TSCP_DARK_CFMNET_UDPRAWRECVTHREAD_UPDATAEOR2, 2, \
											sizeof(CM_UINT16),pCtrl->port,
											sizeof(CM_INT32),len);
									MSCP_LOG_MSG("port %d rx overflow(msgLen=%d)\n", pCtrl->port, len);
								}
								(void)CM_Mutex_Unlock(pCtrl->mutex);
							}
							else
							{
								/*不写入CRC*/
								(void)CM_Mutex_Lock(pCtrl->mutex);
								rt = CM_MQ_UpData(&pCtrl->InfoQ, (CM_UINT16)(10u));
								if (ENUM_CM_TRUE == rt)
								{
									rt = CM_MQ_UpData(&pCtrl->MsgQ,(CM_UINT16)(len + 6));
									if (ENUM_CM_TRUE == rt)
									{

									}
									else
									{
										/*- 防御性清空*/
										(void)CFM_DarkLog_Multiple(DARK_LOG_HEX, TSCP_DARK_CFMNET_UDPRAWRECVTHREAD_UPDATAEOR3, 2, \
												sizeof(CM_UINT16),pCtrl->port,
												sizeof(CM_INT32),len);
										MSCP_LOG_MSG("port %d rx overflow(msgLen=%d)\n", pCtrl->port, len);
										(void)CM_MQ_RollbackData(&pCtrl->InfoQ);
									}
								}
								else
								{
									/*- 防御性清空*/
									(void)CFM_DarkLog_Multiple(DARK_LOG_HEX, TSCP_DARK_CFMNET_UDPRAWRECVTHREAD_UPDATAEOR4, 2, \
											sizeof(CM_UINT16),pCtrl->port,
											sizeof(CM_INT32),len);
									MSCP_LOG_MSG("port %d rx overflow(msgLen=%d)\n", pCtrl->port, len);
								}
								(void)CM_Mutex_Unlock(pCtrl->mutex);
							}
						}
						else
						{
							/*解析失败不写入-无操作*/
						}
					}
					else
					{
						/*解析指针为空*/
						/*- 保存通信数据 */
						rt = CM_MQ_UpData(&pCtrl->MsgQ,(CM_UINT16)(len + 6));
						if (ENUM_CM_TRUE == rt)
						{
							/*无操作*/
						}
						else
						{
							/*- 防御性清空*/
							(void)CFM_DarkLog_Multiple(DARK_LOG_HEX, TSCP_DARK_CFMNET_UDPRAWRECVTHREAD_UPDATAEOR5, 2, \
									sizeof(CM_UINT16),pCtrl->port,
									sizeof(CM_INT32),len);
							MSCP_LOG_MSG("port %d rx overflow(msgLen=%d)\n", pCtrl->port, len);
							rt = CM_MQ_Clear(&pCtrl->MsgQ);
							CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_12, TSCP_DARK_ASSERT_9);
						}
					}
				}
				else
				{
					/*- 来自非预期IP端口的数据*/
					MSCP_LOG_MSG("Raw port %d rx err [%s:%d]:%d \n", srcIP, srcPort, len);
					CM_RE_ASSERT(0, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_12, TSCP_DARK_ASSERT_10);
				}
			}
			else
			{
				/*- 接收出错 */
				(void)CFM_DarkLog_Multiple(DARK_LOG_HEX, TSCP_DARK_CFMNET_UDPRAWRECVTHREAD_UPDATAEOR6, 2, \
						sizeof(CM_UINT16),pCtrl->port,
						sizeof(CM_INT32),len);
				MSCP_LOG_MSG("Raw port %d rx err(len=%d)\n", pCtrl->port, len);
				CM_RE_ASSERT(0, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_12, TSCP_DARK_ASSERT_11);
			}
    	}
    	else
    	{
			
			if(NULL != (RAW_ALGORITHM)(*pCtrl->ALGORITHM_Fun))
			{
				MSCP_LOG_MSG("port %d rx overflow(msgLen=%d) MsgQ is full!\n", pCtrl->port, len);
				(void)CM_Mutex_Lock(pCtrl->clear_mutex);
				rt = CM_MQ_Clear(&pCtrl->MsgQ);
				CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_12, TSCP_DARK_ASSERT_12);
				rt = CM_MQ_Clear(&pCtrl->InfoQ);
				(void)CM_Mutex_Unlock(pCtrl->clear_mutex);
				CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_12, TSCP_DARK_ASSERT_13);

			}
			else
			{
				(void)CFM_DarkLog_Multiple(DARK_LOG_HEX, TSCP_DARK_CFMNET_UDPRAWRECVTHREAD_UPDATAEOR7, 2, \
						sizeof(CM_UINT16),pCtrl->port,
						sizeof(CM_INT32),len);
				MSCP_LOG_MSG("port %d rx overflow(msgLen=%d) MsgQ is full!\n", pCtrl->port, len);
				rt = CM_MQ_Clear(&pCtrl->MsgQ);
				CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_12, TSCP_DARK_ASSERT_14);

			}
    	}
    }
    return NULL;
}
/**
* @brief TCP接收线程
* @param arg 指向STRU_CFM_RECV_CTRL的指针
* @details
* 创建本线程之前应先配置好STRU_CFM_RECV_CTRL，包括创建阻塞通信的socket
* 本线程将以非阻塞方式接收TCP报文并写入线程接收队列
*/
static CM_THREAD_FUNC_T t_TcpRecvThread(IN CM_Thread_Arg_Struct_T* arg)
{
    /*- 变量初始化 */
    STRU_CFM_RECV_CTRL_T* pCtrl = (STRU_CFM_RECV_CTRL_T*)arg; /* 线程控制信息 */
    ENUM_CM_RETURN rt = ENUM_CM_FALSE; /* 函数返回值 */
    CM_INT32 len; /* 报文长度 */
	CM_SOCKET tcpsock = -1;			/* 临时变量 */
	CM_UINT16 tcpId = 0u;			/* 临时变量 */
	CM_UINT32 ServeraddrIP = 0u;			/* 临时变量 */
	CM_UINT16 ServerportNumber = 0u;			/* 临时变量 */
	CM_UINT32 TcpState = 0u;			/* 临时变量 */
	CM_UINT16 ConnectFlag = 0u;			/* 临时变量 */
	ENUM_CM_RETURN ret = ENUM_CM_FALSE; /* 临时结果 */
	CM_INT32 FullFrameSize = 0;			/* 临时变量 */
	CM_INT32 Count = 0;			/* 临时变量 */
	struct in_addr serveraddr;
	CM_UINT64 tick = 0u;          /* 精确时间 */
#if QNX
    void* pmask = NULL;
    /*- 本线程锁定在 A53 core 1 */
	pmask = (void*)(0x01u|0x02u);
	(void)ThreadCtl(_NTO_TCTL_RUNMASK, pmask);

#endif
    rt = CM_Memcpy((void*) &serveraddr, sizeof(serveraddr), (void*)(&pCtrl->rmtIP), (CM_SIZE_T)4);
    CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_13, TSCP_DARK_ASSERT_1);
	
	MSCP_LOG_MSG("Client: IP:%s, Port :%d, Server: IP:%s, Port :%d, Tcpid = %u, Tcp recv Start\n", pCtrl->IP, pCtrl->port,inet_ntoa(serveraddr), pCtrl->rmtPort,pCtrl->Tcpid);
	tcpId = pCtrl->Tcpid;
    /*- 循环接收TCP数据 */
    while (1)
    {
    	/*- 每次轮询重置连接成功标志为0 */
    	ConnectFlag = 0u;

		tick = CM_GetTick();
		tick = tick + (CM_UINT64)(100000000u);

		if(ENUM_2x2_MASTER == SFM_2x2_GetLocal2x2State())
		{
			/*- 查询套接字状态 */
			ret = CM_TCP_Msgstate_Query(tcpId, &tcpsock, &TcpState, &ServeraddrIP, &ServerportNumber);
			CM_RE_ASSERT(ENUM_CM_TRUE == ret, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_13, TSCP_DARK_ASSERT_2);

			if (((CM_UINT32)ENUM_CM_CLOSED == (CM_UINT32)TcpState) || ((CM_UINT32)ENUM_CM_CONNFAIL == (CM_UINT32)TcpState) )
			{
				/*- 套接字状态为已断开连接，待创建 */
				/*- 重新创建socket */
				ret = CM_TCP_Socket_Create(&tcpsock,(CM_UINT32)inet_addr(pCtrl->IP), pCtrl->port,tcpId,ServeraddrIP, ServerportNumber);
				if (ENUM_CM_TRUE != ret)
				{
					/*日志记录*/
					(void)CFM_DarkLog_Storage(DARK_LOG_HEX, TSCP_DARK_WARNING, 4U, DARK_FAULT_CODE_MERGE(NET_MODE, DARK_FAULT_CODE_FUN_ORDER_3, TSCP_DARK_ASSERT_1));
					MSCP_LOG_MSG("Create Tcp Socket Fail.\n");
				}
				else
				{
					/*- 建立连接，超时时间为20毫秒 */
					ret = CM_TCP_Socket_Connect(tcpId,(CM_UINT32)20);
					if (ENUM_CM_TRUE != ret)
					{
						/*- 连接失败*/
						/*- 日志记录*/
						(void)CFM_DarkLog_Storage(DARK_LOG_HEX, TSCP_DARK_WARNING, 4U, DARK_FAULT_CODE_MERGE(NET_MODE, DARK_FAULT_CODE_FUN_ORDER_3, TSCP_DARK_ASSERT_2));
						MSCP_LOG_MSG("Connect  Server Fail.\n");
					}
					else
					{
						/*- 连接成功，置连接成功标志为1 */
						ConnectFlag = 1u;
					}
				}
			}
			else if((CM_UINT32)ENUM_CM_NOCONN == (CM_UINT32)TcpState)
			{
				/*- 套接字状态为已创建，未连接 */
				/*- 建立连接，超时时间为20毫秒 */
				ret = CM_TCP_Socket_Connect(tcpId,(CM_UINT32)20);
				if (ENUM_CM_TRUE != ret)
				{
					/*- 连接失败 */
					/*- 日志记录*/
					(void)CFM_DarkLog_Storage(DARK_LOG_HEX, TSCP_DARK_WARNING, 4U, DARK_FAULT_CODE_MERGE(NET_MODE, DARK_FAULT_CODE_FUN_ORDER_3, TSCP_DARK_ASSERT_3));
					MSCP_LOG_MSG("Connect  Server Fail.\n");
				}
				else
				{
					/*- 连接成功，置连接成功标志为1 */
					ConnectFlag = 1u;
				}

			}
			else if((CM_UINT32)ENUM_CM_CONNECTED == (CM_UINT32)TcpState)
			{
				/*- 连接成功，置连接成功标志为1 */
				ConnectFlag = 1u;
			}
			else
			{
				/*- 无处理 */
			}
			/*- 判断连接状态标志为1则接收 */
			if (1u == (CM_UINT16)ConnectFlag)
			{

				/*- TCP非阻塞接收 */
				len = CM_TCP_Recv_Msg((CM_UINT16)tcpId, pCtrl->cache_buf + 6 + (CM_INT32)pCtrl->Offset, (CM_INT32)((CM_INT32)sizeof(pCtrl->cache_buf) - 6 - pCtrl->Offset));
				if (0 < len)
				{
					/*- 将未收到数据计数置为0 */
					Count = 0;

					/*- 拆分完整帧数据 */
					ret = CM_TCP_Find_Full_Frame(pCtrl->cache_buf + 6,len,&FullFrameSize);
					if (ENUM_CM_TRUE == ret)
					{

						/*- 有完整帧数据 */
						/*- @alias 将收到的完整帧写入线程接收队列 */
						CM_LongToChar(ServeraddrIP, pCtrl->cache_buf);
						CM_ShortToChar(ServerportNumber, pCtrl->cache_buf + 4);


						/*- 保存通信数据 */
						rt = CM_MQ_Write(&pCtrl->MsgQ, pCtrl->cache_buf, (CM_UINT16)CM_SIGNED_SHORT_EXP(FullFrameSize + 6));
						if (ENUM_CM_TRUE == rt)
						{

							if (len > FullFrameSize)
							{
								/*- 保存剩余的数据，供下次使用 */
								(void)CM_Memmove((void*)(pCtrl->cache_buf + 6), (CM_SIZE_T)CM_SIGNED_INT_EXP(sizeof(pCtrl->cache_buf) - 6), (void*)(pCtrl->cache_buf + 6 + FullFrameSize), (CM_SIZE_T)CM_SIGNED_INT_EXP(len - FullFrameSize));

								/*- 保存偏移量 */
								pCtrl->Offset = len - FullFrameSize;
							}
							else
							{
								/*- 正好是完整帧，将偏移量置为0 */


								pCtrl->Offset = 0;
							}
						}
						else
						{
							/*- 防御性清空*/

							(void)CM_MQ_Clear(&pCtrl->MsgQ);

							/*- 将偏移量置为0 */
							pCtrl->Offset = 0;
						}
					}
					else
					{
						/*- 没有完整帧数据 */
						/*- 保存偏移量 */
						pCtrl->Offset = len;
					}
				}
				else if(0 == len)
				{

					/*- 本次处理未收到数据 */

					/*- 计数连续3次处理未收到数据，关闭套接字重新创建并连接 */
					Count++;
					if (10 == Count)
					{
						(void)CM_TCP_Socket_Close(tcpId, (CM_UINT32)ENUM_CM_CLOSED);

						/*- 将偏移量置为0 */
						pCtrl->Offset = 0;

						/*- 将未收到数据计数置为0 */
						Count = 0;
					}
					else
					{
						/*- 无处理，等待下次轮询处理 */
					}
				}
				else
				{

					/*- 接收出现异常，将偏移量置为0，接收接口里已经关闭了套接字这里不需要关闭 */
					pCtrl->Offset = 0;
				}
			}
			else
			{
				/*- 无处理，等待下次轮询处理 */
			}
		}
		else
		{
			/*非主系*/
			/*可能降为主，判断连接状态，释放连接*/
			/*- 查询套接字状态 */
			ret = CM_TCP_Msgstate_Query(tcpId, &tcpsock, &TcpState, &ServeraddrIP, &ServerportNumber);
			CM_RE_ASSERT(ENUM_CM_TRUE == ret, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_13, TSCP_DARK_ASSERT_3);

			if ((CM_UINT32)ENUM_CM_CONNECTED == TcpState )
			{
				/*释放连接*/
				(void)CM_TCP_Socket_Close(tcpId, (CM_UINT32)ENUM_CM_CLOSED);

				/*- 将偏移量置为0 */
				pCtrl->Offset = 0;

				/*- 将未收到数据计数置为0 */
				Count = 0;				
			}
			else
			{
				/*无操作*/
			}
		}
		/* 线程轮询处理，每轮100毫秒 */

		(void)DFM_WaitUntill(tick);
    }
    return NULL;
}

/* @brief 内网透传TCP通信数据发送
* @param ch   内网透传通道序号，[1...n]有效
* @param pBuf 发送报文指针
* @param Len 发送报文长度
* @param DstIP 目的IP
* @param DstPort 目的端口
* @return 发送结果
* - ENUM_CM_TRUE 成功
* - ENUM_CM_FALSE 失败
*/
ENUM_CM_RETURN CFM_InnetRaw_Tcp_Send(IN CM_UINT16 Tcpid, IN const CM_UINT8* Buf, IN CM_INT32 Len)
{
	/*- 返回内网透传TCP通信通道的发送结果 */
    return CM_TCP_Send_Msg(Tcpid, Buf, Len);		
}

/*读数据时禁止清空（即使写满）*/
inline void CFM_InnetRawClear_Mutex_Lock(IN CM_INT32 ch)
{
	(void)CM_Mutex_Lock(s_CFM_RxInnetRaw[ch].clear_mutex);
}
inline void CFM_InnetRawClear_Mutex_UnLock(IN CM_INT32 ch)
{
	(void)CM_Mutex_Unlock(s_CFM_RxInnetRaw[ch].clear_mutex);
}
/**
* @brief 获取指定内网透传通道的全部报文特征信息（时间戳和序列号）
* @param ch 通道号
* @param info 特征信息
* @param infoSize 特征信息数组的长度
* @return 特征信息长度
*/
CM_UINT32 CFM_InnetRaw_GetInfo(IN CM_INT32 ch, OUT CM_UINT8 info[], IN CM_UINT32 infoSize,OUT CM_UINT8 *CompareEnable)
{
    /*- 变量初始化 */
    CM_INT32 i = 0;
    CM_INT32 num = 0;
    CM_UINT32 temp_size = 0u;
    CM_UINT16 len = 0u;
    CM_UINT32 offset = 0u;
    num = CM_MQ_Get_Msg_Num(&s_CFM_RxInnetRaw[ch].InfoQ);
    CM_RE_ASSERT((CM_UINT32)(num*12) <= infoSize, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_28, TSCP_DARK_ASSERT_1);
    if(0 < num)
    {
		/*- @alias 获取全部特征信息 */
		for (i = 0; i < num; i++)
		{
			len = 12u;
			(void)CM_MQ_Get(&s_CFM_RxInnetRaw[ch].InfoQ, (CM_UINT16)(i), &info[offset], &len);
			offset += len;
		}
		/*如果长度等于时间戳+CRC 12个字节，需要比较*/
		if(12u == len)
		{
			*CompareEnable = 1u;
		}
		/*如果长度等于时间戳 10个字节，不需要比较*/
		else if(10u == len)
		{
			*CompareEnable = 0u;
		}
		else
		{
			CM_RE_ASSERT(0, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_28, TSCP_DARK_ASSERT_2);
		}
		temp_size = (CM_UINT32)num * len;
		CM_RE_ASSERT(offset == temp_size, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_28, TSCP_DARK_ASSERT_3);
    }
    else
    {
    	*CompareEnable = 1u;
    }
    /*- 返回读取的特征信息长度 */
    return offset;
}

/**
* @brief 获取一帧带时间戳的透传数据
* @param ch 通道号
* @param bufFirst 帧头
* @param bufFirstLen 帧头长度
* @param bufSecond 有效数据
* @param bufSecondLen 有效数据长度
* @return 无
* @details
*/
ENUM_CM_RETURN CFM_InnetRaw_Rx_MsgInfoQueue(IN CM_INT32 ch, OUT CM_UINT8 bufFirst[], IN CM_UINT32 bufFirstLen,
								OUT CM_UINT8 *bufSecond, IN CM_UINT32 *bufSecondLen)
{
	ENUM_CM_RETURN rt = ENUM_CM_FALSE;
	CM_UINT8* read_addr = NULL;
	CM_UINT16 addrBuf_Size = 0u;
	/*- 读取通信报文队列和特征信息队列 */
	read_addr = CM_MQ_Read_Addr(&s_CFM_RxInnetRaw[ch].MsgQ,&addrBuf_Size);
	CM_ASSERT(NULL != read_addr, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_29, TSCP_DARK_ASSERT_1);
	rt = CM_MQ_Read_Clear(&s_CFM_RxInnetRaw[ch].InfoQ);
	CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_29, TSCP_DARK_ASSERT_2);
	CM_RE_ASSERT(addrBuf_Size > (bufFirstLen), NET_MODE, DARK_FAULT_CODE_FUN_ORDER_29, TSCP_DARK_ASSERT_3);
	(void)CM_Memcpy(bufFirst,(CM_SIZE_T)bufFirstLen,read_addr,(CM_SIZE_T)bufFirstLen);
	rt = CM_Memcpy(bufSecond,(CM_SIZE_T)*bufSecondLen,&read_addr[bufFirstLen],(CM_SIZE_T)CM_UNSIGNED_INT_EXP(addrBuf_Size - bufFirstLen));
	if(ENUM_CM_TRUE == rt)
	{
		*bufSecondLen = addrBuf_Size - bufFirstLen;
		rt = CM_MQ_Read_UpData(&s_CFM_RxInnetRaw[ch].MsgQ);
		CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_29, TSCP_DARK_ASSERT_4);
	}
	else
	{
		(void)CFM_DarkLog_Storage(DARK_LOG_HEX, TSCP_DARK_WARNING, 4U, DARK_FAULT_CODE_MERGE(NET_MODE, DARK_FAULT_CODE_FUN_ORDER_4, TSCP_DARK_ASSERT_1));
		MSCP_LOG_MSG("Raw[%d]not enough space:%d<-%d!!!\n", ch,  *bufSecondLen,addrBuf_Size - bufFirstLen);
		*bufSecondLen = 0;
		rt = ENUM_CM_FALSE;
	}
	return rt;
}
/**
* @brief 清除一帧带时间戳的透传数据
* @param ch 通道号
* @return 无
* @details
*/
void CFM_Clear_InnetRaw_Rx_Msg(IN CM_INT32 ch)
{
	ENUM_CM_RETURN rt1 = ENUM_CM_FALSE;
	ENUM_CM_RETURN rt2 = ENUM_CM_FALSE;
	/*- 读取通信报文队列和特征信息队列 */
	rt1 = CM_MQ_Read_Clear(&s_CFM_RxInnetRaw[ch].MsgQ);
	rt2 = CM_MQ_Read_Clear(&s_CFM_RxInnetRaw[ch].InfoQ);

	CM_RE_ASSERT(ENUM_CM_TRUE == rt1, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_30, TSCP_DARK_ASSERT_1);
	CM_RE_ASSERT(ENUM_CM_TRUE == rt2, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_30, TSCP_DARK_ASSERT_2);
}

/*********************************外网通信相关*****************************************/

/**
* @brief 外网通信初始化
*/
static void s_NetInit_Outnet(void)
{
    /*- 变量初始化 */
    ENUM_CM_RETURN rt = ENUM_CM_FALSE; /* 临时变量 */
    CM_INT32 val = 0;    /* 临时变量 */
    CM_BOOL rtCheck;     /* 临时变量 */

    /*- 创建socket */
    rt = CM_UDP_Socket_Create(&s_CFM_Sock.Sock_OutnetSafe, CM_FALSE, (CM_UINT32)inet_addr(g_PFM_Cfg.Local_Cfg.IP_Out), g_PFM_Cfg.Local_Cfg.Port_Outnet_Safe, 0u, (CM_UINT8)0);
    CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_4, TSCP_DARK_ASSERT_1);

    /*- 配置socket */
    val = (CM_INT32)NET_UDP_BUF_SIZE;
    (void)setsockopt(s_CFM_Sock.Sock_OutnetSafe, SOL_SOCKET, SO_RCVBUF, (void*)(&val), (unsigned int)sizeof(val));
    (void)setsockopt(s_CFM_Sock.Sock_OutnetSafe, SOL_SOCKET, SO_SNDBUF, (void*)(&val), (unsigned int)sizeof(val));

    /*- 配置接收线程 */
    CM_ASSERT(s_CFM_RxOutnetSafe.IP != NULL, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_4, TSCP_DARK_ASSERT_2);
    (void)sprintf(s_CFM_RxOutnetSafe.IP, "%s", g_PFM_Cfg.Local_Cfg.IP_Out);
    s_CFM_RxOutnetSafe.port = g_PFM_Cfg.Local_Cfg.Port_Outnet_Safe;
    s_CFM_RxOutnetSafe.pSock = &s_CFM_Sock.Sock_OutnetSafe;
    s_CFM_RxOutnetSafe.rmtIP = 0u;
    s_CFM_RxOutnetSafe.threadNumBer = (CM_UINT8)ENUM_THREAD_OutnetS_Rx;
    rt = CM_MQ_Init(&s_CFM_RxOutnetSafe.MsgQ, (CM_UINT16)CFM_OUTNET_MSG_NUM_MAX, (CM_UINT16)(CFM_OUTNET_SAFE_MSG_SIZE));
    CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_4, TSCP_DARK_ASSERT_3);
    /*- 启动外网安全通信接收线程 */
    rtCheck = CM_Thread_Create((CM_THREAD_T*)NULL, (CM_THREAD_FUNC_T)t_UdpRecvThread, "OutnetS_Rx", 0, CM_TASK_PRIORITY_74, (CM_Thread_Arg_Struct_T*)&s_CFM_RxOutnetSafe);
    CM_ASSERT(CM_TRUE == rtCheck, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_4, TSCP_DARK_ASSERT_4);

	/*- 创建外网心跳socket */
    rt = CM_UDP_Socket_Create(&s_CFM_Sock.Sock_OutnetHeart, CM_FALSE, (CM_UINT32)inet_addr(g_PFM_Cfg.Local_Cfg.IP_Out), g_PFM_Cfg.Local_Cfg.Port_Outnet_Heart, 0u, (CM_UINT8)0);
    CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_4, TSCP_DARK_ASSERT_9);

    /*- 配置接收线程 */
    CM_ASSERT(s_CFM_RxOutnetHeart.IP != NULL, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_4, TSCP_DARK_ASSERT_10);
    (void)sprintf(s_CFM_RxOutnetHeart.IP, "%s", g_PFM_Cfg.Local_Cfg.IP_Out);
    s_CFM_RxOutnetHeart.port = g_PFM_Cfg.Local_Cfg.Port_Outnet_Heart;
    s_CFM_RxOutnetHeart.pSock = &s_CFM_Sock.Sock_OutnetHeart;
    s_CFM_RxOutnetHeart.rmtIP = 0u;
    rt = CM_MQ_Init(&s_CFM_RxOutnetHeart.MsgQ, (CM_UINT16)CFM_OUTHEART_MSG_NUM_MAX, (CM_UINT16)(CFM_OUTNET_HEART_MSG_SIZE));
    CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_4, TSCP_DARK_ASSERT_11);
    /*- 启动外网心跳接收线程 */
    rtCheck = CM_Thread_Create((CM_THREAD_T*)NULL, (CM_THREAD_FUNC_T)t_UdpRecvThread, "OutnetH_Rx", 0, CM_TASK_PRIORITY_82, (CM_Thread_Arg_Struct_T*)&s_CFM_RxOutnetHeart);
    CM_ASSERT(CM_TRUE == rtCheck, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_4, TSCP_DARK_ASSERT_12);

	/*判断外网透传使能开关*/
    if(0x55u == (CM_UINT32)g_PFM_Cfg.M_OutnetRaw_Enable)
    {
		/*- 创建socket */
		rt = CM_UDP_Socket_Create(&s_CFM_Sock.Sock_OutnetRaw, CM_FALSE, (CM_UINT32)inet_addr(g_PFM_Cfg.Local_Cfg.IP_Out), g_PFM_Cfg.Local_Cfg.Port_Outnet_Raw, 0u, (CM_UINT8)0);
		CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_4, TSCP_DARK_ASSERT_5);

	
		/*- 配置socket */
		val = (CM_INT32)NET_UDP_BUF_SIZE;
		(void)setsockopt(s_CFM_Sock.Sock_OutnetRaw, SOL_SOCKET, SO_RCVBUF, (void*)(&val), (unsigned int)sizeof(val));
		(void)setsockopt(s_CFM_Sock.Sock_OutnetRaw, SOL_SOCKET, SO_SNDBUF, (void*)(&val), (unsigned int)sizeof(val));

		/*- 配置接收线程 */
        CM_ASSERT(s_CFM_RxOutnetRaw.IP != NULL,NET_MODE, DARK_FAULT_CODE_FUN_ORDER_4, TSCP_DARK_ASSERT_6);
		(void)sprintf(s_CFM_RxOutnetRaw.IP, "%s", g_PFM_Cfg.Local_Cfg.IP_Out);
		s_CFM_RxOutnetRaw.port = g_PFM_Cfg.Local_Cfg.Port_Outnet_Raw;
		s_CFM_RxOutnetRaw.pSock = &s_CFM_Sock.Sock_OutnetRaw;
		s_CFM_RxOutnetRaw.rmtIP = 0u;
		rt = CM_MQ_Init(&s_CFM_RxOutnetRaw.MsgQ, (CM_UINT16)CFM_OUTNET_RAW_MSG_NUM_MAX, (CM_UINT16)(CFM_OUTNET_RAW_MSG_SIZE));
		CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_4, TSCP_DARK_ASSERT_7);

		rtCheck = CM_Thread_Create((CM_THREAD_T*)NULL, (CM_THREAD_FUNC_T)t_UdpRecvThread, "OutnetR_Rx", 0, CM_TASK_PRIORITY_82, (CM_Thread_Arg_Struct_T*)&s_CFM_RxOutnetRaw);
		CM_ASSERT(CM_TRUE == rtCheck, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_4, TSCP_DARK_ASSERT_8);
		CM_Sleep(100u);/* 延时等待线程启动 */
    }
    else
    {
    	/*外网透传未使能*/
    	(void)CFM_DarkLog_Storage(DARK_LOG_HEX, TSCP_DARK_WARNING, 4U, DARK_FAULT_CODE_MERGE(NET_MODE, DARK_FAULT_CODE_FUN_ORDER_5, TSCP_DARK_ASSERT_1));
    }

    rtCheck = CM_Thread_Create((CM_THREAD_T*) NULL, (CM_THREAD_FUNC_T) t_ClearArpThread,"Clear_Arp", 0, CM_TASK_PRIORITY_94, NULL);
   	CM_RE_ASSERT(CM_TRUE == rtCheck, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_4, TSCP_DARK_ASSERT_13);

	CM_Sleep(100u);/* 延时等待线程启动 */
}

/**
* @brief 获取接收包数和接受长度并且清空
*/
void CFM_GetOSCache(void)
{
	MSCP_LOG_MSG("g_CFM_OSCache_ClearNum = %d, g_CFM_OSCache_Len = %d\n", g_CFM_OSCache_ClearNum, g_CFM_OSCache_Len);
	g_CFM_OSCache_ClearNum = 0;
	g_CFM_OSCache_Len = 0;
}

/**
* @brief 清空外网安全数据队列长度
*/
void CFM_ClearCache(void)
{
	(void)CM_MQ_Clear(&s_CFM_RxOutnetSafe.MsgQ);
}
/*********************************维护网相关*****************************************/

/**
* @brief 维护网通信队列初始化
*/
void CFM_Maintain_Queue_Init(void)
{
	/*- 变量初始化 */
	ENUM_CM_RETURN rt = ENUM_CM_FALSE; /* 临时变量 */
	/*- 平台日志队列初始化 */
	rt = CM_MQ_Init((CM_MQ_Struct_T*)&s_CFM_Send_LogStr.MsgQ, (CM_UINT16)CFM_INNET_LOG_MSG_SIZE, (CM_UINT16)(CFM_INNET_LOG_SIZE));
	CM_NM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_5, TSCP_DARK_ASSERT_1);

	rt = CM_QueueInitial(&s_Log_CtrlQ.MsgQ, CFM_INNET_LOG_MSG_SIZE_DARK);
	CM_NM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_5, TSCP_DARK_ASSERT_2);
	(void)CM_Mutex_Init(&ciphertextCtrl.mutex);
}
/**
* @brief 维护网通信UDP初始化
*/
void CFM_Maintain_Init(void)
{
	ENUM_CM_RETURN rt = ENUM_CM_FALSE; /* 临时变量 */
    /*- UDP协议初始化 */
    rt = CM_UDP_Init();
    CM_NM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_6, TSCP_DARK_ASSERT_1);

    /*- 维护网通信初始化 */
    s_NetInit_Maintain(); /* 首先初始化维护网通信，以使以太网日志可用 */

    CM_Sleep(1000u);
    PFM_SendLastAssertLog();

    DFM_Network_Check();
}


/* 维护网通信初始化 */
static void s_NetInit_Maintain(void)
{
    /*- 变量初始化 */
    ENUM_CM_RETURN rt = ENUM_CM_FALSE; /* 临时变量 */
    CM_INT32 val = 0;    /* 临时变量 */
    /*- 创建socket */
    rt = CM_UDP_Socket_Create(&s_CFM_Sock.Sock_LogBase, CM_FALSE, (CM_UINT32)inet_addr(g_PFM_Cfg.Local_Cfg.IP_Maintain), g_PFM_Cfg.Local_Cfg.Port_Log_Base, 0u, (CM_UINT8)0);
    CM_NM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_8, TSCP_DARK_ASSERT_1);
    s_CFM_Send_LogStr.pSock = &s_CFM_Sock.Sock_LogBase;

    rt = CM_UDP_Socket_Create(&s_CFM_Sock.Sock_LogCiphertext, CM_FALSE, (CM_UINT32)inet_addr(g_PFM_Cfg.Local_Cfg.IP_Maintain), g_PFM_Cfg.Local_Cfg.Port_Log_Ciphertext, 0u, (CM_UINT8)0);
    CM_NM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_8, TSCP_DARK_ASSERT_2);
	s_Log_CtrlQ.pSock = &s_CFM_Sock.Sock_LogCiphertext;

    /*- 配置socket */
    val = (CM_INT32)NET_UDP_BUF_SIZE * 32;
    (void)setsockopt(s_CFM_Sock.Sock_LogBase, SOL_SOCKET, SO_SNDBUF, (void*)(&val), (unsigned int)sizeof(val));
    (void)setsockopt(s_CFM_Sock.Sock_LogCiphertext, SOL_SOCKET, SO_SNDBUF, (void*)(&val), (unsigned int)sizeof(val));

    /*初始化参数*/
    CM_NM_ASSERT(s_CFM_Send_LogStr.rmtIP != NULL, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_8, TSCP_DARK_ASSERT_3);
    CM_NM_ASSERT(g_PFM_Cfg.Logger_IP != NULL, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_8, TSCP_DARK_ASSERT_4);
	(void)sprintf(s_CFM_Send_LogStr.rmtIP, "%s", g_PFM_Cfg.Logger_IP);
	s_CFM_Send_LogStr.rmtPort = g_PFM_Cfg.Local_Cfg.Port_Log_Base;

	CM_NM_ASSERT(s_Log_CtrlQ.rmtIP != NULL, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_8, TSCP_DARK_ASSERT_5);
    (void)sprintf(s_Log_CtrlQ.rmtIP, "%s", g_PFM_Cfg.Logger_IP);
    s_Log_CtrlQ.rmtPort = g_PFM_Cfg.Local_Cfg.Port_Log_Ciphertext;

    /*创建发送线程*/
    /*- 启动明文日志发送线程 */
    (void)CM_Thread_Create((CM_THREAD_T*)NULL, (CM_THREAD_FUNC_T)t_LogSendThread, "LogSend", 0, CM_TASK_PRIORITY_90, (CM_Thread_Arg_Struct_T*)&s_CFM_Send_LogStr);
	CM_Sleep(100u);/* 延时等待线程启动 */
}


/**
* @brief 日志发送线程
* @param arg 指向STRU_CFM_TIME_CTRL的指针
* @return 线程函数返回值（实际永远不会返回）
* @details
*/
static CM_THREAD_FUNC_T t_LogSendThread(IN CM_Thread_Arg_Struct_T* arg)
{
    /*- 变量初始化 */
	STRU_CFM_SEND_LOG* pCtrl = (STRU_CFM_SEND_LOG*)arg;  /* 线程参数 */
	ENUM_CM_RETURN rt1 = ENUM_CM_FALSE; /* 平台临时变量 */
    CM_UINT8 buf[CFM_INNET_LOG_SIZE * 2u] = { 0u };  /* 接收缓冲区 */
    CM_UINT16 len = 0u;            /* 数据长度 */
    CM_UINT16 offset = 0u;
    CM_UINT16 bufSize = 0u;
#if QNX
    void* pmask = NULL;
    /*- 本线程锁定在 A53 core 1 */
    pmask = (void*)(0x01u|0x02u);
    (void)ThreadCtl(_NTO_TCTL_RUNMASK, pmask);
#endif
    MSCP_LOG_MSG("IP:%s:%d LogSend Service Start\n", pCtrl->rmtIP, (CM_INT32)pCtrl->rmtPort);
    /*- 循环执行接收线程 */
    while (1)
    {
    	/*- 获取消息条数*/
    	bufSize = CFM_INNET_LOG_SIZE * 2u;
    	offset = 0u;
    	len = bufSize;

    	do
    	{
    		rt1 = CM_MQ_Read(&pCtrl->MsgQ, &buf[offset], &len);
    		if((ENUM_CM_TRUE == rt1) && (len > 0u))
    		{
    			if(0x55u == PFM_LOG_GET_STOP_FLAG())
    			{
    				/*- 判断宕机前是否有未发送的攒包数据*/
    				if(offset > 0u)
    				{
    					/*- 有攒包数据 先把这部分数据发送出去*/
    					(void)CM_UDP_Send_Msg((CM_SOCKET)*pCtrl->pSock, buf, (CM_INT32)offset, (CM_UINT32)inet_addr(pCtrl->rmtIP), pCtrl->rmtPort);
    					CM_Sleep(1u);//发送完延时1ms
    				}
    				else
    				{
    					;
    				}
    				/*- 发送本次读到的数据*/
    				(void)CM_UDP_Send_Msg((CM_SOCKET)*pCtrl->pSock, &buf[offset], (CM_INT32)len, (CM_UINT32)inet_addr(pCtrl->rmtIP), pCtrl->rmtPort);
    				(void)CM_Memset(buf, 0u, (CM_SIZE_T)(offset + len) ,sizeof(buf));
    		    	bufSize = CFM_INNET_LOG_SIZE * 2u;
    		    	offset = 0u;
    			}
    			else if(buf[offset + 1u] == (CM_UINT8)'b')
    			{
    				/*- 是数字 直接发送*/
    				(void)CM_UDP_Send_Msg((CM_SOCKET)*pCtrl->pSock, buf, (CM_INT32)offset, (CM_UINT32)inet_addr(pCtrl->rmtIP), pCtrl->rmtPort);
    				CM_Sleep(1u);
    				(void)CM_UDP_Send_Msg((CM_SOCKET)*pCtrl->pSock, &buf[offset], (CM_INT32)len, (CM_UINT32)inet_addr(pCtrl->rmtIP), pCtrl->rmtPort);
    				(void)CM_Memset(buf, 0u, (CM_SIZE_T)(offset + len) ,sizeof(buf));
    		    	CM_Sleep(1u);
    		    	bufSize = CFM_INNET_LOG_SIZE * 2u;
    		    	offset = 0u;
    			}
    			else
    			{
        			offset += len;
        			bufSize -= len;
    			}
    			len = bufSize;
    		}
    		else
    		{
				CM_delayUs((CM_UINT64)5000u);
    		}
    	}while(offset < LOG_MAX);
		/*- UDP数据发送*/
		(void)CM_UDP_Send_Msg((CM_SOCKET)*pCtrl->pSock, buf, (CM_INT32)offset, (CM_UINT32)inet_addr(pCtrl->rmtIP), pCtrl->rmtPort);
		(void)CM_Memset(buf, 0u, (CM_SIZE_T)offset, sizeof(buf));
		CM_Sleep(1u);
    }
    return NULL;
}

/**
* @brief 暗文日志组包发送函数
* @param 无
* @return 无
* @details
*/
void CFM_LogCiphertextSend(void)
{
    /*- 变量初始化 */
	ENUM_CM_RETURN rt = ENUM_CM_FALSE; 								/* 临时变量 */
    CM_UINT8 sendBuf[CFM_INNET_LOG_MSG_SIZE_DARK + 20u] = { 0u };   			/* 发送队列冲区 */
    CM_UINT32 sendOffset = 11u; 						     			/* 发送队列偏移量,包头占11字节 */
    CM_UINT32 dataLen = 0u;         									/* 信息包队列大小 */
    CM_UINT8 appType = 0u;											/* 应用类型 */
    CM_UINT32 crc = 0u;
    CM_UINT8 typeBoard = 1u;                                       /* id = 1代表主机板 */

	(void)CM_Mutex_Lock(ciphertextCtrl.mutex);
	dataLen = CM_QueueStatus(&s_Log_CtrlQ.MsgQ);
	/*- 应用内网发送缓冲是否非空 */
	if (dataLen > 0u)
	{
		/*- 从发送缓冲区读出数据 */
		rt = CM_QueueRead(dataLen, &sendBuf[sendOffset], &s_Log_CtrlQ.MsgQ);
		(void)CM_Mutex_Unlock(ciphertextCtrl.mutex);
		if(ENUM_CM_TRUE == rt)
		{
			/*- sendOffset偏移量增加 */
			sendOffset += dataLen;
			/*- 组包头 包尾 长度不包含自身4字节 */
			CM_LongToChar(sendOffset, &sendBuf[0]);
			/*- 源类型 */
			sendBuf[4] = typeBoard;
			if(0 == strcmp(g_PFM_Cfg.APP_NAME, "ZC"))
			{
				appType = 1u;
			}
			else if(0 == strcmp(g_PFM_Cfg.APP_NAME, "RCOCI"))
			{
				appType = 2u;
			}
			else if(0 == strcmp(g_PFM_Cfg.APP_NAME, "CI"))
			{
				appType = 3u;
			}
			else if(0 == strcmp(g_PFM_Cfg.APP_NAME, "TMC"))
			{
				appType = 4u;
			}
			else if(0 == strcmp(g_PFM_Cfg.APP_NAME, "ITE"))
			{
				appType = 5u;
			}
			else if(0 == strcmp(g_PFM_Cfg.APP_NAME, "TSL"))
			{
				appType = 6u;
			}
			else if(0 == strcmp(g_PFM_Cfg.APP_NAME, "DSU"))
			{
				appType = 7u;
			}
			else if(0 == strcmp(g_PFM_Cfg.APP_NAME, "YJP"))
			{
				appType = 8u;
			}
			else
			{
				appType = 0u;
			}
			sendBuf[5] = appType; /*应用类型id=1 ZC*/
			sendBuf[6] = g_PFM_Cfg.CPU_ID;
			/*- 序列号,主机板那周期号代替 */
			CM_LongToChar(SFM_2x2_GetSysCount(), &sendBuf[7]);
			/*- crc */
			crc = CM_Crc32(&sendBuf[0], sendOffset);
			CM_LongToChar(crc, &sendBuf[sendOffset]);

			/*- 发送一整包,后面可能都是0,由上位机解析 */
			(void)CM_UDP_Send_Msg((CM_SOCKET)*s_Log_CtrlQ.pSock, (CM_UINT8*)sendBuf, (CM_INT32)CM_UNSIGNED_INT_EXP(sendOffset+4u), (CM_UINT32)inet_addr(s_Log_CtrlQ.rmtIP), s_Log_CtrlQ.rmtPort);
		}
		else
		{
			MSCP_LOG_MSG("Ciphertext read queue fail \n");
		}

	}
	else
	{
		(void)CM_Mutex_Unlock(ciphertextCtrl.mutex);
		MSCP_LOG_MSG("dataLen = %d\n",dataLen);
	}
}

/**
* @brief 平台明文日志发送
* @param pBuf 发送报文指针
* @param Len 发送报文长度
* @return 发送结果
* - ENUM_CM_TRUE 成功
* - ENUM_CM_FALSE 失败
*/
ENUM_CM_RETURN CFM_BaseLog_Send(IN const CM_UINT8* Buf, IN CM_INT32 Len)
{
    /*- 返回日志通道的发送结果 */
	return CM_MQ_Write(&s_CFM_Send_LogStr.MsgQ, Buf, (CM_UINT16)Len);
}

/**
* @brief 应用日志发送
* @param pBuf 发送报文指针
* @param Len 发送报文长度
* @return 发送结果
* - ENUM_CM_TRUE 成功
* - ENUM_CM_FALSE 失败
*/
ENUM_CM_RETURN CFM_AppLog_Send(IN const CM_UINT8* Buf, IN CM_INT32 Len)
{
    /*- 返回日志通道的发送结果 */
	return CM_MQ_Write(&s_CFM_Send_LogStr.MsgQ, Buf, (CM_UINT16)Len);
}
/**
* @brief 平台日志保存本地文件
* @param FILE * fp_crash 文件指针 取值范围：非空
* @return 无
*/
void CFM_BaseLog_SaveLocal(FILE * fp_crash)
{
	/*- 变量初始化 */
	CM_UINT16 i = 1u;
	CM_UINT16 Len = 0;
	CM_UINT8 Buf[CFM_INNET_LOG_MSG_SIZE] = {0u};
	ENUM_CM_RETURN rtnval = ENUM_CM_FALSE;
	/*- 如果参数非空 */
	if(NULL != fp_crash)
	{
		/*- 锁定消息队列 */
		(void)CM_Mutex_Lock(s_CFM_Send_LogStr.MsgQ.mutex);
		/*- @alias 读取消息队列写入本地文件中 */
		for(i = 1u;i <= CFM_INNET_LOG_SIZE;i++)
		{
			Len = CFM_INNET_LOG_MSG_SIZE;
			rtnval = CM_MQ_Again_Read(&s_CFM_Send_LogStr.MsgQ, i,Buf, &Len);
			if((ENUM_CM_TRUE == rtnval) && (Len > 0u) && (Buf[1] == (CM_UINT8)'s'))
			{
				(void)fwrite(Buf,(CM_SIZE_T)1u,Len,fp_crash);
			}
		}
	    /*- 释放消息队列 */
	    (void)CM_Mutex_Unlock(s_CFM_Send_LogStr.MsgQ.mutex);
	}
	else
	{
		/*- 输出失败提示信息 */
    	(void)CFM_DarkLog_Storage(DARK_LOG_HEX, TSCP_DARK_WARNING, 4U, DARK_FAULT_CODE_MERGE(NET_MODE, DARK_FAULT_CODE_FUN_ORDER_6, TSCP_DARK_ASSERT_1));
		(void)printf("Unable to output log\n");
	}
}
/**
* @brief 应用/平台暗文日志存储
* @param infoType 数据类型
* 取值范围：0x55：info为字符串数据方式
* 		   0xAA：info为十六进制数据方式
* 		   0xFF：info为十进制数据方式
* @param code 信息编码/信息类型   取值范围：0~0xffff
* @param infoLen 数据长度  取值范围：0~0xffff
* @param info 数据/信息 取值范围：任意类型指针
* @return 发送结果
* - ENUM_CM_TRUE 成功
* - ENUM_CM_FALSE 失败
*/
ENUM_CM_RETURN CFM_DarkLog_Storage(IN const CM_UINT8 infoType, IN const CM_UINT16 code, IN const CM_UINT32 infoLen, IN const void *info)
{
	/*- 变量初始化 */
	CM_UINT8 TempBuf[CFM_INNET_LOG_MSG_SIZE_DARK] = { 0u };
	CM_UINT32 TempBufLen = infoLen + 7u;
	ENUM_CM_RETURN ret = ENUM_CM_FALSE;
	/*- 如果数据为空或者数据长度+包头大小大于队列大小,则返回失败*/
	if((NULL == info) || (CFM_INNET_LOG_MSG_SIZE_DARK < (infoLen + 7u)) || (ENUM_INIT_MAIN_QUEUE_NET > PFM_LOG_GET_INIT_STAGE()))
	{
		MSCP_LOG_MSG("If the data is empty or the data length + header size is greater than the queue size, failure is returned\n");
		ret = ENUM_CM_FALSE;
	}
	else
	{
		/*- 组包*/
		TempBuf[0] =  infoType;
		CM_ShortToChar(code, &TempBuf[1]);
		CM_LongToChar(infoLen, &TempBuf[3]);
		if((4u == infoLen) && (DARK_LOG_STRING != (CM_UINT8)infoType))
		{
			CM_LongToChar(*(const CM_UINT32*)info,&TempBuf[7]);
			ret = ENUM_CM_TRUE;
		}
		else if((2u == infoLen) && (DARK_LOG_STRING != (CM_UINT8)infoType))
		{
			CM_ShortToChar(*(const CM_UINT16*)info,&TempBuf[7]);
			ret = ENUM_CM_TRUE;
		}
		else if((8u == infoLen) && (DARK_LOG_STRING != (CM_UINT8)infoType))
		{
			CM_64ToChar(*(const CM_UINT32*)info,&TempBuf[7]);
			ret = ENUM_CM_TRUE;
		}
		else
		{
			ret = CM_Memcpy(&TempBuf[7], (CM_SIZE_T)CM_UNSIGNED_INT_EXP(CFM_INNET_LOG_MSG_SIZE_DARK-7u), info, (CM_SIZE_T)infoLen);
			if(ENUM_CM_FALSE == ret)
			{
				MSCP_LOG_MSG("Memcpy Dark Write failed\n");
			}
			else
			{
				/*-无处理  */
			}
		}
		/*- 如果组包没问题*/
		if(ENUM_CM_TRUE == ret)
		{
			/*- 直接将组好的信息包写到队列中*/
			/*- 在这加锁*/
			ret = CM_Mutex_Lock(ciphertextCtrl.mutex);
			if(ENUM_CM_FALSE == ret)
			{
				MSCP_LOG_MSG("Dark Mutex Lock failed\n");
			}
			else
			{
				ret= CM_QueueWrite(TempBufLen, TempBuf, &s_Log_CtrlQ.MsgQ);/*长度*/
				if(ENUM_CM_FALSE == ret)
				{
					MSCP_LOG_MSG("Dark Write faild(Maybe the queue is full)\n");
				}
				else
				{
					/*- 无处理 */
				}
			}
			(void)CM_Mutex_Unlock(ciphertextCtrl.mutex);
		}
		else
		{
			MSCP_LOG_MSG("There is a packet grouping problem\n");
			/*- 无处理 */
		}
	}
	/*- 返回结果 */
	return ret;
}
/**
* @brief 应用/平台暗文日志多变量存储
* @param infoType 数据类型
* 取值范围：0x55：info为字符串数据方式
* 		   0xAA：info为十六进制数据方式
* 		   0xFF：info为十进制数据方式
* @param code 信息编码/信息类型   取值范围：0~0xffff
* @param infoCut 数据个数  取值范围：0~0xff
* @param ... 可变参数/信息 取值范围：任意类型数据，但是需要与sizeof()成对使用。
* @return 发送结果
* - ENUM_CM_TRUE 成功
* - ENUM_CM_FALSE 失败
*/
ENUM_CM_RETURN CFM_DarkLog_Multiple(IN const CM_UINT8 infoType, IN const CM_UINT16 code, CM_UINT8 infoCut, ...)
{
	va_list argList;
	ENUM_CM_RETURN ret = ENUM_CM_FALSE;
	CM_UINT8 i = 0u;
	CM_UINT8 dataLen = 0u;
	CM_UINT8 dataBuf[1024] = {0};
	CM_UINT16 totalLen = 0u;
	/*判断是否为且大于0*/
	if(infoCut > 0u)
	{
		/*定位参数链表栈顶位置*/
		va_start(argList, (infoCut));
		/* @alias 循环读取数据*/
		for(i = 0u; i<infoCut; i++)
		{
			dataLen = (CM_UINT8)va_arg(argList,CM_UINT32);
			switch(dataLen)
			{
				case 1:
					dataBuf[totalLen++] = (CM_UINT8)va_arg(argList,CM_UINT32);
					break;
				case 2:
					CM_ShortToChar((CM_UINT16)va_arg(argList,CM_UINT32),&dataBuf[totalLen]);
					totalLen += 2u;
					break;
				case 4:
					CM_LongToChar(va_arg(argList,CM_UINT32),&dataBuf[totalLen]);
					totalLen += 4u;
					break;
				case 8:
					CM_64ToChar(va_arg(argList,CM_UINT64),&dataBuf[totalLen]);
					totalLen += 8u;
					break;
				default:
					dataLen = (CM_UINT8)va_arg(argList,CM_UINT32);
					MSCP_LOG_MSG("CFM_DarkLog_Multiple len_err\n");
					break;
			}
		}
		va_end(argList);
		/*- 写入暗文日志队列*/
		ret = CFM_DarkLog_Storage(infoType,code,totalLen,dataBuf);
	}
	else
	{
		;
	}
	return ret;
}
/* 远程部署通信初始化 */
static void s_NetInit_RemoteUpdate(void)
{
    /*- 变量初始化 */
    ENUM_CM_RETURN rt = ENUM_CM_FALSE; /* 临时变量 */
    CM_INT32 val = 0;    /* 临时变量 */
    CM_BOOL rtCheck;     /* 临时变量 */
	CM_INT32 i = 0;      /* 循环变量 */

	if ((0x55u == g_PFM_Cfg.M_RemoteUpdate_Enable) &&(0x00u != g_Maintenance_Id))
	{
		/* 维护模式下用到的cfg全局变量数据拷贝，防护内存自检宕机引起的维护模式下使用cfg全局变量异常 */
		g_RMUP_Cfg.CPU_ID=g_PFM_Cfg.CPU_ID;
		g_RMUP_Cfg.BOARD_ID = g_PFM_Cfg.BOARD_ID;
		g_RMUP_Cfg.INNET_ID_RM = g_PFM_Cfg.INNET_ID_RM;
		g_RMUP_Cfg.OUTNET_ID = g_PFM_Cfg.OUTNET_ID;
		g_RMUP_Cfg.M_2oo2_Enable = g_PFM_Cfg.M_2oo2_Enable;
		g_RMUP_Cfg.M_RemoteUpdate_Enable = g_PFM_Cfg.M_RemoteUpdate_Enable;
		g_RMUP_Cfg.reboot_replycount = g_PFM_Cfg.reboot_replycount;
		g_RMUP_Cfg.INNET_COM_NUM = g_PFM_Cfg.INNET_COM_NUM;
		g_RMUP_Cfg.CYC_TIME = g_PFM_Cfg.CYC_TIME;
		(void)CM_Memcpy(g_RMUP_Cfg.CFG_MD5, sizeof(g_RMUP_Cfg.CFG_MD5), g_PFM_Cfg.CFG_MD5, sizeof(g_PFM_Cfg.CFG_MD5));
		(void)CM_Memcpy(g_RMUP_Cfg.APP_NAME, sizeof(g_RMUP_Cfg.APP_NAME), g_PFM_Cfg.APP_NAME, sizeof(g_PFM_Cfg.APP_NAME));
		(void)CM_Memcpy(g_RMUP_Cfg.APP_MD5, sizeof(g_RMUP_Cfg.APP_MD5), g_PFM_Cfg.APP_MD5, sizeof(g_PFM_Cfg.APP_MD5));
		(void)CM_Memcpy(g_RMUP_Cfg.Start_Path, sizeof(g_RMUP_Cfg.Start_Path), g_PFM_Cfg.Start_Path, sizeof(g_PFM_Cfg.Start_Path));
	    for (i = 1; i <= (CM_INT32)g_RMUP_Cfg.INNET_COM_NUM; i++)
	    {
	        g_RMUP_Cfg.INNET_COM_CFG[i].InnetID = g_PFM_Cfg.INNET_COM_CFG[i].InnetID;
			g_RMUP_Cfg.INNET_COM_CFG[i].IP_G = g_PFM_Cfg.INNET_COM_CFG[i].IP_G;
			g_RMUP_Cfg.INNET_COM_CFG[i].Port_Raw_G = g_PFM_Cfg.INNET_COM_CFG[i].Port_Raw_G;
			g_RMUP_Cfg.INNET_COM_CFG[i].Port_Safe_G = g_PFM_Cfg.INNET_COM_CFG[i].Port_Safe_G;
			g_RMUP_Cfg.INNET_COM_CFG[i].IP_P = g_PFM_Cfg.INNET_COM_CFG[i].IP_P;
			g_RMUP_Cfg.INNET_COM_CFG[i].Port_Raw_P = g_PFM_Cfg.INNET_COM_CFG[i].Port_Raw_P;
			g_RMUP_Cfg.INNET_COM_CFG[i].Port_Safe_P = g_PFM_Cfg.INNET_COM_CFG[i].Port_Safe_P;
	    }
		
	    /*- 创建socket */
	    rt = CM_UDP_Socket_Create(&s_CFM_Sock.Sock_Remote_Update, CM_FALSE, (CM_UINT32)inet_addr(g_PFM_Cfg.Local_Cfg.IP_Maintain), g_PFM_Cfg.Local_Cfg.Port_Remote_Update, 0u, (CM_UINT8)0);
	    CM_NM_ASSERT(ENUM_CM_TRUE == rt,NET_MODE, DARK_FAULT_CODE_FUN_ORDER_9, TSCP_DARK_ASSERT_1);

	    /*- 配置socket */
	    val = (CM_INT32)NET_UDP_BUF_SIZE;
	    (void)setsockopt(s_CFM_Sock.Sock_Remote_Update, SOL_SOCKET, SO_RCVBUF, (void*)(&val), (unsigned int)sizeof(val));
	    (void)setsockopt(s_CFM_Sock.Sock_Remote_Update, SOL_SOCKET, SO_SNDBUF, (void*)(&val), (unsigned int)sizeof(val));

	    /*- 配置和启动内网安全通信接收线程 */
	    CM_NM_ASSERT(s_CFM_RxRemoteUpdate.IP != NULL,NET_MODE, DARK_FAULT_CODE_FUN_ORDER_9, TSCP_DARK_ASSERT_2);
	    (void)sprintf(s_CFM_RxRemoteUpdate.IP, "%s", g_PFM_Cfg.Local_Cfg.IP_Maintain);
	    s_CFM_RxRemoteUpdate.port = g_PFM_Cfg.Local_Cfg.Port_Remote_Update;
	    s_CFM_RxRemoteUpdate.pSock = &s_CFM_Sock.Sock_Remote_Update;
	    s_CFM_RxRemoteUpdate.rmtIP = 0u;
	    rt = CM_MQ_Init(&s_CFM_RxRemoteUpdate.MsgQ, (CM_UINT16)CFM_INNET_SAFE_MSG_NUM_MAX, (CM_UINT16)(CFM_INNET_SAFE_MSG_SIZE));
	    CM_NM_ASSERT(ENUM_CM_TRUE == rt,NET_MODE, DARK_FAULT_CODE_FUN_ORDER_9, TSCP_DARK_ASSERT_3);

	    /*- 启动远程部署通信接收线程 */
	    rtCheck = CM_Thread_Create((CM_THREAD_T*)NULL, (CM_THREAD_FUNC_T)t_RemoteUpdateThread, "RemoteUpdate_Rx", 0, CM_TASK_PRIORITY_82, (CM_Thread_Arg_Struct_T*)&s_CFM_RxRemoteUpdate);
	    CM_NM_ASSERT(CM_TRUE == rtCheck,NET_MODE, DARK_FAULT_CODE_FUN_ORDER_9, TSCP_DARK_ASSERT_4);
	    CM_Sleep(100u);/* 延时等待线程启动 */		
	}
	else
	{
		(void)CFM_DarkLog_Storage(DARK_LOG_HEX, TSCP_DARK_WARNING, 4U, DARK_FAULT_CODE_MERGE(NET_MODE, DARK_FAULT_CODE_FUN_ORDER_7, TSCP_DARK_ASSERT_1));
		MSCP_LOG_MSG("App not set g_Maintenance_Id,Remote Update Function Off!!!\n");
	}
}

/*********************************线程通用模块*****************************************/

/**
* @brief 2取、远程部署通信初始化
*/
void CFM_UpdateAnd2oo2_Net_Init(void)
{
    /*- 远程部署通信初始化 */
    s_NetInit_RemoteUpdate();

    /*- 2oo2功能是否开启 */
    if (0x55u == g_PFM_Cfg.M_2oo2_Enable)
    {
        /*- 2oo2通信初始化 */
        s_NetInit_2oo2();
    }
    else
	{
		/*- 无处理 */
	}
}
/**
* @brief 网络通信模块初始化
*/
void CFM_Net_Init(void)
{
	ENUM_CM_RETURN rt = ENUM_CM_FALSE; /* 函数返回值 */

    /*- TCP协议初始化 */
    rt = CM_TCP_Init();
    CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_10, TSCP_DARK_ASSERT_1);

    /*- 2x2功能是否开启 */
	if (0x55u == g_PFM_Cfg.M_2x2_Enable)
	{
		/*- 2x2相关网络通信初始化 */
		s_NetInit_2x2();
	}
	else
	{
		/*- 无处理 */
   	}
    /* 内网通信初始化 */
    s_NetInit_Innet();
    /* 外网通信初始化 */
    s_NetInit_Outnet();
}
/**
* @brief 配置网卡ip
*/
void CFM_NetworkCard_Init(void)
{
	/*- 变量初始化 */
	CM_CHAR str[1024] = {0};
	/*- 配置2取网卡ip */
	(void)memset(str, 0, sizeof(str));
	(void)sprintf(str, "ifconfig %s %s", "fec0", g_PFM_Cfg.Local_Cfg.IP_2oo2);
	(void)printf("%s\n",str);
	(void)system(str);

	/*- 配置通用网卡ip */
	(void)memset(str, 0, sizeof(str));
	(void)sprintf(str, "ifconfig %s %s", "fec1", g_PFM_Cfg.Local_Cfg.IP_Com);
	(void)printf("%s\n",str);
	(void)system(str);

	/*- 配置维护网卡ip */
	(void)memset(str, 0, sizeof(str));
	(void)sprintf(str, "ifconfig %s %s", "wm0", g_PFM_Cfg.Local_Cfg.IP_Maintain);
	(void)printf("%s\n",str);
	(void)system(str);
}
/**
* @brief UDP接收线程
* @param arg 指向STRU_CFM_RECV_CTRL的指针
* @details
* 创建本线程之前应先配置好STRU_CFM_RECV_CTRL，包括创建阻塞通信的socket
* 本线程将以阻塞方式接收UDP报文并写入线程接收队列
*/
static CM_THREAD_FUNC_T t_UdpRecvThread(IN CM_Thread_Arg_Struct_T* arg)
{
    /*- 变量初始化 */
    STRU_CFM_RECV_CTRL_T* pCtrl = (STRU_CFM_RECV_CTRL_T*)arg; /* 线程控制信息 */
    ENUM_CM_RETURN rt = ENUM_CM_FALSE; /* 函数返回值 */
    CM_UINT8* rcvBuf = NULL;
    CM_INT32 len; /* 报文长度 */
    CM_UINT32 srcIP;/* 源IP */
    CM_UINT16 srcPort;/* 源端口 */
    CM_SOCKADDR_T addr;/* 地址转换*/
#if QNX
    void* pmask = NULL;
    /*- 本线程锁定在 A53 core 1 */
    if(ENUM_THREAD_2oo2_AppRecv == pCtrl->threadNumBer)
    {
    	pmask = (void*)(0x20u | 0x10u | 0x08u | 0x04u);
    }
    else
    {
    	pmask = (void*)(0x01u|0x02u);
    }
    (void)ThreadCtl(_NTO_TCTL_RUNMASK, pmask);
#endif
    MSCP_LOG_MSG("IP:%s:%d UDP recv Start\n", pCtrl->IP, pCtrl->port);
    /*- 循环接收UDP数据 */
    while (1)
    {
    	/*- UDP阻塞接收 */
		rcvBuf = CM_MQ_Get_BufAddr(&pCtrl->MsgQ);
		if(NULL != rcvBuf)
		{
			len = CM_UDP_Recv_Msg(*(pCtrl->pSock), &rcvBuf[6u], (CM_INT32)CM_UNSIGNED_SHORT_EXP(pCtrl->MsgQ.maxMsgSize - 6u), &srcIP, &srcPort);
			/*- 是否收到有效数据 */
			if (len > 0)
			{
				/*- 源IP端口是否合法 */
				if ((pCtrl->rmtIP == 0u)
					|| ((srcIP == pCtrl->rmtIP) && (srcPort== pCtrl->rmtPort)))
				{
					/*- @alias 将收到的报文写入线程接收队列 */
					if((CM_UINT8)ENUM_THREAD_2x2_StateRecv == pCtrl->threadNumBer)
					{
						/*接收数据时间戳ms数记录*/
						CM_LongToChar((CM_UINT32)(CM_GetTick()/CM_UNSIGNED_MILLION), rcvBuf);
					}
					else
					{
						CM_LongToChar(srcIP, rcvBuf);
						CM_ShortToChar(srcPort, &rcvBuf[4u]);
					}
					/*- 保存通信数据 */
					rt = CM_MQ_UpData(&pCtrl->MsgQ,(CM_UINT16)CM_SIGNED_INT_EXP(len + 6));
					/*- 数据保存是否成功 */
					if (ENUM_CM_TRUE == rt)
					{
						/*成功无操作*/
					}
					else
					{
						/*- 防御性清空*/
						MSCP_LOG_MSG("port %d rx overflow(msgLen=%d),threadNumBer = %d\n", pCtrl->port, len, pCtrl->threadNumBer);
						rt = CM_MQ_Clear(&pCtrl->MsgQ);
						CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_11, TSCP_DARK_ASSERT_1);
					}
					(ENUM_THREAD_OutnetS_Rx == (ENUM_THREAD_NUM_T)pCtrl->threadNumBer)?(g_CFM_OSCache_ClearNum++):g_CFM_OSCache_ClearNum;
					(ENUM_THREAD_OutnetS_Rx == (ENUM_THREAD_NUM_T)pCtrl->threadNumBer)?(g_CFM_OSCache_Len += (CM_UINT32)len):g_CFM_OSCache_Len;
				}
				else
				{
					/*- 来自非预期IP端口的数据*/
					addr.sin_addr.s_addr = srcIP;
					MSCP_LOG_MSG("rx err want port:%d src [%s:%d]:%d \n", pCtrl->rmtPort, inet_ntoa(addr.sin_addr), srcPort, len);
					CM_RE_ASSERT(0, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_11, TSCP_DARK_ASSERT_2);
				}
			}
			else
			{
				/*- 接收出错 */
				MSCP_LOG_MSG("warning ASSERT1103: port %d rx err(len=%d)\n", pCtrl->port, len);
				(void)CFM_DarkLog_Storage(DARK_LOG_HEX, TSCP_DARK_WARNING, 4U, DARK_FAULT_CODE_MERGE(NET_MODE, DARK_FAULT_CODE_FUN_ORDER_8, TSCP_DARK_ASSERT_1));
			}
		}
		else
		{
			/*获取队列指针失败，清空队列*/
			rt = CM_MQ_Clear(&pCtrl->MsgQ);
			MSCP_LOG_MSG("buf clear\n");
			CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_11, TSCP_DARK_ASSERT_4);
		}
    }
    return NULL;
}
/**
* @brief 维护模式下UDP接收线程
* @param arg 指向STRU_CFM_RECV_CTRL的指针
* @details
* 创建本线程之前应先配置好STRU_CFM_RECV_CTRL，包括创建阻塞通信的socket
* 本线程将以阻塞方式接收UDP报文并写入线程接收队列
*/
static CM_THREAD_FUNC_T t_UdpRecvMaintenanceThread(IN CM_Thread_Arg_Struct_T* arg)
{
    /*- 变量初始化 */
    STRU_CFM_RECV_CTRL_T* pCtrl = (STRU_CFM_RECV_CTRL_T*)arg; /* 线程控制信息 */
    ENUM_CM_RETURN rt = ENUM_CM_FALSE; /* 函数返回值 */
    CM_UINT8* rcvBuf = NULL;
    CM_INT32 len; /* 报文长度 */
    CM_UINT32 srcIP;/* 源IP */
    CM_UINT16 srcPort;/* 源端口 */
    CM_SOCKADDR_T srcaddr;/* 地址转换*/
#if QNX
    void* pmask = NULL;
    /*- 本线程锁定在 A53 core 1 */
    pmask = (void*)(0x01u|0x02u);
    (void)ThreadCtl(_NTO_TCTL_RUNMASK, pmask);
#endif
    MSCP_LOG_MSG("IP:%s:%d dpRecvMaintenance recv Start\n", pCtrl->IP, pCtrl->port);
    /*- 循环接收UDP数据 */
    while (1)
    {
    	/*- UDP阻塞接收 */
		rcvBuf = CM_MQ_Get_BufAddr(&pCtrl->MsgQ);
		if(NULL != rcvBuf)
		{
			len = CM_UDP_Recv_Msg(*(pCtrl->pSock), &rcvBuf[6u], (CM_INT32)CM_UNSIGNED_SHORT_EXP(pCtrl->MsgQ.maxMsgSize - 6u), &srcIP, &srcPort);
			/*- 是否收到有效数据 */
			if (len > 0)
			{
				/*- 源IP端口是否合法 */
				if ((pCtrl->rmtIP == 0u)
					|| ((srcIP == pCtrl->rmtIP) && (srcPort== pCtrl->rmtPort)))
				{
					/*- @alias 将收到的报文写入线程接收队列 */
					CM_LongToChar(srcIP, rcvBuf);
					CM_ShortToChar(srcPort, &rcvBuf[4u]);
					/*- 保存通信数据 */
					rt = CM_MQ_UpData(&pCtrl->MsgQ,(CM_UINT16)CM_SIGNED_INT_EXP(len + 6));
					/*- 数据保存是否成功 */
					if (ENUM_CM_TRUE == rt)
					{
						/*成功无操作*/
					}
					else
					{
						/*- 防御性清空*/
						/* MSCP_LOG_MSG("port %d rx overflow(msgLen=%d)\n", pCtrl->port, len);*/
						rt = CM_MQ_Clear(&pCtrl->MsgQ);
						CM_NM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_38, TSCP_DARK_ASSERT_1);

					}
				}
				else
				{
					/*- 来自非预期IP端口的数据*/
					srcaddr.sin_addr.s_addr = srcIP;
					MSCP_LOG_MSG("rx err want port:%d src [%s:%d]:%d \n", pCtrl->rmtPort, inet_ntoa(srcaddr.sin_addr), srcPort, len);
					CM_NM_ASSERT(0, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_38, TSCP_DARK_ASSERT_2);
				}
			}
			else
			{
				/*- 接收出错 */
				MSCP_LOG_MSG("port %d rx err(len=%d)\n", pCtrl->port, len);
				CM_NM_ASSERT(0, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_38, TSCP_DARK_ASSERT_3);
			}
		}
		else
		{
			/*获取队列指针失败，清空队列*/
			rt = CM_MQ_Clear(&pCtrl->MsgQ);
			CM_NM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_38, TSCP_DARK_ASSERT_4);
		}
    }
    return NULL;
}
/**
* @brief 时钟同步线程
* @param arg 指向STRU_CFM_TIME_CTRL的指针
* @return 线程函数返回值（实际永远不会返回）
* @details
* 创建本线程之前应先配置好STRU_CFM_TIME_CTRL，包括创建阻塞通信的socket
* 本线程将以阻塞方式接收时钟同步报文并作出应答
* 收到请求报文时立即给出应答
* 收到应答报文时记录并计算延迟时间、偏移时间
* @see :: CFM_2oo2_TimeReq
* @see :: CFM_2oo2_TimeGet
*/
static CM_THREAD_FUNC_T t_TimeThread(IN CM_Thread_Arg_Struct_T* arg)
{
    /*- 变量初始化 */
    STRU_CFM_TIME_CTRL_T* pCtrl = (STRU_CFM_TIME_CTRL_T*)arg;  /* 线程参数 */
    CM_UINT8 buf[100] = { 0u };  /* 接收缓冲区 */
    CM_INT32 len;            /* 数据长度 */
    CM_UINT32 srcIP;         /* 源IP */
    CM_UINT16 srcPort;       /* 源端口 */
    CM_UINT64 tick = 0u;     /* 精确时间 */
    CM_UINT64 T1 = 0u;  /* 时钟同步参数 */
    CM_UINT64 T2 = 0u;  /* 时钟同步参数 */
    CM_UINT64 T3 = 0u;  /* 时钟同步参数 */
    CM_UINT64 T4 = 0u;  /* 时钟同步参数 */
    ENUM_CM_RETURN rt = ENUM_CM_FALSE;
#if QNX
    void* pmask = NULL;
    /*- 本线程锁定在 A53 core 1 */
    pmask = (void*)(0x01u|0x02u);
    (void)ThreadCtl(_NTO_TCTL_RUNMASK, pmask);
#endif
    MSCP_LOG_MSG("IP:%s:%d Time Service Start\n", pCtrl->IP, (CM_INT32)pCtrl->port);
    /*- 循环执行接收线程 */
    while (1)
    {
        /*- 阻塞接收时钟同步报文 */
        len = CM_UDP_Recv_Msg(*(pCtrl->pSock), buf, (CM_INT32)sizeof(buf), &srcIP, &srcPort);
        tick = DFM_GetCycTick();
        /*- 是否收到有效报文 */
        if (len > 0)
        {
            /*- 报文类型 */
            switch ((ENUM_TIME_MSG_T)buf[0])
            {
            case ENUM_TIME_REQ: /*-< 时钟同步请求 */
                /*- 长度是否合法 */
                if (9 == len)
                {
                    /*- 解析请求报文 */
                    T1 = CM_64FromChar(buf + 1);
                    /*- 生成应答报文 */
                    T2 = tick;
                    buf[0] = (CM_UINT8)ENUM_TIME_ACK;
                    CM_64ToChar(T1, buf + 1);
                    CM_64ToChar(T2, buf + 9);
                    T3 = DFM_GetCycTick();
                    CM_64ToChar(T3, buf + 17);
                    /*- 发送应答报文 */
                    (void)CM_UDP_Send_Msg(*(pCtrl->pSock), buf, (CM_INT32)25, srcIP, srcPort);
                }
                else
				{
					/*- 无处理 */
				}
                /*- 返回 */
                break;
            case ENUM_TIME_ACK:/*-< 时钟同步应答 */
                /*- 长度是否合法 */
                if (25 == len)
                {
                    /*- 解析应答报文 */
                    T1 = CM_64FromChar(buf + 1);
                    T2 = CM_64FromChar(buf + 9);
                    T3 = CM_64FromChar(buf + 17);
                    T4 = tick;
                    /*- 记录延迟时间和偏移时间 */
                    rt = CM_Mutex_Lock(pCtrl->mutex);
                    CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_14, TSCP_DARK_ASSERT_1);
                    pCtrl->isOK = ENUM_CM_TRUE;
                    pCtrl->delay = (CM_INT64)((T4 - T1) - (T3 - T2)) / 2;
                    pCtrl->offset = (CM_INT64)((T2 + T3) - (T4 + T1)) / 2;
                    rt = CM_Mutex_Unlock(pCtrl->mutex);
                    CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_14, TSCP_DARK_ASSERT_2);

                }
                else
				{
					/*- 无处理 */
				}
                /*- 返回 */
                break;
            case ENUM_TIME_ERROR:/*-< 保留字 */
                /*- 宕机 */
            	CM_RE_ASSERT(0, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_14, TSCP_DARK_ASSERT_3);
                /*- 返回 */
                break;
            default:
                /*- 返回 */
                break;
            }
        }
        else
        {
            /*- 不处理 */
        }
    }
    return NULL;
}

/**
* @brief 远程部署接收线程
* @param arg 指向STRU_CFM_RECV_CTRL的指针
* @details
* 创建本线程之前应先配置好STRU_CFM_RECV_CTRL，包括创建阻塞通信的socket
* 本线程将以阻塞方式接收远程部署命令UDP报文，然后进行相关处理
*/
static CM_THREAD_FUNC_T t_RemoteUpdateThread(IN CM_Thread_Arg_Struct_T* arg)
{
    /*- 变量初始化 */
    STRU_CFM_RECV_CTRL_T* pCtrl = (STRU_CFM_RECV_CTRL_T*)arg; /* 线程控制信息 */
	STRU_PFM_INNET_CFG_T *pCom = NULL;
    ENUM_CM_RETURN rt = ENUM_CM_FALSE; /* 函数返回值 */
    CM_UINT8 rcvBuf[1024] = { 0u };  /* 接收缓冲区 */
    CM_INT32 len; /* 报文长度 */
    CM_UINT32 srcIP;/* 源IP */
    CM_UINT16 srcPort;/* 源端口 */
	CM_UINT32 rmtIP;/* 对方IP */
    CM_UINT16 rmtPort_safe;/* 对方sfp端口 */
	CM_UINT16 rmtPort_raw;/* 对方透传端口 */
	struct in_addr serveraddr;/* 源ip */
	CM_UINT8 Result = 0x0u;/* 请求处理结果 */
#if QNX
    void* pmask = NULL;
    /*- 本线程锁定在 A53 core 1 */
    pmask = (void*)(0x01u|0x02u);
    (void)ThreadCtl(_NTO_TCTL_RUNMASK, pmask);
#endif
    MSCP_LOG_MSG("IP:%s:%d UDP recv Start\n", pCtrl->IP, pCtrl->port);
	/*- 获取目的IP端口 */
	pCom = PFM_INI_InnetID2Addr(g_Maintenance_Id);
	if (NULL != pCom)
	{
		/*- 本机是否为CPU1 */
		if (1u == g_PFM_Cfg.CPU_ID)
		{	
			rmtIP = pCom->IP_G;
			rmtPort_safe = pCom->Port_Safe_G;
			rmtPort_raw = pCom->Port_Raw_G;
		}
		else
		{
			rmtIP = pCom->IP_P;
			rmtPort_safe = pCom->Port_Safe_P;
			rmtPort_raw = pCom->Port_Raw_P;
		}		
	}
	else
	{
		(void)CFM_DarkLog_Storage(DARK_LOG_HEX, TSCP_DARK_WARNING, 4U, DARK_FAULT_CODE_MERGE(NET_MODE, DARK_FAULT_CODE_FUN_ORDER_9, TSCP_DARK_ASSERT_1));
		MSCP_LOG_MSG("Map Value From g_Maintenance_Id Error!!!\n");
	}

    /*- 循环接收UDP数据 */
    while (1)
    {
    	/* 请求处理结果重新置0 */
    	Result = 0x0u;
    	/*- UDP阻塞接收 */
		len = CM_UDP_Recv_Msg(*(pCtrl->pSock), &rcvBuf[6u], (CM_INT32)sizeof(rcvBuf)-6, &srcIP, &srcPort);
		/*- 是否收到有效数据 */
		if (len > 0)
		{
			MSCP_LOG_DATALEN(rcvBuf, len, "t_RemoteUpdateThread rcvBuflen");
			/*- 源IP端口是否合法 */
			if ((srcIP == rmtIP) && ((srcPort== rmtPort_safe) || (srcPort == rmtPort_raw)))
			{
				if (srcPort== rmtPort_safe)
				{
					/*- @alias 需要解sfp协议的远程部署命令 */
					/*- @alias 将收到的完整帧写入线程接收队列 */
					CM_LongToChar(srcIP, &rcvBuf[0]);
					CM_ShortToChar(srcPort, &rcvBuf[4]);
					/*- 保存通信数据 */
					rt = CM_MQ_Write(&pCtrl->MsgQ, rcvBuf, (CM_UINT16)CM_SIGNED_SHORT_EXP(len + 6));
					if (ENUM_CM_TRUE == rt)
					{
						MSCP_LOG_MSG("CM_MQ_Write success!!! len = %d\n",len);
						/*成功无操作*/
					}
					else
					{
						/*- 防御性清空*/
						(void)CM_MQ_Clear(&pCtrl->MsgQ);
						(void)CFM_DarkLog_Storage(DARK_LOG_HEX, TSCP_DARK_WARNING, 4U, DARK_FAULT_CODE_MERGE(NET_MODE, DARK_FAULT_CODE_FUN_ORDER_10, TSCP_DARK_ASSERT_1));
						MSCP_LOG_MSG("CM_MQ_Write error!!! \n");
					}
				}
				else
				{
					/*- @alias 不需要解sfp协议的远程部署透传命令 */
					/*- @alias 判断帧类型 */
					if (0xa3u == rcvBuf[8u])
					{
						/*- 文件更新请求 */
						MSCP_LOG_MSG("recv 0xa3 pack g_RemoteUpdate_State = %d\n",g_RemoteUpdate_State);
						rt = PFM_FileUpdate_Request(&rcvBuf[6u],(CM_UINT16)len,&Result);
						if (ENUM_CM_TRUE != rt)
						{
							(void)CFM_DarkLog_Storage(DARK_LOG_HEX, TSCP_DARK_WARNING, 4U, DARK_FAULT_CODE_MERGE(NET_MODE, DARK_FAULT_CODE_FUN_ORDER_10, TSCP_DARK_ASSERT_2));
							/*- 文件更新请求处理失败*/
							MSCP_LOG_MSG("Call PFM_FileUpdate_Request error!!! \n");
							/*- 置远程部署过程状态为0x00默认值，维护终端重新触发*/
							g_RemoteUpdate_State = 0x00u;
						}
						else
						{
							/*- 文件更新请求处理成功*/
							MSCP_LOG_MSG("Call PFM_FileUpdate_Request sucess!!! \n");
							if (0x01u == Result)
							{
								/*- 置远程部署过程状态为0x01已处理文件更新请求*/
								g_RemoteUpdate_State = 0x01u;
								MSCP_LOG_MSG("recv 0xa3 pack success\n");
							}
							else
							{
								(void)CFM_DarkLog_Storage(DARK_LOG_HEX, TSCP_DARK_WARNING, 4U, DARK_FAULT_CODE_MERGE(NET_MODE, DARK_FAULT_CODE_FUN_ORDER_12, TSCP_DARK_ASSERT_2));
								MSCP_LOG_MSG("An error occurred in the file update request message!!! \n");
							}
						}
					}
					else if(0xa4u == rcvBuf[8u])
					{
						if (0x01u == g_RemoteUpdate_State)
						{
							/*- 当前远程部署过程为上传完成验证请求*/
							/*- 文件上传完成验证请求 */
							rt = PFM_FileVerity_Request(&rcvBuf[6u],(CM_UINT16)len);
							if (ENUM_CM_TRUE != rt)
							{
								(void)CFM_DarkLog_Storage(DARK_LOG_HEX, TSCP_DARK_WARNING, 4U, DARK_FAULT_CODE_MERGE(NET_MODE, DARK_FAULT_CODE_FUN_ORDER_10, TSCP_DARK_ASSERT_3));
								/*- 文件上传完成验证请求处理失败*/
								MSCP_LOG_MSG("Call PFM_FileVerity_Request error!!! \n");
								/*- 置远程部署过程状态为0x00默认值，维护终端重新触发*/
								g_RemoteUpdate_State = 0x00u;
							}
							else
							{
								/*- 置远程部署过程状态为0x02为成功，等待维护终端升级部署*/
								g_RemoteUpdate_State = 0x02u;
								/*- 文件上传完成验证请求处理成功*/
								MSCP_LOG_MSG("Call PFM_FileVerity_Request sucess!!! \n");
							}
						}
						else
						{
							/*- 不是当前应该收到的过程报文丢弃不处理*/
							MSCP_LOG_MSG("0xa4u The packet should not be received in the current state!!! \n");
							(void)CFM_DarkLog_Storage(DARK_LOG_HEX, TSCP_DARK_WARNING, 4U, DARK_FAULT_CODE_MERGE(NET_MODE, DARK_FAULT_CODE_FUN_ORDER_10, TSCP_DARK_ASSERT_4));
						}
					}
					else
					{
						/*- 来自非预期帧类型的数据*/
						(void)CM_Memcpy((void*) &serveraddr, sizeof(serveraddr), (void*) &srcIP, (CM_SIZE_T)4);
						MSCP_LOG_MSG("frame type err [%s:%d]:%d:%x \n", inet_ntoa(serveraddr), srcPort, len, rcvBuf[8u]);
						(void)CFM_DarkLog_Storage(DARK_LOG_HEX, TSCP_DARK_WARNING, 4U, DARK_FAULT_CODE_MERGE(NET_MODE, DARK_FAULT_CODE_FUN_ORDER_10, TSCP_DARK_ASSERT_5));
					}
				}				
			}
			else
			{
				/*- 来自非预期IP端口的数据*/
				(void)CM_Memcpy((void*) &serveraddr, sizeof(serveraddr), (void*) &srcIP, (CM_SIZE_T)4);
				MSCP_LOG_MSG("rx err [%s:%d]:%d \n", inet_ntoa(serveraddr), srcPort, len);
				(void)CFM_DarkLog_Storage(DARK_LOG_HEX, TSCP_DARK_WARNING, 4U, DARK_FAULT_CODE_MERGE(NET_MODE, DARK_FAULT_CODE_FUN_ORDER_10, TSCP_DARK_ASSERT_6));
			}
		}
		else
		{
			/*- 接收出错 */
			MSCP_LOG_MSG("port %d rx err(len=%d)\n", pCtrl->port, len);
			(void)CFM_DarkLog_Multiple(DARK_LOG_HEX, TSCP_DARK_CFMNET_REMOTEUPDATETHREAD_LENEOR, 2, \
					sizeof(CM_UINT16),pCtrl->port,
					sizeof(CM_INT32),len);
		}
    }

    return NULL;
}
/**
* @brief 清空接收缓冲区
*/
void CFM_Net2XFlush(void)
{
    ENUM_CM_RETURN rt = ENUM_CM_FALSE;
	if (0x55u == g_PFM_Cfg.M_2x2_Enable)
	{
		/*- 2x2接收缓冲区清空 */
		rt = CM_MQ_Flush(&s_CFM_Rx2x2.MsgQ);
		CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_27, TSCP_DARK_ASSERT_1);
	}
	else
	{
		/*- 无处理 */
	}
}
/**
* @brief 清空接收缓冲区
*/
void CFM_Net2X_State_Flush(void)
{
    ENUM_CM_RETURN rt = ENUM_CM_FALSE;
	if (0x55u == g_PFM_Cfg.M_2x2_Enable)
	{
	    rt = CM_MQ_Flush(&s_CFM_State2x2.MsgQ);
	    CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_27, TSCP_DARK_ASSERT_11);
	    rt = CM_Com_OtherDataClear();
	    CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_27, TSCP_DARK_ASSERT_9);
	}
	else
	{
		/*- 无处理 */
	}
}
/**
* @brief 清空接收缓冲区
*/
void CFM_NetFlush(void)
{
    /*- 变量初始化 */
    CM_INT32 i = 0;
    ENUM_CM_RETURN rt = ENUM_CM_FALSE;
	/*- 2x2功能是否开启 */
    CFM_Net2XFlush();
    CFM_Net2X_State_Flush();

    /*- 内网安全接收缓冲区清空 */
    rt = CM_MQ_Flush(&s_CFM_RxInnetSafe.MsgQ);
    CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_27, TSCP_DARK_ASSERT_2);

    /*- 外网安全接收缓冲区清空 */
    rt = CM_MQ_Flush(&s_CFM_RxOutnetSafe.MsgQ);
    CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_27, TSCP_DARK_ASSERT_3);

    /*判断外网透传使能开关*/
    if(0x55u == (CM_UINT32)g_PFM_Cfg.M_OutnetRaw_Enable)
    {
		/* 外网透传缓冲区清空 */
		rt = CM_MQ_Flush(&s_CFM_RxOutnetRaw.MsgQ);
		CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_27, TSCP_DARK_ASSERT_7);
    }
    else
    {
    	/*无处理 */
    }
    if((0x55u == g_PFM_Cfg.M_RemoteUpdate_Enable) &&(0x00u != g_Maintenance_Id))
    {
		/*- 内网远程部署接收缓冲区清空 */
		rt = CM_MQ_Flush(&s_CFM_RxRemoteUpdate.MsgQ);
		CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_27, TSCP_DARK_ASSERT_8);
    }
    else
    {
		/*无处理 */
    }

    rt = CM_MQ_Flush(&s_CFM_RxOutnetHeart.MsgQ);
    CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_27, TSCP_DARK_ASSERT_10);

	/*- @alias 内网透传缓冲区清空 */
    for (i = 1; i <= (s_CFM_Sock.num_InnetRaw + s_CFM_Sock.num_InnetRaw_Extend); i++)
    {
		if (RAW_COM_DISENABLE != g_PFM_Cfg.Local_Cfg.Innet_Raw_Parameter[i].Port_Type_Enable)
		{
	    	if((0x55u == (CM_UINT16)g_PFM_Cfg.Local_Cfg.Innet_Raw_Parameter[i].INNET_2oo2_RAW) && (0x55u == (CM_UINT16)g_PFM_Cfg.Local_Cfg.Innet_Raw_Parameter[i].TIME_STAMP_ENABLE))
	    	{
	    		(void)CM_Mutex_Lock(s_CFM_RxInnetRaw[i].mutex);
	    		rt = CM_MQ_Flush(&s_CFM_RxInnetRaw[i].MsgQ);
	    		CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_27, TSCP_DARK_ASSERT_4);
				rt = CM_MQ_Flush(&s_CFM_RxInnetRaw[i].InfoQ);
				CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_27, TSCP_DARK_ASSERT_5);
				(void)CM_Mutex_Unlock(s_CFM_RxInnetRaw[i].mutex);
	    	}
	    	else
	    	{
	    		rt = CM_MQ_Flush(&s_CFM_RxInnetRaw[i].MsgQ);
	    		CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_27, TSCP_DARK_ASSERT_6);
	    	}			
		}
		else
		{
			
		}
    }
}
/**
* @brief 内网安全通信数据接收
* @param pBuf 接收报文指针
* @param BufSize 接收报文缓冲区大小
* @param pSrcIP 源IP
* @param pSrcPort 源端口
* @return 接收报文长度
* - 正整数 接收报文长度
* - 0      接收失败
*/
CM_INT32 CFM_InnetSafe_Recv(OUT CM_UINT8* pBuf, IN CM_UINT32 BufSize, OUT CM_UINT32* pSrcIP, OUT CM_UINT16* pSrcPort)
{
    /*- 变量初始化 */
    CM_UINT16 len = (BufSize > 65535u) ? (CM_UINT16)(65535u) : (CM_UINT16)(BufSize);
    ENUM_CM_RETURN rt = ENUM_CM_FALSE;

    /*- 从接收线程获取输入报文 */
    rt = CM_MQ_Read(&s_CFM_RxInnetSafe.MsgQ, s_CFM_UDP_Cache, &len);
    /*- 是否收到有效报文 */
    if ((ENUM_CM_TRUE == rt) && (len > 6u))
    {
        /*- 保存源IP、端口和收到的报文 */
        *pSrcIP = CM_LongFromChar(s_CFM_UDP_Cache);   /* parasoft-suppress BD-PB-CHECKRET "后续在查询对应内网ID时进行非法值防护" */
        *pSrcPort = CM_ShortFromChar(s_CFM_UDP_Cache + 4);  /* parasoft-suppress BD-PB-CHECKRET "后续在查询对应内网ID时进行非法值防护" */
        len -= 6u;
        rt = CM_Memcpy((void*)pBuf, (CM_SIZE_T)BufSize, (void*)(s_CFM_UDP_Cache + 6), (CM_SIZE_T)len);
        CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_21, TSCP_DARK_ASSERT_1);
    }
    else
    {
        /*- 接收长度为0 */
        len = 0u;
    }
    /*- 返回接收长度 */
    return (CM_INT32)len;
}
/**
* @brief 内网安全通信数据接收
* @param pBuf 接收报文指针
* @param BufSize 接收报文缓冲区大小
* @param pSrcIP 源IP
* @param pSrcPort 源端口
* @return 接收报文长度
* - 正整数 接收报文长度
* - 0      接收失败
*/
CM_INT32 CFM_InnetSafeRm_Recv(OUT CM_UINT8* pBuf, IN CM_UINT32 BufSize, OUT CM_UINT32* pSrcIP, OUT CM_UINT16* pSrcPort)
{
    /*- 变量初始化 */
    CM_UINT16 len = (BufSize > 65535u) ? (CM_UINT16)(65535u) : (CM_UINT16)(BufSize);
    ENUM_CM_RETURN rt = ENUM_CM_FALSE;
    CM_ASSERT(pBuf != NULL, NET_MODE,DARK_FAULT_CODE_FUN_ORDER_35, TSCP_DARK_ASSERT_2);
    /*- 从接收线程获取输入报文 */
    rt = CM_MQ_Read(&s_CFM_RxRemoteUpdate.MsgQ, s_CFM_UDP_Cache, &len);
    /*- 是否收到有效报文 */
    if ((ENUM_CM_TRUE == rt) && (len > 6u))
    {
        /*- 保存源IP、端口和收到的报文 */
        *pSrcIP = CM_LongFromChar(s_CFM_UDP_Cache);   /* parasoft-suppress BD-PB-CHECKRET "后续在查询对应内网ID时进行非法值防护" */
        *pSrcPort = CM_ShortFromChar(s_CFM_UDP_Cache + 4);  /* parasoft-suppress BD-PB-CHECKRET "后续在查询对应内网ID时进行非法值防护" */
        len -= 6u;
        rt = CM_Memcpy((void*)pBuf, (CM_SIZE_T)BufSize, (void*)(s_CFM_UDP_Cache + 6), (CM_SIZE_T)len);
        CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_35, TSCP_DARK_ASSERT_1);
    }
    else
    {
        /*- 接收长度为0 */
        len = 0u;
    }
    /*- 返回接收长度 */
    return (CM_INT32)len;
}

/**
* @brief 内网安全远程部署通信数据接收
* @param pBuf 接收报文指针
* @param BufSize 接收报文缓冲区大小
* @param pSrcIP 源IP
* @param pSrcPort 源端口
* @return 接收报文长度
* - 正整数 接收报文长度
* - 0      接收失败
*/
CM_INT32 CFM_InnetRemoteUpdate_Recv(OUT CM_UINT8* pBuf, IN CM_UINT32 BufSize, OUT CM_UINT32* pSrcIP, OUT CM_UINT16* pSrcPort)
{
    /*- 变量初始化 */
    CM_UINT16 len = (BufSize > 65535u) ? (CM_UINT16)(65535u) : (CM_UINT16)(BufSize);
    ENUM_CM_RETURN rt = ENUM_CM_FALSE;

    CM_ASSERT_MAINTAIN(pBuf != NULL);
	/*- 从接收线程获取输入报文 */
	rt = CM_MQ_Read(&s_CFM_RxRemoteUpdate.MsgQ, s_CFM_UDP_Cache, &len);
	/*- 是否收到有效报文 */
	if ((ENUM_CM_TRUE == rt) && (len > 6u))
	{
		/*- 保存源IP、端口和收到的报文 */
		*pSrcIP = CM_LongFromChar(s_CFM_UDP_Cache);   /* parasoft-suppress BD-PB-CHECKRET "后续在查询对应内网ID时进行非法值防护" */
		*pSrcPort = CM_ShortFromChar(s_CFM_UDP_Cache + 4);  /* parasoft-suppress BD-PB-CHECKRET "后续在查询对应内网ID时进行非法值防护" */
		len -= 6u;
		rt = CM_Memcpy((void*)pBuf, (CM_SIZE_T)BufSize, (void*)(s_CFM_UDP_Cache + 6), (CM_SIZE_T)len);
		if (ENUM_CM_TRUE != rt)
		{
			len = 0u;
			MSCP_LOG_MSG("CFM_InnetRemoteUpdate_Recv  CM_Memcpy error!!! \n");
			(void)CFM_DarkLog_Storage(DARK_LOG_HEX, TSCP_DARK_WARNING, 4U, DARK_FAULT_CODE_MERGE(NET_MODE, DARK_FAULT_CODE_FUN_ORDER_13, TSCP_DARK_ASSERT_1));
		}
		else
		{
			/*成功无操作*/
		}
	}
	else
	{
		/*- 接收长度为0 */
		len = 0u;
	}
    /*- 返回接收长度 */
    return (CM_INT32)len;
}

/**
* @brief 内网安全通信数据发送
* @param pBuf 发送报文指针
* @param Len 发送报文长度
* @param DstIP 目的IP
* @param DstPort 目的端口
* @return 发送结果
* - ENUM_CM_TRUE 成功
* - ENUM_CM_FALSE 失败
*/
ENUM_CM_RETURN CFM_InnetSafe_Send(IN const CM_UINT8* Buf, IN CM_INT32 Len, IN CM_UINT32 DstIP, IN CM_UINT16 DstPort)
{
    /*- 返回内网安全通信通道的发送结果 */
    return CM_UDP_Send_Msg(s_CFM_Sock.Sock_InnetSafe, Buf, Len, DstIP, DstPort);
}

/**
* @brief 内网远程部署安全通信数据发送
* @param pBuf 发送报文指针
* @param Len 发送报文长度
* @param DstIP 目的IP
* @param DstPort 目的端口
* @return 发送结果
* - ENUM_CM_TRUE 成功
* - ENUM_CM_FALSE 失败
*/
ENUM_CM_RETURN CFM_InnetRemoteUpdate_Send(IN const CM_UINT8* Buf, IN CM_INT32 Len, IN CM_UINT32 DstIP, IN CM_UINT16 DstPort)
{
    /*- 返回内网安全通信通道的发送结果 */
    return CM_UDP_Send_Msg(s_CFM_Sock.Sock_Remote_Update, Buf, Len, DstIP, DstPort);
}

/**
* @brief 内网透传通信数据接收
* @param ch   内网透传通道序号，[1...n]有效
* @param pBuf 接收报文指针
* @param BufLen 接收报文缓冲区大小
* @param pSrcIP 源IP
* @param pSrcPort 源端口
* @return 接收报文长度
* - 正整数 接收报文长度
* - 0      接收失败
*/
CM_UINT16 CFM_InnetRaw_Recv(IN CM_INT32 ch, OUT CM_UINT8* pBuf, IN CM_UINT32 BufSize, OUT CM_UINT32* pSrcIP, OUT CM_UINT16* pSrcPort)
{
    /*- 变量初始化 */
    CM_UINT16 len = (BufSize > 65535u) ? (CM_UINT16)(65535u) : (CM_UINT16)(BufSize);
    ENUM_CM_RETURN rt = ENUM_CM_FALSE;

    /*- 从接收线程获取输入报文 */
    rt = CM_MQ_Read(&s_CFM_RxInnetRaw[ch].MsgQ, s_CFM_UDP_Cache, &len);
    /*- 是否收到有效报文 */
    if ((ENUM_CM_TRUE == rt) && (len > (CM_UINT16)(6u)))
    {
        /*- 保存源IP、端口和收到的报文 */
        len -= 6u;
        *pSrcIP = CM_LongFromChar(s_CFM_UDP_Cache);        /* parasoft-suppress BD-PB-CHECKRET "后续在查询对应内网ID时进行非法值防护" */
        *pSrcPort = CM_ShortFromChar(s_CFM_UDP_Cache + 4); /* parasoft-suppress BD-PB-CHECKRET "后续在查询对应内网ID时进行非法值防护" */
        rt = CM_Memcpy((void*)pBuf, (CM_SIZE_T)BufSize, (void*)(s_CFM_UDP_Cache + 6), (CM_SIZE_T)(len));
        CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_22, TSCP_DARK_ASSERT_1);
    }
    else
    {
        /*- 接收长度为0 */
        len = 0u;
    }
    /*- 返回接收长度 */
    return len;
}

/**
* @brief 内网透传通信数据发送
* @param ch   内网透传通道序号，[1...n]有效
* @param pBuf 发送报文指针
* @param Len 发送报文长度
* @param DstIP 目的IP
* @param DstPort 目的端口
* @return 发送结果
* - ENUM_CM_TRUE 成功
* - ENUM_CM_FALSE 失败
*/
ENUM_CM_RETURN CFM_InnetRaw_Send(IN CM_INT32 ch, IN const CM_UINT8* Buf, IN CM_INT32 Len, IN CM_UINT32 DstIP, IN CM_UINT16 DstPort)
{
    /*- 返回内网透传通信通道的发送结果 */
    return CM_UDP_Send_Msg(s_CFM_Sock.Sock_InnetRaw[ch], Buf, Len, DstIP, DstPort);
}

/**
* @brief 外网安全通信数据接收
* @param pBuf 接收报文指针
* @param BufLen 接收报文缓冲区大小
* @param pChn 外网通道类型
* @return 接收报文长度
* - 正整数 接收报文长度
* - 0或负数 接收失败
*/
CM_INT32 CFM_OutnetSafe_Recv(OUT CM_UINT8* pBuf, IN CM_UINT32 BufSize, OUT ENUM_OUTNET_CHN_T* pChn)
{
    /*- 变量初始化 */
    CM_UINT16 len = (BufSize > 65535u) ? (CM_UINT16)(65535u) : (CM_UINT16)(BufSize);
    ENUM_CM_RETURN rt = ENUM_CM_FALSE;

    CM_UINT32 srcIP = 0u;
    CM_UINT16 srcPort = 0u;

    /*- 从接收线程获取输入报文 */
    rt = CM_MQ_Read(&s_CFM_RxOutnetSafe.MsgQ, s_CFM_UDP_Cache, &len);
    /*- 是否收到有效报文 */
    if ((ENUM_CM_TRUE == rt) && (len > 6u))
    {
        /*- 读取源IP和端口 */
        srcIP = CM_LongFromChar(s_CFM_UDP_Cache);
        srcPort = CM_ShortFromChar(s_CFM_UDP_Cache + 4);
        len -= 6u;
        /*- 是否来自红网CC */
        if ((srcIP == inet_addr(g_PFM_Cfg.CC_R_IP)) && (g_PFM_Cfg.CC_R_OutnetSafe_Port == srcPort))
        {
            /*- 来自外网红网 */
            *pChn = ENUM_OUTNET_RED;
            rt = CM_Memcpy((void*)pBuf, (CM_SIZE_T)BufSize, (void*)(s_CFM_UDP_Cache + 6), (CM_SIZE_T)len);
            CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_23, TSCP_DARK_ASSERT_1);
        }
        /*- 是否来自蓝网CC */
        else if ((srcIP == inet_addr(g_PFM_Cfg.CC_B_IP)) && (g_PFM_Cfg.CC_B_OutnetSafe_Port == srcPort))
        {
            /*- 来自外网蓝网 */
            *pChn = ENUM_OUTNET_BLUE;
            rt = CM_Memcpy((void*)pBuf, (CM_SIZE_T)BufSize, (void*)(s_CFM_UDP_Cache + 6), (CM_SIZE_T)len);
            CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_23, TSCP_DARK_ASSERT_2);
        }
        else if ((srcIP == inet_addr(g_PFM_Cfg.EXTEND_R_IP)) && (g_PFM_Cfg.CC_R_OutnetSafe_Port == srcPort))
        {
            *pChn = ENUM_OUTNET_EXTEND_RED;
            rt = CM_Memcpy((void*)pBuf, (CM_SIZE_T)BufSize, (void*)(s_CFM_UDP_Cache + 6), (CM_SIZE_T)len);
            CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_23, TSCP_DARK_ASSERT_3);
        }
        else if ((srcIP == inet_addr(g_PFM_Cfg.EXTEND_B_IP)) && (g_PFM_Cfg.CC_B_OutnetSafe_Port == srcPort))
        {
            *pChn = ENUM_OUTNET_EXTEND_BLUE;
            rt = CM_Memcpy((void*)pBuf, (CM_SIZE_T)BufSize, (void*)(s_CFM_UDP_Cache + 6), (CM_SIZE_T)len);
            CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_23, TSCP_DARK_ASSERT_4);
        }
        else
        {
            /*- 异常，宕机*/
            MSCP_LOG_MSG("unkown msg rcv from %08x:%d,len=%d\n", srcIP, srcPort, len);
			(void)CFM_DarkLog_Multiple(DARK_LOG_HEX, TSCP_DARK_CFMNET_OUTNETSAFE_RECVLENERO, 3, \
					sizeof(CM_UINT32),srcIP,
					sizeof(CM_UINT16),srcPort,
					sizeof(CM_UINT16),len);
			CM_RE_ASSERT(0, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_23, TSCP_DARK_ASSERT_5);
        }
    }
    else
    {
        /*- 接收长度为0 */
        len = 0u;
    }
    /*- 返回接收长度 */
    return (CM_INT32)len;
}

/**
* @brief 外网安全数据发送
* @param pBuf 发送报文指针
* @param Len 发送报文长度
* @param Chn 外网通道类型
* @return 发送结果
* - ENUM_CM_TRUE 成功
* - ENUM_CM_FALSE 失败
*/
ENUM_CM_RETURN CFM_OutnetSafe_Send(IN const CM_UINT8* pBuf, IN CM_INT32 Len, IN ENUM_OUTNET_CHN_T Chn)
{
    /*- 变量初始化 */
    ENUM_CM_RETURN rt = ENUM_CM_FALSE;
    /*- 是否是外网红网通道 */
    if (ENUM_OUTNET_RED == Chn)
    {
        /*- UDP方式以外网数据通道发送给红网CC */
        rt = CM_UDP_Send_Msg(s_CFM_Sock.Sock_OutnetSafe, pBuf, Len, inet_addr(g_PFM_Cfg.CC_R_IP),g_PFM_Cfg.CC_R_OutnetSafe_Port);
    }
    /*- 是否是外网蓝网通道 */
    else if (ENUM_OUTNET_BLUE == Chn)
    {
        /*- UDP方式以外网数据通道发送给蓝网CC */
        rt = CM_UDP_Send_Msg(s_CFM_Sock.Sock_OutnetSafe, pBuf, Len, inet_addr(g_PFM_Cfg.CC_B_IP), g_PFM_Cfg.CC_B_OutnetSafe_Port);
    }
    else if (ENUM_OUTNET_EXTEND_RED == Chn)
    {
        rt = CM_UDP_Send_Msg(s_CFM_Sock.Sock_OutnetSafe, pBuf, Len, inet_addr(g_PFM_Cfg.EXTEND_R_IP), g_PFM_Cfg.CC_R_OutnetSafe_Port);
    }
    else if (ENUM_OUTNET_EXTEND_BLUE == Chn)
    {
        rt = CM_UDP_Send_Msg(s_CFM_Sock.Sock_OutnetSafe, pBuf, Len, inet_addr(g_PFM_Cfg.EXTEND_B_IP), g_PFM_Cfg.CC_B_OutnetSafe_Port);
    }
    else
    {
        /*- 异常，宕机 */
    	CM_RE_ASSERT(0, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_24, TSCP_DARK_ASSERT_1);
    }
    /*- 返回发送结果 */
    return rt;
}

/**
* @brief 外网透传通信数据接收
* @param pBuf 接收报文指针
* @param BufLen 接收报文缓冲区大小
* @param pChn 外网通道类型
* @return 接收报文长度
* - 正整数 接收报文长度
* - 0或负数 接收失败
*/
CM_UINT16 CFM_OutnetRaw_Recv(OUT CM_UINT8* pBuf, IN CM_UINT32 BufSize, OUT ENUM_OUTNET_CHN_T* pChn)
{
    /*- 变量初始化 */
    CM_UINT16 len = (BufSize > 65535u) ? (CM_UINT16)(65535u) : (CM_UINT16)(BufSize);
    ENUM_CM_RETURN rt = ENUM_CM_FALSE;

    CM_UINT32 srcIP = 0u;
    CM_UINT16 srcPort = 0u;

    /*- 从接收线程获取输入报文 */
    rt = CM_MQ_Read(&s_CFM_RxOutnetRaw.MsgQ, s_CFM_UDP_Cache, &len);
    /*- 是否收到有效报文 */
    if ((ENUM_CM_TRUE == rt) && (len > 6u))
    {
        /*- 读取源IP和端口 */
        srcIP = CM_LongFromChar(s_CFM_UDP_Cache);
        srcPort = CM_ShortFromChar(s_CFM_UDP_Cache + 4);
        len -= 6u;
        /*- 是否来自红网CC */
        if ((srcIP == inet_addr(g_PFM_Cfg.CC_R_IP)) && (g_PFM_Cfg.CC_R_OutnetRaw_Port == srcPort))
        {
            /*- 来自外网红网 */
            *pChn = ENUM_OUTNET_RED;
            rt = CM_Memcpy((void*)pBuf, (CM_SIZE_T)BufSize, (void*)(s_CFM_UDP_Cache + 6), (CM_SIZE_T)len);
            CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_25, TSCP_DARK_ASSERT_1);
        }
        /*- 是否来自蓝网CC */
        else if ((srcIP == inet_addr(g_PFM_Cfg.CC_B_IP)) && (g_PFM_Cfg.CC_B_OutnetRaw_Port == srcPort))
        {
            /*- 来自外网蓝网 */
            *pChn = ENUM_OUTNET_BLUE;
            rt = CM_Memcpy((void*)pBuf, (CM_SIZE_T)BufSize, (void*)(s_CFM_UDP_Cache + 6), (CM_SIZE_T)len);
            CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_25, TSCP_DARK_ASSERT_2);
        }
        else if ((srcIP == inet_addr(g_PFM_Cfg.EXTEND_R_IP)) && (g_PFM_Cfg.CC_R_OutnetRaw_Port == srcPort))
        {
            *pChn = ENUM_OUTNET_EXTEND_RED;
            rt = CM_Memcpy((void*)pBuf, (CM_SIZE_T)BufSize, (void*)(s_CFM_UDP_Cache + 6), (CM_SIZE_T)len);
            CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_25, TSCP_DARK_ASSERT_3);
        }
        else if ((srcIP == inet_addr(g_PFM_Cfg.EXTEND_B_IP)) && (g_PFM_Cfg.CC_B_OutnetRaw_Port == srcPort))
        {
            *pChn = ENUM_OUTNET_EXTEND_BLUE;
            rt = CM_Memcpy((void*)pBuf, (CM_SIZE_T)BufSize, (void*)(s_CFM_UDP_Cache + 6), (CM_SIZE_T)len);
            CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_25, TSCP_DARK_ASSERT_4);
        }
        else
        {
            /*- 异常，宕机*/
            MSCP_LOG_MSG("unkown msg rcv from %08x:%d,len=%d\n", srcIP, srcPort, len);
            (void)CFM_DarkLog_Multiple(DARK_LOG_HEX, TSCP_DARK_CFMNET_OUTNETRAW_RECVLENERO, 3, \
            					sizeof(CM_UINT32),srcIP,
            					sizeof(CM_UINT16),srcPort,
            					sizeof(CM_UINT16),len);
            CM_RE_ASSERT(0, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_25, TSCP_DARK_ASSERT_5);
        }
    }
    else
    {
        /*- 接收长度为0 */
        len = 0u;
    }
    /*- 返回接收长度 */
    return len;
}

/**
* @brief 外网透传数据发送
* @param pBuf 发送报文指针
* @param Len 发送报文长度
* @param Chn 外网通道类型
* @return 发送结果
* - ENUM_CM_TRUE 成功
* - ENUM_CM_FALSE 失败
*/
ENUM_CM_RETURN CFM_OutnetRaw_Send(IN const CM_UINT8* pBuf, IN CM_INT32 Len, IN ENUM_OUTNET_CHN_T Chn)
{
    /*- 变量初始化 */
    ENUM_CM_RETURN rt = ENUM_CM_FALSE;
    /*- 是否是外网红网通道 */
    if (ENUM_OUTNET_RED == Chn)
    {
        /*- UDP方式以外网数据通道发送给红网CC */
        rt = CM_UDP_Send_Msg(s_CFM_Sock.Sock_OutnetRaw, pBuf, Len, inet_addr(g_PFM_Cfg.CC_R_IP),g_PFM_Cfg.CC_R_OutnetRaw_Port);
    }
    /*- 是否是外网蓝网通道 */
    else if (ENUM_OUTNET_BLUE == Chn)
    {
        /*- UDP方式以外网数据通道发送给蓝网CC */
        rt = CM_UDP_Send_Msg(s_CFM_Sock.Sock_OutnetRaw, pBuf, Len, inet_addr(g_PFM_Cfg.CC_B_IP), g_PFM_Cfg.CC_B_OutnetRaw_Port);
    }
    else if (ENUM_OUTNET_EXTEND_RED == Chn)
    {
        rt = CM_UDP_Send_Msg(s_CFM_Sock.Sock_OutnetRaw, pBuf, Len, inet_addr(g_PFM_Cfg.EXTEND_R_IP), g_PFM_Cfg.CC_R_OutnetRaw_Port);
    }
    else if (ENUM_OUTNET_EXTEND_BLUE == Chn)
    {
        rt = CM_UDP_Send_Msg(s_CFM_Sock.Sock_OutnetRaw, pBuf, Len, inet_addr(g_PFM_Cfg.EXTEND_B_IP), g_PFM_Cfg.CC_B_OutnetRaw_Port);
    }
    else
    {
        /*- 异常，宕机 */
    	CM_RE_ASSERT(0, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_26, TSCP_DARK_ASSERT_1);
    }
    /*- 返回发送结果 */
    return rt;
}

/**
* @brief 外网心跳通信数据接收
* @param pBuf 接收报文指针
* @param BufLen 接收报文缓冲区大小
* @param pChn 外网通道类型
* @return 接收报文长度
* - 正整数 接收报文长度
* - 0或负数 接收失败
*/
CM_UINT16 CFM_OutnetHeart_Recv(OUT CM_UINT8* pBuf, IN CM_UINT32 BufSize, OUT ENUM_OUTNET_CHN_T* pChn)
{
    /*- 变量初始化 */
    CM_UINT16 len = (BufSize > 65535u) ? (CM_UINT16)(65535u) : (CM_UINT16)(BufSize);
    ENUM_CM_RETURN rt = ENUM_CM_FALSE;

    CM_UINT32 srcIP = 0u;
    CM_UINT16 srcPort = 0u;
	/*- 参数非空检查 */
	if((NULL != pBuf) && (NULL != pChn))
	{
	    /*- 从接收线程获取输入报文 */
	    rt = CM_MQ_Read(&s_CFM_RxOutnetHeart.MsgQ, s_CFM_UDP_Cache, &len);
	    /*- 是否收到有效报文 */
	    if ((ENUM_CM_TRUE == rt) && (len > 6u))
	    {
	        /*- 读取源IP和端口 */
	        srcIP = CM_LongFromChar(s_CFM_UDP_Cache);
	        srcPort = CM_ShortFromChar(s_CFM_UDP_Cache + 4);
	        len -= 6u;
	        /*- 是否来自红网CC */
	        if ((srcIP == inet_addr(g_PFM_Cfg.CC_R_IP)) && (g_PFM_Cfg.CC_R_Heart_Port == srcPort))
	        {
	            /*- 来自外网红网 */
	            *pChn = ENUM_OUTNET_RED;
	            rt = CM_Memcpy((void*)pBuf, (CM_SIZE_T)BufSize, (void*)(s_CFM_UDP_Cache + 6), (CM_SIZE_T)len);
	            CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_37, TSCP_DARK_ASSERT_1);
	        }
	        /*- 是否来自蓝网CC */
	        else if ((srcIP == inet_addr(g_PFM_Cfg.CC_B_IP)) && (g_PFM_Cfg.CC_B_Heart_Port == srcPort))
	        {
	            /*- 来自外网蓝网 */
	            *pChn = ENUM_OUTNET_BLUE;
	            rt = CM_Memcpy((void*)pBuf, (CM_SIZE_T)BufSize, (void*)(s_CFM_UDP_Cache + 6), (CM_SIZE_T)len);
	            CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_37, TSCP_DARK_ASSERT_2);
	        }
			/*- 是否来自红网SEB */
	        else if ((srcIP == inet_addr(g_PFM_Cfg.EXTEND_R_IP)) && (g_PFM_Cfg.CC_R_Heart_Port == srcPort))
	        {
	        	/*- 来自外网红网SEB */
	            *pChn = ENUM_OUTNET_EXTEND_RED;
	            rt = CM_Memcpy((void*)pBuf, (CM_SIZE_T)BufSize, (void*)(s_CFM_UDP_Cache + 6), (CM_SIZE_T)len);
	            CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_37, TSCP_DARK_ASSERT_3);
	        }
			/*- 是否来自蓝网SEB */
	        else if ((srcIP == inet_addr(g_PFM_Cfg.EXTEND_B_IP)) && (g_PFM_Cfg.CC_B_Heart_Port == srcPort))
	        {
			/*- 来自外网蓝网SEB */
	            *pChn = ENUM_OUTNET_EXTEND_BLUE;
	            rt = CM_Memcpy((void*)pBuf, (CM_SIZE_T)BufSize, (void*)(s_CFM_UDP_Cache + 6), (CM_SIZE_T)len);
	            CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_37, TSCP_DARK_ASSERT_4);
	        }
	        else
	        {
	            /*- 异常，宕机*/
	        	(void)CFM_DarkLog_Multiple(DARK_LOG_HEX, TSCP_DARK_CFMNET_OUTNETHEART_RECVLENERO, 3, \
	        						sizeof(CM_UINT32),srcIP,
	        						sizeof(CM_UINT16),srcPort,
	        						sizeof(CM_UINT16),len);
	            MSCP_LOG_MSG("unkown msg rcv from %08x:%d,len=%d\n", srcIP, srcPort, len);
	            CM_RE_ASSERT(0, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_37, TSCP_DARK_ASSERT_5);
	        }
	    }
	    else
	    {
	        /*- 接收长度为0 */
	        len = 0u;
	    }
	}
	else
	{
		/*- 空指针无处理*/
	}
    /*- 返回接收长度 */
    return len;
}
/**
* @brief 外网心跳数据发送
* @param pBuf 发送报文指针
* @param Len 发送报文长度
* @param Chn 外网通道类型
* @return 发送结果
* - ENUM_CM_TRUE 成功
* - ENUM_CM_FALSE 失败
*/
ENUM_CM_RETURN CFM_OutnetHeart_Send(IN const CM_UINT8* pBuf, IN CM_INT32 Len, IN ENUM_OUTNET_CHN_T Chn)
{
    /*- 变量初始化 */
    ENUM_CM_RETURN rt = ENUM_CM_FALSE;
	/*- 参数非空检查 */
	if(NULL != pBuf)
	{
	    /*- 是否是外网红网通道 */
	    if (ENUM_OUTNET_RED == Chn)
	    {
	        /*- UDP方式以外网数据通道发送给红网CC */
	        rt = CM_UDP_Send_Msg(s_CFM_Sock.Sock_OutnetHeart, pBuf, Len, inet_addr(g_PFM_Cfg.CC_R_IP),g_PFM_Cfg.CC_R_Heart_Port);
	    }
	    /*- 是否是外网蓝网通道 */
	    else if (ENUM_OUTNET_BLUE == Chn)
	    {
	        /*- UDP方式以外网数据通道发送给蓝网CC */
	        rt = CM_UDP_Send_Msg(s_CFM_Sock.Sock_OutnetHeart, pBuf, Len, inet_addr(g_PFM_Cfg.CC_B_IP), g_PFM_Cfg.CC_B_Heart_Port);
	    }
		/*- 是否是外网扩展红网通道 */
	    else if (ENUM_OUTNET_EXTEND_RED == Chn)
	    {
	        rt = CM_UDP_Send_Msg(s_CFM_Sock.Sock_OutnetHeart, pBuf, Len, inet_addr(g_PFM_Cfg.EXTEND_R_IP), g_PFM_Cfg.CC_R_Heart_Port);
	    }
		/*- 是否是外网扩展蓝网通道 */
	    else if (ENUM_OUTNET_EXTEND_BLUE == Chn)
	    {
	        rt = CM_UDP_Send_Msg(s_CFM_Sock.Sock_OutnetHeart, pBuf, Len, inet_addr(g_PFM_Cfg.EXTEND_B_IP), g_PFM_Cfg.CC_B_Heart_Port);
	    }
	    else
	    {
	        /*- 异常，宕机 */
	    	CM_RE_ASSERT(0, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_36, TSCP_DARK_ASSERT_1);
	    }
	}
	else
	{
		/*- 空指针无处理*/
		(void)CFM_DarkLog_Storage(DARK_LOG_HEX, TSCP_DARK_WARNING, 4U, DARK_FAULT_CODE_MERGE(NET_MODE, DARK_FAULT_CODE_FUN_ORDER_14, TSCP_DARK_ASSERT_1));
	}
    /*- 返回发送结果 */
    return rt;
}


static CM_THREAD_FUNC_T t_ClearArpThread(void)
{
	static STRU_HARDWARE_BOOT_COM_T lastComRecord;
	CM_UINT32 cycle = DFM_GetBirthCount();
	CM_UINT8 cmdBuf[100] = {0};
#if QNX
    void* pmask = NULL;
    /*- 本线程锁定在 A53 core 1 */
    pmask = (void*)(0x01u|0x02u);
    (void)ThreadCtl(_NTO_TCTL_RUNMASK, pmask);
#endif
	while(1)
	{
		cycle = DFM_GetBirthCount();
		if((cycle > (g_Hardware_boot_com_state.CCU_A_Count + 100u))&&(lastComRecord.CCU_A_Count != g_Hardware_boot_com_state.CCU_A_Count))
		{
			lastComRecord.CCU_A_Count = g_Hardware_boot_com_state.CCU_A_Count;
			snprintf(cmdBuf, sizeof(cmdBuf), "arp -d %s", g_PFM_Cfg.CC_R_IP);
			(void)system(cmdBuf);
			MSCP_LOG_MSG("%s\n", cmdBuf);
			MSCP_LOG_MSG("clear arp cycle = %d,g_Hardware_boot_com_state.CCU_A_Count=%d,lastComRecord.CCU_A_Count=%d\n",cycle,g_Hardware_boot_com_state.CCU_A_Count,lastComRecord.CCU_A_Count);
		}
		else
		{
			/* 无处理 */
		}

		if((cycle > (g_Hardware_boot_com_state.CCU_B_Count + 100u))&&(lastComRecord.CCU_B_Count != g_Hardware_boot_com_state.CCU_B_Count))
		{
			lastComRecord.CCU_B_Count = g_Hardware_boot_com_state.CCU_B_Count;
			snprintf(cmdBuf, sizeof(cmdBuf), "arp -d %s", g_PFM_Cfg.CC_B_IP);
			(void)system(cmdBuf);
			MSCP_LOG_MSG("%s\n", cmdBuf);
			MSCP_LOG_MSG("clear arp cycle = %d,g_Hardware_boot_com_state.CCU_B_Count=%d,lastComRecord.CCU_B_Count=%d\n",cycle,g_Hardware_boot_com_state.CCU_B_Count,lastComRecord.CCU_B_Count);
		}
		else
		{
			/* 无处理 */
		}

		if(NULL == p_Serial_IN_VOBC_Func)
		{
			/* 无处理 */
		}
		else
		{
			if((cycle > (g_Hardware_boot_com_state.SEB_A_Count + 100u))&&(lastComRecord.SEB_A_Count != g_Hardware_boot_com_state.SEB_A_Count))
			{
				lastComRecord.SEB_A_Count = g_Hardware_boot_com_state.SEB_A_Count;
				snprintf(cmdBuf, sizeof(cmdBuf), "arp -d %s", g_PFM_Cfg.EXTEND_R_IP);
				(void)system(cmdBuf);
				MSCP_LOG_MSG("%s\n", cmdBuf);
				MSCP_LOG_MSG("clear arp cycle = %d,g_Hardware_boot_com_state.SEB_A_Count=%d,lastComRecord.SEB_A_Count=%d\n",cycle,g_Hardware_boot_com_state.SEB_A_Count,lastComRecord.SEB_A_Count);
			}
			else
			{
				/* 无处理 */
			}

			if((cycle > (g_Hardware_boot_com_state.SEB_B_Count + 100u))&&(lastComRecord.SEB_B_Count != g_Hardware_boot_com_state.SEB_B_Count))
			{
				lastComRecord.SEB_B_Count = g_Hardware_boot_com_state.SEB_B_Count;
				snprintf(cmdBuf, sizeof(cmdBuf), "arp -d %s", g_PFM_Cfg.EXTEND_B_IP);
				(void)system(cmdBuf);
				MSCP_LOG_MSG("%s\n", cmdBuf);
				MSCP_LOG_MSG("clear arp cycle = %d,g_Hardware_boot_com_state.SEB_B_Count=%d,lastComRecord.SEB_B_Count=%d\n",cycle,g_Hardware_boot_com_state.SEB_B_Count,lastComRecord.SEB_B_Count);
			}
			else
			{
				/* 无处理 */
			}
		}

		CM_Sleep(1000u);
	}
	return NULL;
}


/*
MAC层：14字节
dst MAC [6] src MAC [6] type [2]
IP层：20字节
head [12]  src ip [4] dst ip [4]
UDP层：8字节
src port [2] dst port [2] len [2] crc16 [2]
TCP层：20字节
...
*/
