/*
 * @Author: ybzhou yibo.zhou@lnxall.com
 * @Date: 2025-05-26 15:15:18
 * @LastEditors: ybzhou yibo.zhou@lnxall.com
 * @LastEditTime: 2025-06-26 14:38:11
 * @FilePath: /my_ota_v2/proto_forward/src/ota_upgrade/interface.h
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#ifndef __INTERFACE_H__
#define __INTERFACE_H__
#include <stdint.h>
#include <time.h>

#include "../tag.h"

typedef enum type_if_t
{
    OTA_NONE = 0,
    OTA_RS485,
    OTA_CAN,
    OTA_SOCKET_TCP,
    OTA_SOCKET_UDP,
    OTA_MAX
} type_if_t;

typedef struct
{
    char channel[CHANNEL_NAME_SIZE];
    type_if_t type;   // ota连接类型
    char *dev_or_ip;  // 串口名或者网络ip地址/CAN口名
    uint16_t port;    // 网络端口号
} ota_inter_t;

typedef struct ota_hd_t ota_hd_t;
typedef struct ota_if
{
    int (*ota_connect)(ota_hd_t *hd);
    int (*ota_tx)(ota_hd_t *hd, void *buff, uint32_t len);
    int (*ota_rx)(ota_hd_t *hd, void *buff, uint32_t max_len);
    int (*ota_flush)(ota_hd_t *hd);
    int (*ota_dis_connect)(ota_hd_t *hd);
    int (*ota_free)(ota_hd_t *hd);
} ota_if_t;

typedef enum {
    INTERFACE_UART = 0,
    INTERFACE_TCP,
    INTERFACE_UDP,
    INTERFACE_CAN,
    INTERFACE_MAX,
} INTERFACE_TYPE;

struct ota_hd_t
{
    char name[32];
    int fd;
    int error_recovery;
    const ota_if_t *if_funs;
    void *data;
    INTERFACE_TYPE type; // 接口类型
    int effect_fd;       // 通道fd是否有效
    int    same;
    uint32_t read_time_out;
    uint32_t interval;
    int32_t frame_gap;
    uint64_t lastread;
};

ota_hd_t *new_ota_tcp(channel_t* chan_pr, char *ip_or_dev, uint16_t port);
ota_hd_t *new_ota_udp(channel_t* chan_pr, char *ip_or_dev, uint16_t port);
ota_hd_t *new_ota_uart(channel_t* chan_pr, char *dev, int baud, uint8_t data_bit, uint8_t stop_bit, char parity);
ota_hd_t *new_ota_can(channel_t* chan_pr, char *dev);

int ota_connect(ota_hd_t *hd);
int ota_dis_connect(ota_hd_t *hd);
int ota_free(ota_hd_t *hd);
int ota_write(ota_hd_t *hd, void *tx_buff, int tx_len, void *rx_buff, int max_len);
int ota_set_time(ota_hd_t *hd, uint32_t timeout_ms, uint32_t interval);
int ota_set_single_time(ota_hd_t *hd, uint32_t timeout_ms);
int ota_set_name(ota_hd_t *hd, char *new_name);

ota_hd_t *register_ota_interface(char* dev_no, channel_t* chan_pr, device_t* dev_pr);
void ota_deinit(ota_hd_t *hd);

#endif
