/**
* @file CFM_Net.h
* @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>
*/
#ifndef CFM_NET_H
#define CFM_NET_H

#include "CM_Types.h"
#include "CM_Sem.h"
#include "MSCP_APP_Interface.h"
#include "CM_Mutex.h"
#include "PFM_Cfg.h"
#if QNX
#include <sys/neutrino.h> /* ThreadCtl BMP绑定CPU*/
#endif
#ifdef __cplusplus
extern "C"
{
#endif

    /*注意UDP协议栈单个UDP包最大65535字节（1024*64-1）*/
#define NET_UDP_2OO2_BUF_SIZE    ((1024*64)-(1)) /*2OO2UDP协议栈缓冲区大小（用于接收代码）*/
#define NET_UDP_MAINTENANCE_BUF_SIZE    ((1024*5)-(1)) /*2OO2UDP协议栈缓冲区大小（维护模式下用于接收代码）*/
#define NET_UDP_2X2_BUF_SIZE    ((1024*64)-(1)) /*2X2UDP协议栈缓冲区大小（用于接收代码）*/
#define NET_UDP_BUF_SIZE    ((1024*64)-(1)) /*UDPsocket消息队列缓冲区（用于接收代码）*/
#define NET_UDP_BUF_DOUBLESIZE    ((1024*256) - (1)) /*UDP协议栈缓冲区大小（用于接收代码）*/

#define NET_50K_SIZE    (50000u) /*实际允许使用的应用帧大小（用于发送代码）*/
#define NET_20K_SIZE    (20000u) /*实际允许使用的应用帧大小（用于发送代码）*/
#define CFM_INNET_RAW_MSG_NUM_MAX (7000u)
#define CFM_OUTNET_RAW_MSG_NUM_MAX (1000u)


/*暗文类型宏定义*/
#define DARK_LOG_STRING  (0x55u)
#define DARK_LOG_HEX (0xAAu)
#define DARK_LOG_DEC (0xFFu)

    /*- 时钟同步报文类型 */
    typedef enum
    {
        ENUM_TIME_ERROR = 0, /**< 保留 */
        ENUM_TIME_REQ,       /**< 时钟同步请求 */
        ENUM_TIME_ACK        /**< 时钟同步应答 */
    }ENUM_TIME_MSG_T;

    typedef struct
    {
        CM_SEM_T m_logStart;  /* 自检开始信号量 */
        CM_SEM_T m_logStop;   /* 自检结束信号量 */
        CM_MUTEX_T mutex;     /**< 互斥信号量 */
    }STRU_LOG_CTRL_T;

    /*- 时钟同步报文类型 */
    typedef enum
    {
        ENUM_THREAD_ERROR = 0, 			/**< 保留 */
		ENUM_THREAD_OutnetS_Rx = 1,     /**< 外网安全线程 */
		ENUM_THREAD_2oo2_AppRecv = 2,     /**< 应用2取线程 */
		ENUM_THREAD_2x2_StateRecv = 3     /**< 状态2x线程 */
    }ENUM_THREAD_NUM_T;

    /* 暗文发送控制变量  */
    extern STRU_LOG_CTRL_T ciphertextCtrl;
    /** 2oo2小数据量单包通信控制 */
    typedef struct
    {
        CM_UINT32 SN;      			/**< 通信序列号 */
        /*2取发送函数指针注册*/
        ENUM_CM_RETURN (*DataSend)(IN const CM_UINT8* , IN CM_INT32 );
        /*2取接收函数指针注册*/
        CM_INT32 (*DataRecv)(OUT CM_UINT8* , IN CM_UINT32 );
    }STRU_2OO2_NET_NO_PACK_T;

    /** 小数据量单包2oo2报文类型 */
    typedef enum
    {
        ENUM_2oo2_NET_ERROR = 0,  /**< 保留 */
        ENUM_2oo2_NET_DATA,       /**< 数据*/
		ENUM_2oo2_NET_ARQ,			/*重传请求*/
		ENUM_2oo2_NET_RCV_SUCCESS,	/*接收成功标志*/
    }ENUM_2oo2_NET_T;

    /*注册透传算法函数指针数组*/
    extern RAW_ALGORITHM p_ALGORITHM_Fun[INNET_RAW_DOUBLE_PASS_NUM];
    /*硬重启通信状态结构体*/
    typedef struct
    {
        CM_UINT32 SYS_Count;  /*-系统周期 */
        CM_UINT32 CCU_A_Count;/*-通控A周期 */
        CM_UINT32 CCU_B_Count;/*-通控B周期 */
        CM_UINT32 SEB_A_Count;/*-串口板A周期 */
        CM_UINT32 SEB_B_Count;/*-串口板B周期 */
    }STRU_HARDWARE_BOOT_COM_T;

    extern STRU_HARDWARE_BOOT_COM_T g_Hardware_boot_com_state;
    /**
    * @brief 2oo2上电同步
    * @details
    */
    ENUM_CM_RETURN CFM_2oo2_InitSync(void);

    /**
    * @brief 发起一次2oo2时钟同步
    * @details
    * 发送一个2oo2时钟同步请求报文
    * 由双方的时钟同步线程完成一次NTP校时操作
    * 操作完成后本方的时钟同步线程会记录到延迟时间和偏移时间
    * @see :: CFM_2oo2_TimeGet
    * @see :: t_TimeThread
    */
    void CFM_2oo2_TimeReq(void);

    /**
    * @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);

    /**
    * @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);

    /**
    * @brief 2oo2数据接收
    * @param pBuf 接收报文指针
    * @param BufLen 接收报文缓冲区大小
    * @return 接收报文长度
    * - 正整数 接收报文长度
    * - 0 接收失败
    */
    CM_INT32 CFM_2oo2_DataRecv(OUT CM_UINT8* pBuf, IN CM_UINT32 BufSize);

    /**
    * @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);

    /**
    * @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);

    /**
    * @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);

    /**
    * @brief 2oo2数据接收
    * @param pBuf 接收报文指针
    * @param BufLen 接收报文缓冲区大小
    * @return 接收报文长度
    * - 正整数 接收报文长度
    * - 0 接收失败
    */
    CM_INT32 CFM_2oo2_2xStateRecv(OUT CM_UINT8* pBuf, IN CM_UINT32 BufSize);

    /**
    * @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);

    /**
    * @brief 2oo2数据接收(维护模式)
    * @param pBuf 接收报文指针
    * @param BufLen 接收报文缓冲区大小
    * @return 接收报文长度
    * - 正整数 接收报文长度
    * - 0 接收失败
    */
    CM_INT32 CFM_2oo2_DataRecv_Crash(OUT CM_UINT8* pBuf, IN CM_UINT32 BufSize);

    /**
    * @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);

    /**
    * @brief 2oo2数据接收(宕机状态)
    * @param pBuf 接收报文指针
    * @param BufLen 接收报文缓冲区大小
    * @return 接收报文长度
    * - 正整数 接收报文长度
    * - 0 接收失败
    */
    CM_INT32 CFM_2oo2_DataRecv_ASSERT(OUT CM_UINT8* pBuf, IN CM_UINT32 BufSize);

    /**
    * @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);

    /**
    * @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);

    /**
    * @brief 通用2oo2数据接收
    * @param pBuf 接收报文指针 取值范围：非空
    * @param BufLen 接收报文缓冲区大小 取值范围：0~0xFFFFFFFF
    * @return 接收报文长度
    * - 1~0xFFFFFFFF 接收报文长度
    * - 0 接收失败
    */
    CM_INT32 CFM_2x2_StateChange_Recv(CM_UINT8* pBuf, IN CM_UINT32 BufSize);

    /**
    * @brief 发起一次2x2时钟同步
    * @details
    * 发送一个2x2时钟同步请求报文
    * 由双方的时钟同步线程完成一次NTP校时操作
    * 操作完成后本方的时钟同步线程会记录到延迟时间和偏移时间
    * @see :: CFM_2x2_TimeGet
    * @see :: t_TimeThread
    */
    void CFM_2x2_TimeReq(void);

    /**
    * @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);

    /**
    * @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);

    /**
    * @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);

    /**
    * @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);

    /**
    * @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);

    /**
    * @brief 2x2数据接收
    * @param pBuf 接收报文指针
    * @param BufLen 接收报文缓冲区大小
    * @return 接收报文长度
    * - 正整数 接收报文长度
    * - 0或负数 接收失败
    */
    CM_INT32 CFM_2x2_DataRecv(OUT CM_UINT8* pBuf, IN CM_UINT32 BufSize);

    /**
    * @brief 2x2串口数据接收
    * @param pBuf 接收报文指针(非空)
    * @param BufLen 接收报文缓冲区大小(0~0xffffffff)
    * @return 接收报文长度
    * - 正整数 接收报文长度
    * - 0或负数 接收失败
    */
    CM_UINT16 CFM_2x2_UartDataRecv(OUT CM_UINT8* pBuf, IN CM_UINT32 BufSize);

    /* @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);

    /*读数据时禁止清空（即使写满）*/
    void CFM_InnetRawClear_Mutex_Lock(IN CM_INT32 ch);
    void CFM_InnetRawClear_Mutex_UnLock(IN CM_INT32 ch);

    /**
    * @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);

    /**
    * @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);

    /**
    * @brief 清除一帧带时间戳的透传数据
    * @param ch 通道号
    * @return 无
    * @details
    */
    void CFM_Clear_InnetRaw_Rx_Msg(IN CM_INT32 ch);

    /**
    * @brief 获取接收包数和接受长度并且清空
    */
    void CFM_GetOSCache(void);

    /**
    * @brief 清空外网安全数据队列长度
    */
    void CFM_ClearCache(void);

    /*********************************维护网相关*****************************************/

    /**
    * @brief 维护网通信队列初始化
    */
    void CFM_Maintain_Queue_Init(void);

    /**
    * @brief 维护网通信UDP初始化
    */
    void CFM_Maintain_Init(void);
    /**
    * @brief 暗文日志组包发送函数
    * @param 无
    * @return 无
    * @details
    */
    void CFM_LogCiphertextSend(void);
    /**
    * @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);

    /**
    * @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);
    /**
    * @brief 平台日志保存本地文件
    * @param FILE * fp_crash 文件指针
    * @return 无
    */
    void CFM_BaseLog_SaveLocal(FILE * fp_crash);

    /**
    * @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);
    /**
    * @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, ...);

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

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

    /**
    * @brief 网络通信模块初始化
    */
    void CFM_Net_Init(void);

    /**
    * @brief 配置网卡ip
    */
    void CFM_NetworkCard_Init(void);
    /**
    * @brief 清空接收缓冲区
    */
    void CFM_Net2XFlush(void);
    /**
    * @brief 清空接收缓冲区
    */
    void CFM_Net2X_State_Flush(void);
    /**
    * @brief 清空接收缓冲区
    */
    void CFM_NetFlush(void);

    /**
    * @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);

    /**
    * @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);

    /**
    * @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);

    /**
    * @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);

    /**
    * @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);

    /**
    * @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);

    /**
    * @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);

    /**
    * @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);

    /**
    * @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);

    /**
    * @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);

    /**
    * @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);

    /**
    * @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);

    /**
    * @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);

#ifdef __cplusplus
}
#endif
#endif
