#pragma once

#include "myIcp67.h"

#include <map>
/**************************************************/

// 设备类型定义
typedef enum
{
    ENUM_DEV_TYPE_MAINTENANCE = 1,  // 维护软件
    ENUM_DEV_TYPE_SYS = 2,          // 主板
    ENUM_DEV_TYPE_SAMPL = 3,        // 采样板
    ENUM_DEV_TYPE_LCD = 4,          // LCD屏
}enum_dev_type;

/**************************************************/
// 方向定义
typedef enum
{
    ENUM_DIR_SLAVE = 0,   // 从动站
    ENUM_DIR_MASTER = 1,  // 启动站
}enum_dir;


/**************************************************/
// 类型标识定义
#define TI_1   (1)    // 读独立编码参数
#define TI_2   (2)    // 写独立编码参数
#define TI_3   (3)    // 读自定义组合编码参数 [点表，校准数据]
#define TI_4   (4)    // 写自定义组合编码参数 [点表，校准数据]
#define TI_5   (5)    // 终端时间
#define TI_6   (6)    // 终端状态读取 [查询相关自检信息，版本号]
#define TI_9   (9)    // 升级
#define TI_11  (11)   // 文件操作 [文件读写，升级时使用文件流程]
// #define TI_20  (20)   // 遥信置数
// #define TI_21  (21)   // 遥测置数
// #define TI_22  (22)   // 校准
// #define TI_23  (23)   // 采样通道置数
// #define TI_24  (24)   // 硬遥信置数
#define TI_30  (30)   // 录波文件压缩
// #define TI_100 (100)  // 召唤遥信 [lcd交互，传输地址为点表地址]
// #define TI_101 (101)  // 召唤遥测 [lcd交互，传输地址为点表地址]
// #define TI_102 (102)  // SOE信息 [lcd交互]
// #define TI_103 (103)  // 故障事件信息 [lcd交互]
// #define TI_104 (104)  // 遥控操作 [lcd交互]
// #define TI_105 (105)  // 扩展信息 [lcd交互]
// #define TI_106 (106)  // 遥控操作记录 [lcd交互]
#define TI_200 (200)  // 遥测传输 [采样板交互]
#define TI_201 (201)  // 状态传输 [采样板交互]
#define TI_202 (202)  // 计量传输 [
#define TI_203 (203)  // 遥控交互 [采样板交互]
#define TI_204 (204)  // SOE传输 [采样板交互]
#define TI_205 (205)  // 故障事件传输 [采样板交互]
// #define TI_206 (206)  // 潮流反向传输 [采样板交互]
#define TI_207 (207)  // 遥测扰动传输 [采样板交互]
#define TI_208 (208)  // 按键操作传输 [采样板交互]
// #define TI_220 (220)  // 录波 [采样板交互]
#define TI_221 (221)  // 时间同步 [采样板交互]
#define TI_222 (222)  // 日志信息传输 [采样板交互]

/**************************************************/
// 传输原因定义
#define COT_3   (3)   
#define COT_5   (5)    // 请求
#define COT_6   (6)    // 激活
#define COT_7   (7)    // 正常确认
#define COT_8   (8)    // 终端响应
#define COT_20  (20)   // MD5不匹配

/**************************************************/
// 信息体地址
#define TI_1_INFO_ADDR (0)  // 独立编码参数信息体地址



#define TI_5_INFO_ADDR (0) // 终端时间 信息体地址
#define TI_6_INFO_ADDR (1) // 终端状态读取 信息体地址
#define TI_9_INFO_ADDR (0) // 升级 信息体地址

#define TI_11_INFO_ADDR (0) // 文件操作 信息体地址

/**************************************************/
// 帧头定义
#define ICP67_HEAD (0x67)  // 启动字符

// 帧尾定义
#define ICP67_TAIL (0x16)  // 帧尾字符




/**************************************************/
// 独立编码参数数据结构
#pragma pack(1)
typedef struct
{
    uint8_t md5[16];  // MD5校验码
    uint16_t num;     // 参数个数
    uint8_t data[0];  // 参数数据
}stru_ti_1_2;
#pragma pack()





/**************************************************/
// 自定义组合编码参数

#pragma pack(1)
typedef struct
{
    uint16_t total;  // 总参数个数
    uint16_t frame_no;  // 帧序号
    uint8_t follow;    // 后续帧标志
    uint16_t num;  // 参数个数
    uint8_t data[0];   // 数据区
}stru_ti_3_follow;
#pragma pack()


#pragma pack(1)
typedef struct
{
    uint16_t total;  // 总参数个数
    uint16_t frame_no;  // 帧序号
    uint8_t follow;    // 后续帧标志
    uint8_t data[0];   // 数据区
}stru_ti_3_4;
#pragma pack()

#pragma pack(1)
typedef struct
{
    uint8_t num;  // 参数个数
    uint8_t data[0];   // 数据区
}stru_ti_3_4_data;
#pragma pack()





/**************************************************/
// 终端状态读取
#pragma pack(1)
typedef struct
{
    uint16_t st_num;  // 状态个数
    uint8_t st_data[0];  // 状态数据
}stru_ti_6;
#pragma pack()

// 状态数据 使用stru_data_info


/**************************************************/
// 文件操作
#define FILE_CMD_1 (1) // 读目录
#define FILE_CMD_2 (2) // 读目录响应
#define FILE_CMD_3 (3) // 读文件激活
#define FILE_CMD_4 (4) // 读文件激活响应
#define FILE_CMD_5 (5) // 读文件内容
#define FILE_CMD_6 (6) // 读文件内容响应
#define FILE_CMD_7 (7) // 写文件激活
#define FILE_CMD_8 (8) // 写文件激活响应
#define FILE_CMD_9 (9) // 写文件内容
#define FILE_CMD_10 (10) // 写文件内容响应
#define FILE_CMD_11 (11) // 写文件校验成功



// 读目录
#pragma pack(1)
typedef struct
{
    uint8_t cmd; // 文件操作
    uint32_t id; // 目录ID
    uint8_t len; // 目录长度
    uint8_t data[0]; // 数据
}stru_ti_11_1;
#pragma pack()

// 读目录内容
#pragma pack(1)
typedef struct
{
    uint8_t flag; // 召唤标志 0：所有，1：指定时间
    uint8_t start_tm[7]; // 起始时间
    uint8_t end_tm[7]; // 结束时间
    uint8_t data[0]; // 数据
}stru_ti_11_1_info;
#pragma pack()

// 读目录响应
#pragma pack(1)
typedef struct
{
    uint8_t cmd; // 文件操作
    uint8_t result; // 结果
    uint32_t id; // 目录ID
    uint8_t follow; // 后续标志
    uint16_t num; // 文件个数
    uint8_t data[0]; // 数据
}stru_ti_11_2;
#pragma pack()

// 读文件激活
#pragma pack(1)
typedef struct
{
    uint8_t cmd; // 文件操作
    uint8_t len; // 文件名长度
    uint8_t data[0]; // 数据
}stru_ti_11_3;
#pragma pack()

// 读文件激活响应
#pragma pack(1)
typedef struct
{
    uint8_t cmd; // 文件操作
    uint8_t result; // 结果
    uint8_t len; // 文件名长度
    uint8_t data[0]; // 数据
}stru_ti_11_4;
#pragma pack()

// 读文件内容
#pragma pack(1)
typedef struct
{
    uint8_t cmd; // 文件操作
    uint32_t id; // 文件ID
    uint32_t offset; // 偏移地址
    uint8_t follow; // 后续标志
    uint16_t len; // 长度
    uint8_t data[0]; // 数据
}stru_ti_11_5;
#pragma pack()

// 读文件内容响应
#pragma pack(1)
typedef struct
{
    uint8_t cmd; // 文件操作
    uint32_t id; // 文件ID
    uint32_t offset; // 偏移地址
    uint8_t result; // 结果
    uint8_t data[0]; // 数据
}stru_ti_11_6;
#pragma pack()

// 写文件激活
#pragma pack(1)
typedef struct
{
    uint8_t cmd; // 文件操作
    uint8_t len; // 文件名长度
    uint8_t data[0]; // 数据
}stru_ti_11_7;
#pragma pack()


// 写文件激活响应
#pragma pack(1)
typedef struct
{
    uint8_t cmd; // 文件操作
    uint8_t result; // 结果 
    uint8_t len; // 文件名长度
    uint8_t data[0]; // 数据
}stru_ti_11_8;
#pragma pack()



// 写文件内容
#pragma pack(1)
typedef struct
{
    uint8_t cmd; // 文件操作
    uint32_t id; // 文件ID
    uint32_t offset; // 偏移地址
    uint8_t follow; // 后续标志
    uint16_t len; // 长度
    uint8_t data[0]; // 数据
}stru_ti_11_9;
#pragma pack()

// 写文件内容响应
#pragma pack(1)
typedef struct
{
    uint8_t cmd; // 文件操作
    uint32_t id; // 文件ID
    uint32_t offset; // 偏移地址
    uint8_t result; // 结果
    uint8_t md5[16]; // MD5校验码
    uint8_t data[0]; // 数据
}stru_ti_11_10;
#pragma pack()



// 写文件校验成功
#pragma pack(1)
typedef struct
{
    uint8_t cmd; // 文件操作
    uint32_t id; // 文件ID
    uint8_t result; // 结果
    uint8_t md5[16]; // MD5校验码
    uint8_t data[0]; // 数据
}stru_ti_11_11;
#pragma pack()


// 文件ID、大小、校验信息
#pragma pack(1)
typedef struct
{
    uint32_t id; // 文件ID
    uint32_t size; // 文件大小
    uint16_t crc; // 校验码
}stru_ti_11_file_info;
#pragma pack()


/**************************************************/

// 录波文件压缩控制
#pragma pack(1)
typedef struct
{
    uint8_t cmd; // 录波文件压缩控制命令
    uint8_t zip_type; // 压缩类型
    uint8_t len; // 压缩文件名长度
    uint8_t data[0]; // 数据
}stru_ti_30_1;
#pragma pack()

// 录波文件压缩控制响应
#pragma pack(1)
typedef struct
{
    uint8_t cmd; // 录波文件压缩控制命令
    uint8_t zip_type; // 压缩类型
    uint8_t len; // 压缩文件名长度
    uint8_t data[0]; // 数据
}stru_ti_30_2;
#pragma pack()

// 压缩文件传输
#pragma pack(1)
typedef struct
{
    uint8_t cmd; // 压缩文件传输命令
    uint8_t file_no; // 文件号
    uint32_t offset; // 偏移地址
    uint16_t len; // 长度
    uint8_t data[0]; // 数据
}stru_ti_30_3;
#pragma pack()

// 压缩文件传输响应
#pragma pack(1)
typedef struct
{
    uint8_t cmd; // 压缩文件传输命令
    uint8_t file_no; // 文件号
    uint32_t offset; // 偏移地址
    uint8_t data[0]; // 数据
}stru_ti_30_4;
#pragma pack()

// 录波文件压缩控制命令
#define TI_30_CMD_1 (1) // 录波文件压缩控制命令
#define TI_30_CMD_2 (2) // 录波文件压缩控制命令响应
#define TI_30_CMD_3 (3) // 压缩文件传输命令
#define TI_30_CMD_4 (4) // 压缩文件传输命令响应


/**************************************************/

// 遥测、遥信、计量数据传输报文
#pragma pack(1)
typedef struct
{
    uint16_t num; // 遥测个数
    uint16_t addr; // 起始地址
    uint8_t data[0]; // 数据
}stru_ti_200_201_202;
#pragma pack()


/**************************************************/
// 遥控交互报文
#pragma pack(1)
typedef struct
{
    uint16_t addr; // 遥控地址
    uint8_t cmd; // 命令
    uint8_t status; // 状态
    uint8_t data[0]; // 数据
}stru_ti_203;
#pragma pack()

#define ICP67_TI_203_CMD_SELECT (1) // 遥控选择
#define ICP67_TI_203_CMD_DIRECT (2) // 遥控执行
#define ICP67_TI_203_CMD_CANCEL (3) // 遥控取消

#define ICP67_TI_203_STATUS_ON (1) // 控合
#define ICP67_TI_203_STATUS_OFF (0) // 控分

/**************************************************/
// soe、故障事件、遥测扰动数据传输报文
#pragma pack(1)
typedef struct
{
    uint16_t num; // 个数
    uint8_t data[0]; // 数据
}stru_ti_204_205_207;
#pragma pack()





/**************************** */




void icp67_make_head(uint8_t dst, uint8_t ti, uint8_t cot, uint16_t inf, uint8_t *p_tx, uint16_t &tx_len);
void icp67_make_tail(uint8_t *p_tx, uint16_t &tx_len);
void icp67_rtx_flag_get(stru_icp67 *p_icp67, uint8_t &flag, uint8_t &resend_cnt, uint32_t &tm_cnt);
void icp67_rtx_flag_set(stru_icp67 *p_icp67, uint8_t flag, uint8_t resend_cnt, uint32_t tm_cnt);
void icp67_reset_resend_cnt(stru_icp67 *p_icp67);
void icp67_reset_tm_cnt(stru_icp67 *p_icp67);