/**
* @file SFM_2oo2.h
* @brief Safe Function Module:2oo2功能
* @details
* 2oo2上电初始化：初始化、同步、校验
* 2oo2周期同步和2oo2数据交换
* @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 SFM_2oo2_H
#define SFM_2oo2_H
#include "CM_Types.h"
#include "SFM_package.h"
#ifdef __cplusplus
extern "C"
{
#endif

    /** 2oo2报文类型 */
    typedef enum
    {
        ENUM_2oo2_ERROR = 0,  /**< 保留 */
        ENUM_2oo2_SYNC,       /**< 同步 */
        ENUM_2oo2_INIT_CHECK, /**< 上电比较 */
        ENUM_2oo2_INPUT_EX,   /**< 输入交换 */
		ENUM_2oo2_INPUT_FULL_EX,   /**< 输入全双工交换 */
		ENUM_2oo2_INPUT_MS,   /**< 输入热备状态交换 */
        ENUM_2oo2_OUTPUT_EX,  /**< 输出交换 */
        ENUM_2oo2_END_EX,     /**< 周期末交换 */
        ENUM_2oo2_OUTPUT_CHECK,  /**< 输出比较 */
		ENUM_2oo2_RAW_INFO,
		ENUM_2oo2_SHUTDOWNQUIT,   /**< 维护模式下的2取交换 */
        ENUM_2oo2_RESET_AUTOREBOOT,/*重置自动重启*/
		ENUM_2oo2_ARQ,			/*重传请求*/
		ENUM_2oo2_RCV_SUCCESS,	/*接收成功标志*/
		ENUM_2oo2_APP,			/*应用二取类型*/
		NUM_2oo2_FIRSTSYNC,       /**< 同步 */
    }ENUM_2oo2_MSG_T;

    /** 2oo2通信控制 */
    typedef struct
    {
        CM_UINT32 LocalID; 			/**< 本机设备ID */
        CM_UINT32 PeerID;  			/**< 邻机设备ID */
        CM_UINT32 SN;      			/**< 通信序列号 */
        STRU_FrameCtrl_T FrameCtrl; /**< 分帧接收控制 */
        /*2取发送函数指针注册*/
        ENUM_CM_RETURN (*DataSend)(IN const CM_UINT8* , IN CM_INT32 );
        /*2取接收函数指针注册*/
        CM_INT32 (*DataRecv)(OUT CM_UINT8* , IN CM_UINT32 );
        CM_UINT8 UDP_Cache[NET_UDP_BUF_SIZE];	/*2取分帧收发临时缓冲区*/
    }STRU_2OO2_CTRL_T;

    extern STRU_2OO2_CTRL_T s_2oo2_Ctrl; /**< 平台通信控制 */
    extern STRU_2OO2_CTRL_T s_2oo2_Ctrl_App; /**< 应用通信控制 */

    /*2oo2上电初始化*/
    void SFM_2oo2_Init(IN const CM_UINT8 *vitalBuf, IN CM_UINT16 vitalLen, OUT CM_UINT64 *p2oo2SyncTick);

    /* 半双工2oo2数据交换 */
    CM_INT32 SFM_2oo2_Exchange_Currency(IN const CM_UINT8 * pMyData, IN CM_INT32 DataLen, OUT CM_UINT8 * pPeerData, IN CM_UINT32 DataSize, IN ENUM_2oo2_MSG_T msgType);
    CM_INT32 SFM_2oo2_Currency_App(IN const CM_UINT8 pMyData[], IN CM_INT32 DataLen, OUT CM_UINT8 pPeerData[], IN CM_UINT32 DataSize);
    /*2oo2同步*/
    CM_UINT64 SFM_2oo2_Sync(OUT CM_INT64* pOffset);
    /* 2oo2关键数据初始化 */
    void SFM_2oo2_DataInit(void);
    /* 应用半双工2oo2数据交换 */
    CM_INT32 SFM_2oo2_HalfDuplex_App(IN const CM_UINT8 pMyData[], IN CM_INT32 DataLen, OUT CM_UINT8 pPeerData[], IN CM_UINT32 DataSize);
    /* 全双工2oo2数据交换(进入运营模式后的2取交换,限制时间) */
    CM_INT32 SFM_2oo2_Exchange_FullDuplex_Crash(IN const CM_UINT8* pMyData, IN CM_INT32 DataLen, OUT CM_UINT8* pPeerData, IN CM_UINT32 DataSize, IN ENUM_2oo2_MSG_T msgType);
    /* 二取判断是否重置自动重启次数 */
    void SFM_2oo2_Reset_AutoRbootCut(void);
    /* 初始化2取控制数据以及清空2取缓冲区  */
    void SFM_2oo2_CtrlInit(void);
#ifdef __cplusplus
}
#endif
#endif
