/** 
* @file      virtual_gw_common.h 
* @brief     description common for virtual gateway run in docker
* @details  e.g. broker address, user_name, password .etc
* @author   zhaoxianpeng@zjdyiot.com
* @date     2019.09.04
* @version  A001 
* @par Copyright (c):  
*       DYIOT
* @par History:          
*   version: draft\n 
*/
#ifndef __VINT_COMMON_H
#define __VINT_COMMON_H

/***************HEADER FILES****************/
#include <string.h>
#include <syslog.h>
#include "mqtt_session.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 "dy_utils/period_service.h"
/******************************************/

#define VINT_NODE_STATUS_BAK_FILE "/app/vint_node_status.bak"

#define CONNECT_CHECK_INTERVAL 3 //网络连接检查间隔，秒为单位
#define NORETURN 0
#define ERR_PARSE_DATA 1
#define NOT_BELONG_TO_US 2
#define RETURN_ACK 3

#define TOPIC_EVT_LOGIN "Evt_LogIn"
#define TOPIC_EVT_PRD_DATA "Evt_Prd_Data"
#define TOPIC_DATA_REPORT "Data_Report"
#define TOPIC_DATA_HISTORY "Data_History"
#define TOPIC_ACK "ACK"
#define TOPIC_RSP_GETTAGCFGTABLE "Rsp_GetTagCfgTable"
#define TOPIC_GET_RTC "Get_RTC"
#define TOPIC_RSP_GETGWDEVLINKCFGTABLE "Rsp_GetGWDevLinkCfgTable"
#define TOPIC_RSP_SETGWDEVLINKCFGTABLE "Rsp_SetGWDevLinkCfgTable"
#define TOPIC_RSP_GETGWPARA "Rsp_GetGWPara"
#define TOPIC_RSP_SETGWPARA "Rsp_SetGWPara"
#define UTC_AT_2000_01_01_00_00_00 946684800 // 2000年1月1日 00:00:00的UTC时间戳

typedef struct _payload_data_hdr_s
{
    char source[8];
    char sn[SN_MAX_LEN];
    char cmd[32];
    unsigned int mi;
    char *data;
    int len;
    unsigned char need_free;
} payload_data_hdr_t;

typedef enum _SERVICE_TYPE_E
{
    VGW_MQTT = 0,
    VGW_TCP,
    VGW_UDP,
} SERVICE_TYPE_E;

typedef struct _vint_var_s
{
    mqtt_session_t* session_ext;         //外部broker的MQTT client，用于从外部订阅数据
    ipc_session_t* session_int;         //内部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];
    kv_array_t identifier_backup;
    dev_status_table_t *ds; //下挂节点的状态信息
    int node_status_timer;
    int period_poll_timer;
    time_t nodes_status_sync_date;
    period_service_t *period;
} vint_var_t;

typedef struct mqtt_payload_s
{
    uint16_t mi;
    uint32_t UTC;
    uint8_t payload[0];
} __attribute__((packed, aligned(1))) mqtt_payload_t;

#define IOT_BYTE_ORDER LITTLE_ENDIAN

typedef struct evt_prd_data_s
{
#if IOT_BYTE_ORDER == LITTLE_ENDIAN
    uint16_t start_addr : 6,
        instruction_code : 2,
        term_addr : 8;
#elif IOT_BYTE_ORDER == BIG_ENDIAN
    uint16_t term_addr : 8,
        instruction_code : 2,
        start_addr : 6;
#else
#error "Please fix byte order"
#endif
    uint8_t length;
    uint8_t value[0];
} __attribute__((packed, aligned(1))) evt_prd_data_t;

typedef struct data_report_s
{
#if IOT_BYTE_ORDER == LITTLE_ENDIAN
    uint16_t start_addr;
    uint8_t instruction_code : 4,
        term_addr : 4;
#elif IOT_BYTE_ORDER == BIG_ENDIAN
    uint8_t term_addr : 4,
        instruction_code : 4;
    uint16_t start_addr;
#else
#error "Please fix byte order"
#endif
    uint8_t length;
    uint8_t value[0];
} __attribute__((packed, aligned(1))) data_report_t;
#define MAX_TLV_COUNT 10

typedef struct mqtt_data_out_node_s
{
    struct list_head list;
    mqtt_message_t mqtt_msg;
} mqtt_data_out_node_t;

extern int vint_external_client_init(vint_var_t *var, char *filename);
extern int vint_internal_client_init(vint_var_t *var);
extern int vint_external_mqtt_connect_timer(vint_var_t *var);
extern int vint_internal_mqtt_connect_timer(vint_var_t *var);
extern int vint_external_mqtt_handle_recv_msg(void *obj, mqtt_message_t *mqtt_msg);
extern int vint_send_mqtt_data(vint_var_t *var, mqtt_message_t *mqtt_msg);
extern int handle_dyiot_tcp_data(vint_var_t *var, uint8_t *buf, int len, payload_data_hdr_t *phdr);
extern int handle_unmanned_ship_tcp_data(vint_var_t *var, uint8_t *buf, int len, payload_data_hdr_t *phdr);
extern int handle_puyu_tcp_data(vint_var_t *var, uint8_t *buf, int len, payload_data_hdr_t *phdr);
extern int handle_csi_dt_tcp_data(vint_var_t *var, uint8_t *buf, int len, payload_data_hdr_t *phdr);
extern int vint_tcp_gen_common_ack(vint_var_t *var, payload_data_hdr_t *phdr, char *buf, int ret);
extern int vint_handle_mqtt_from_front_msg(vint_var_t *var, mqtt_message_t *mqtt_msg);
extern int vint_send_mqtt_data_to_front(vint_var_t *var, pp_regulate_signal_t *regulate_data);
extern int vint_send_tcp_data_to_front(vint_var_t *var, pp_regulate_signal_t *regulate_data);
extern int handle_new_rtu_data(vint_var_t *var, mqtt_message_t *mqtt_msg);
extern int vint_send_data_to_rtu(vint_var_t *var, pp_regulate_signal_t *regulate_data);
extern void vint_in_subscribe_all(vint_var_t *var);
extern int vint_send_rglt_data(vint_var_t *var, pp_regulate_signal_t *regulate_data);
extern int vint_send_mqtt_data_lnxall_dtu(vint_var_t *var, pp_regulate_signal_t *regulate_data);
extern int handle_lnxall_dtu(vint_var_t *var, mqtt_message_t *mqtt_msg, node_cfg_t *node);

#endif /* __RS485_COMMON_H */
