/**
* @file      rs485_slave_common.h
* @brief     description about rs485 slave
* @details  e.g. 485 slave port config
* @author   liang.ji@lnxall.com
* @date     2021.10.17
* @version  A001
* @par Copyright (c):
*       DYIOT
* @par History:
*   version: draft\n
*/
#ifndef __RS485_SLAVE_COMMON_H
#define __RS485_SLAVE_COMMON_H

/***************HEADER FILES****************/
#include <string.h>
#include <syslog.h>

#include "modbus/modbus.h"
#include "ipc_session.h"
#include "mqtt_session.h"
#include "dy_utils/dy_common.h"
#include "dy_utils/dy_pp.h"
/******************************************/

/******************MACRO********************/
#if defined(X86_GATEWAY)
#define TTYMXC_CNT 4
#else
#define TTYMXC_CNT 4
#endif
#define MQTT_SERVER_TOPIC_FILE "/app/config/mqtt_server_topic.json"
/******************************************/

/*************ENUM*************************/
/******************************************/

/*******************STRUCTURE**************/
/**
 *  rs485 slave per port config descriptor
 */
typedef struct rs485_slave_port_cfg_s
{
    const char *dev;          ///</dev/ttymxc[1,2,3,4]
    gw_port_e port;           ///<0, 1, 2, 3
    int speed;                ///<9600, 115200
    int stop;                 ///<1 ~ 2
    int parity;               ///<0, 1, 2
    int bits;                 ///<7, 8
    int protocol;             ///<3-GW_PROTC_MODBUS, 2-DYWL_RS485_V1
    bool disable;
} rs485_slave_port_cfg_t;

/**
 *  rs485 slave ports config with mi descriptor
 */
typedef struct rs485_slave_ports_cfg_s
{
    int mi;                                      ///< message cookie
    rs485_slave_port_cfg_t rs485_slave_port_cfg[TTYMXC_CNT]; ///< ports config
} rs485_slave_ports_cfg_t;

typedef struct mqtt_server_topic_s
{
    char addr[MAX_HOST_LEN];
    unsigned short port;
    char user[MAX_USER_LEN];
    char pass[MAX_PASS_LEN];
    unsigned char qos;
    int keepalive;
    char topic[TOPIC_MAX_LEN];
} mqtt_server_topic_t;

typedef struct rs485_slave_var_s
{
    char sn_str[SN_MAX_LEN];
    const char *board_name;
    rs485_slave_ports_cfg_t rs485_slave_ports_cfg;
    object_table_t *object_table; //物模型信息
    mqtt_server_topic_t mqtt_server_topic;
    int poll_timer;
} rs485_slave_var_t;

typedef struct rs485_slave_service_property_s
{
    int pre_len;
    int cur_cnt;
    int cur_len;
    int *p_byte;
    int *p_offset;
} rs485_slave_service_property_t;

typedef struct rs485_slave_services_property_s
{
    int total_len;
    int services_count;
    rs485_slave_service_property_t *service_property;
} rs485_slave_services_property_t;

typedef struct rs485_slave_thread_s
{
    rs485_slave_var_t *var;
    rs485_slave_port_cfg_t *rs485_slave_port_cfg;
    int rs485_slave_port;
    ipc_session_t *session; //内部broker的MQTT client，用于进程间通信

    modbus_t *ctx;
    modbus_mapping_t *map;
    rs485_slave_services_property_t services_property;

    pthread_mutex_t regs_lock;
} rs485_slave_thread_t;
/******************************************/

/******************FUNCTION****************/
void rs485_slave_load_config(rs485_slave_var_t *var);
int rs485_slave_start_thread(rs485_slave_var_t *var, rs485_slave_port_cfg_t *rs485_slave_port_cfg, int rs485_slave_port);

const char *get_tty_from_port(gw_port_e port);
int rs485_slave_port_map(int rs485_slave_port);
/******************************************/
#endif /* __RS485_SLAVE_COMMON_H */
