/**
 * @file      modbus_tcp_comm.h
 * @brief     description about modbus_tcp
 * @details  e.g. 485 port config, period polling
 * @author   wangleilei@zjdyiot.com
 * @date     2019.06.20
 * @version  A001
 * @par Copyright (c):
 *       DYIOT
 * @par History:
 *   version: draft\n
 */
#ifndef __MODBUS_TCP_COMMON_H
#define __MODBUS_TCP_COMMON_H

/***************HEADER FILES****************/
#include <string.h>
#include <syslog.h>
#include "ipc_session.h"
#include "lnxall_list.h"
#include "dy_utils/dy_common.h"
#include "dy_utils/dy_ds.h"
#include "dy_utils/kv_array.h"
#include "dy_utils/dy_ipc.h"
#include "modbus/modbus.h"
#include "lnxall_ubuslog.h"
/******************************************/

/*******************MACRO***********************/
#define MODBUS_TCP_COMMUNICATION_TIMEOUT 200 // unit:ms
#define MODBUS_TCP_NODE_STATUS_BAK_FILE "/app/modbus_tcp_status.bak"
/******************************************/

/*******************STRUCTURE**************/
typedef struct modbus_tcp_thread_s modbus_tcp_thread_t;
typedef struct modbus_tcp_var_s modbus_tcp_var_t;

typedef struct tcp_node_s
{
    struct list_head list;
    node_cfg_t *node_cfg;
    modbus_tcp_thread_t *tcp_thread;
} tcp_node_t;

typedef struct modbus_tcp_data_list_s
{
    struct list_head list;
    pp_regulate_signal_t rs;
    long long last_send;
} modbus_tcp_data_list_t;

typedef struct modbus_tcp_thread_s
{
    ipc_session_t *session; //内部broker的MQTT client，用于进程间通信

    struct list_head list;
    struct list_head data_list;
    struct list_head node_list;

    pthread_mutex_t data_lock;

    unsigned char start_flag;
    unsigned char period_flag;
    int send_timer;
    int period_timer;
    bool period_triggered;

    modbus_t *ctx;
    char tcp_ip_addr[64]; ///< modbus TCP IP
    int tcp_port;         ///< modbus TCP PORT
    unsigned int communication_timeout;
    uint64_t send_cnt;
    uint64_t recv_cnt;

    int try_cnt; /* THE CODE IS PURE SHIT */
    modbus_tcp_var_t *var;
} modbus_tcp_thread_var_t;

typedef struct modbus_tcp_var_s
{
    ipc_session_t *session;             //内部broker的MQTT client，用于进程间通信
    nodes_cfg_table_t *nodes_cfg_table; //节点信息
    template_table_t *template_table;   //模板信息
    char sn_str[SN_MAX_LEN];
    char proc_name[PROGRAM_NAME_LEN];
    struct list_head tcp_thread_list;
    dev_status_table_t *ds; //下挂节点的状态信息
    time_t nodes_status_sync_date;
    int node_status_timer;
} modbus_tcp_var_t;
/******************************************/

/******************FUNCTION****************/
int modbus_tcp_client_init(modbus_tcp_thread_var_t *thread_var, pthread_mutex_t * * mutexpp);
int modbus_tcp_start_thread(modbus_tcp_var_t *var, modbus_tcp_thread_var_t *thread_var);
void modbus_freetcp(const char * ipaddr, int portno, modbus_t * mctx);
/******************************************/

#endif /* __MODBUS_TCP_COMMON_H */
