#ifndef __MODBUS_TCP_H__
#define __MODBUS_TCP_H__
#include "ccu_config.h"
#include "msystem.h"
#include "goose_HW.h"
#include "libinetsocket.h"
#include <openssl/ssl.h>
#include <openssl/err.h>

typedef struct MBPA
{
    uint16_t transaction_identifier;
    uint16_t protocol_identifier;
    uint16_t length_field;
    uint8_t unit_id;
}MBPA_t;

typedef struct PDU
{
    uint8_t function_code;
    uint16_t reg_addr;
    uint16_t reg_value;
}PDU_t;

typedef struct report_reg
{
    uint16_t reg_addr;
    uint16_t reg_numbs;
    uint16_t reg_value[0];
}report_reg_t;

typedef struct report_dev
{
    uint16_t dev_addr;
    uint16_t reg_segmts;
    report_reg_t report_regs[0];
}report_dev_t;

typedef struct modbus_TCP
{
    pthread_mutex_t mutex;
    int enable_ssl;
    char connect_ip_string[64];
    char connect_port[16];
    int fd;

    int quit;

    SSL_CTX *ctx;
    SSL *ssl;
    
    //----------------

    uint8_t  rx_buff[1024];
    int rx_bytes;
    uint8_t  tx_buff[1024];
    int tx_bytes;

    uint8_t  xx_buff[1024];
    int xx_bytes;

    uint16_t trans_ids[2];
    uint16_t seqnumb;

    //----------------
    uint16_t regs_0x0000[0x2B];
    uint16_t regs_0x0100[0x2B];

    //----------------
    uint16_t regs_0x1000[0x26];
    uint16_t regs_0x1100[0xA0];
    uint16_t regs_0x1D00[0xA0];

    uint16_t regs_0x2000[0x17];
    uint16_t regs_0x2100[0x30];
    uint16_t regs_0x2D00[0x30];

    //----------------
    uint16_t regs_0x3000[0x05];
    uint16_t regs_0x3100[0x30];
    uint16_t regs_0x3D00[0x30];

    uint16_t regs_0x4000[0x100];

    goose_HW_t  gooseA;
    goose_HW_t  gooseB;
}modbusTCP_HW_t;

typedef enum HWWorkMode
{
    HW_WORK_MODE_PLUGIN_HOME = 0,
    HW_WORK_MODE_PLUGIN_EV,
    HW_WORK_MODE_RESV1,
    HW_WORK_MODE_CHARGING,
    HW_WORK_MODE_FINISHING,
    HW_WORK_MODE_FAULTED,
    HW_WORK_MODE_RESV2,
    HW_WORK_MODE_UPGRATE,
    HW_WORK_MODE_PRECHARGING,
    HW_WORK_MODE_RESV3,
    HW_WORK_MODE_RESV4,
    HW_WORK_MODE_RESV5,
    HW_WORK_MODE_DISABLE,
}HWWorkMode_t;

typedef enum HWLinkState
{
    HW_UNLINK_STATE = 0,
    HW_SEMILINK_STATE,
    HW_FULLLINK_STATE
}HWLinkState_t;

int modbusTCP_HW_init(modbusTCP_HW_t* dev);

void* modbusTCP_HW_loop(void* argv);

void modbusTCP_HW_exit(modbusTCP_HW_t* dev);

int modbusTCP_HW_report_registers(modbusTCP_HW_t* dev, uint16_t regaddr, uint16_t* regvalue, int N);

#endif//__MODBUS_TCP_H__
