/*
 * @Author: ghzhang gogosanmao@126.com
 * @Date: 2023-06-18 14:25:26
 * @LastEditors: ybzhou yibo.zhou@lnxall.com
 * @LastEditTime: 2025-05-26 16:28:45
 * @FilePath: \lnxall_package\proto_forward\src\protocol.h
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#ifndef __PROTOCOL_H__
#define __PROTOCOL_H__
#include <stdint.h>
#include "modbus.h"
#include "dlt645.h"
#include "ups.h"
#include "bmser.h"
#include "common.h"
#include "tag.h"
#include "custom.h"
#include "ydt1363.h"

typedef struct uart_par_t
{
    char f_name[24];
    int baud;
    uint8_t data_bit;
    uint8_t stop_bit;
    char parity;
} uart_par_t;

typedef enum modbus_if_t
{
    MDBUS_RTU = 0,
    MDBUS_RTU_OVER_TCP,
    MDBUS_TCP,
    MDBUS_TCP_PI,
    MDBUS_RTU_RCRC
} modbus_if_t;

typedef struct
{
    uint8_t func_code;
    uint8_t size;
    uint16_t reg_addr;
    //
    //该poll相关联的tag
    uint32_t tag_sum;
    tag_t **p_tag;
    //
    int index;//在通道中的位置
} modbus_poll_info_t;

typedef dlt645_item dlt645_poll_info_t;

typedef ups_up_info_t ups_read_info_t;
typedef ups_down_info_t ups_write_info_t;
typedef struct
{
    int cmd_len;
    char *cmd;
} ups_poll_info_t;

typedef struct
{
    uint32_t head; // 标识:[0:modbus_write_reg_info_t, 1:modbus_read_reg_info_t
    uint8_t func_code;
    uint16_t reg_addr;
    DATA_TYPE data_type;
    DATA_ORDER data_order;
    int bit_st;   // u16中取bit位的位置
    int bit_len;  //
    int reversal; // 取反
} modbus_read_reg_info_t;

typedef struct
{
    uint32_t data_id;
    uint32_t index;
} dlt645_rw_info_t;


typedef struct
{
    char * iec104_ip;
    uint16_t iec104_port;
    uint16_t connected;

    void * last_device;  // for IEC104 read
    int last_ro_index;   // same as above, refer to `iec104_ASDUReceivedHandler
} iec104_proto;

typedef struct {
    uint32_t iec104_id;   // 0 for IEC104 总召唤, 1 for 发电度量召唤
} proto_iec104_poll;

typedef struct {
    int ioa_addr;
    int ioa_type;
} iec104_reg_info_t;

typedef struct
{
    uint32_t head; // 标识:[0:modbus_write_reg_info_t, 1:modbus_read_reg_info_t
    uint8_t func_code;
    uint16_t reg_addr;
    DATA_TYPE data_type;
    DATA_ORDER data_order;
} modbus_write_reg_info_t;

typedef struct
{
    modbus_if_t type; // modbus连接类型
    char *dev_or_ip;  // 串口设备文件名或者网络ip地址
    uint16_t port;    // 网络端口号
} modbus_proto;

typedef enum dlt645_if_t
{
    DLT645_UART = 0,
    DLT645_TCP
} dlt645_if_type_t;

typedef struct dlt645_proto_s
{
    dlt645_if_type_t type; // 连接类型
    char *dev_or_ip;       // 串口设备文件名或者网络ip地址
    uint16_t port;         // 网络端口号
} dlt645_proto_t;


typedef enum ups_if_t
{
    UPS_UART = 0,
    UPS_TCP
} ups_if_enum_t;
typedef struct ups_proto_s
{
    ups_if_enum_t type; // 连接类型
    char *dev_or_ip;       // 串口设备文件名或者网络ip地址
    uint16_t port;         // 网络端口号
} ups_proto_t;

typedef struct dlt645_dev_attr
{
    uint8_t bcd_addr[6];
} dlt645_dev_attr;

typedef struct bmser_dev_attr
{
    struct protocol
    {
        char str[ADDR_STR_LEN];
        uint32_t no;
    } addr;
    uint32_t online;
    uint64_t last_time;
} bmser_dev_attr;

//
typedef struct bmser_parser_info_t
{
    bmser_data_t type;
    uint32_t block_id;
    uint16_t sub_id;
    uint16_t bit_pos;
    uint16_t bit_len;
    uint8_t reverse; // 取反
    //
    int byte_index;//-1为无效
} bmser_parser_info_t;

typedef struct bmser_proto_s
{
    char *ip;       // 串口设备文件名或者网络ip地址
    uint16_t port;         // 网络端口号
} bmser_proto_s;

typedef struct bmser_poll_info_t
{
    uint32_t block_id;
    uint16_t sub_id;
    uint16_t sub_num;
    //该poll相关联的tag
    uint32_t tag_sum;
    tag_t **p_tag;
} bmser_poll_info_t;

//can
typedef struct can_proto_s
{
    char dev[32];
} can_proto_s;

typedef struct proto_can_poll proto_can_poll;
/* Raw data callback function types */
typedef void (*can_raw_send_cb_t)(proto_can_poll *poll, const uint8_t *data, int data_length, void *channel);
typedef void (*can_raw_receive_cb_t)(proto_can_poll *poll, const uint8_t *data, int data_length, void *channel);
typedef struct proto_can_poll
{
    uint32_t id;
    uint8_t dlc;           // 缓存帧的使用的长度，用于发送非8字节的can帧
    uint8_t loop_tx;       // 需要周期发送的poll
    union
    {
        uint64_t value_64;
        uint8_t buff[8];       
    }buff;
    int remote_len;        // 非负数为远程帧请求长度，-1为数据帧
    int (*fun)(proto_can_poll *p);//用于自定义解析
    //
    int tag_sum;
    tag_t **p_tag;
    /* Raw data callback functions */
    can_raw_send_cb_t raw_send_cb;
    void *raw_send_channel;
    can_raw_receive_cb_t raw_receive_cb;
    void *raw_receive_channel;
} proto_can_poll;

typedef struct can_parser_info_t
{
    uint32_t id;
    uint16_t byte_index;
    DATA_TYPE data_type;
    DATA_ORDER data_order;
    uint16_t bit_pos;
    uint16_t bit_len;
    uint8_t reverse; // 取反
    uint64_t data_mask;
    uint64_t data_target;
} can_parser_info_t;
//


typedef enum custom_if_t
{
    CUS_UART = 0,
    CUS_TCP
} custom_if_enum_t;

//custom
typedef struct custom_proto_t
{
    custom_if_enum_t type; // 连接类型
    char *dev_or_ip;       // 串口设备文件名或者网络ip地址
    uint16_t port;         // 网络端口号
} custom_proto_t;

typedef struct proto_custom_poll proto_custom_poll;
typedef struct proto_custom_poll
{
    uint32_t id;
    int len;               // 缓存帧的使用的长度
    uint8_t loop_tx;       // 需要周期发送的poll
    uint8_t buff[512];     // 用于缓存
    char *crc16_des;
	CRC16_TYPE crc16;
    int (*fun)(proto_custom_poll *p);//用于自定义解析
    //
    int tag_sum;
    tag_t **p_tag;
} proto_custom_poll;

typedef struct can_custom_info_t
{
    uint32_t id;
    uint16_t byte_index;
    DATA_TYPE data_type;
    DATA_ORDER data_order;
    uint16_t bit_pos;
    uint16_t bit_len;
    uint8_t reverse; // 取反
} custom_parser_info_t;


#define SOI 0x7E
#define EOI 0x0D

#define RTN_NORMAL 0x00
#define RTN_VER_ERR 0x01
#define RTN_CHKSUM_ERR 0x02
#define RTN_LCHKSUM_ERR 0x03
#define RTN_CID2_INVALID 0x04
#define RTN_CMD_FORMAT_ERR 0x05
#define RTN_INVALID_DATA 0x06

typedef struct 
{
    int code;
    char *des;
} ydt1363_code_des_t;

typedef struct 
{
    char *des;
    uint8_t exist;           // 0:不存在，1:存在
    int len;                 // 缓存帧的使用的长度
    uint8_t buff[2048];      // 缓存
} ydt1363_comman_info_item;

typedef enum command_info_t
{
    CUSTOM = 0,
    GROUP,
    ID,
    TYPE,
    TIME,
    DATAI,
    DATAF,
    ITEM_MAX
} command_info_enum_t;

typedef enum ydt1363_if_t
{
    YDT1363_UART = 0,
    YDT1363_TCP
} ydt1363_if_enum_t;

//ydt1363
typedef struct ydt1363_proto_t
{
    ydt1363_if_enum_t type; // 连接类型
    char *dev_or_ip;        // 串口设备文件名或者网络ip地址
    uint16_t port;          // 网络端口号
} ydt1363_proto_t;

typedef struct
{
    char *ver;
    uint32_t cid1;
    char *custom;
} ydt1363_user_def_t;

typedef struct proto_ydt1363_poll proto_ydt1363_poll;
typedef struct proto_ydt1363_poll
{
    uint32_t cid2;
    uint32_t len;            // 缓存帧的使用的长度
    uint8_t buff[4095 + 18]; // 用于缓存
    char *command_info;
    char *command_info_list[ITEM_MAX];
    int command_info_list_num;
	uint32_t val;
    uint32_t id;             // id=0 真正的周期性查询命令
    int (*fun)(proto_ydt1363_poll *p);  // 用于自定义解析
    ydt1363_comman_info_item item[ITEM_MAX];
    //
    int tag_sum;
    tag_t **p_tag;
} proto_ydt1363_poll;

typedef struct
{
    uint32_t cid2;
    uint16_t offset; // read: DATA INFO中的偏移量 ,write: 项中的偏移量
    DATA_TYPE data_type;
    DATA_ORDER data_order;
    int bit_st;      // u16中取bit位的位置
    int bit_len;     //
    int reversal;    // 取反
    char *item;      // tag所属COMMAND INFO项
    uint32_t id;     
} ydt1363_parser_info_t;

//
int extract_uart_par(char *info, uart_par_t *p_par);

modbus_t *modbus_proto_init(modbus_proto *if_info);
int modbus_proto_deinit(modbus_t *ctx);
int modbus_proto_read(modbus_t *ctx, uint8_t dev_addr, uint8_t fun_code, uint16_t reg_addr, uint16_t reg_sum, void *ack_buff);

dlt645_hd_t *dlt645_proto_init(dlt645_proto_t *if_info, dlt645_protocal_t dlt645_ver);
int dlt645_proto_deinit(dlt645_hd_t *hd);
int dlt645_proto_read(dlt645_hd_t *hd, uint8_t *bcd_addr,int (*get_raw_data)(char *data,int len,void *contex),void *contex, dlt645_poll_info_t *it, void *buff, uint32_t max_len);
int get_protocal_type(const char *c);


ups_hd_t *ups_proto_init(ups_proto_t *if_info);
custom_hd_t *custom_proto_init(custom_proto_t *if_info);
int custom_proto_deinit(custom_hd_t *hd);

ydt1363_hd_t *ydt1363_proto_init(ydt1363_proto_t *if_info);
int ydt1363_proto_deinit(ydt1363_hd_t *hd);
#endif
