#ifndef __SCADA_IEC104_H
#define __SCADA_IEC104_H

#include <string.h>
#include <syslog.h>
#include "ipc_session.h"
#include "lnxall_list.h"
#include "dy_utils/dy_common.h"
#include "dy_utils/dy_pp.h"
#include "dy_utils/dy_ipc.h"
#include "dy_utils/dy_ds.h"
#include "dy_utils/period_service.h"
#include "lib60870/cs104_connection.h"
#include "lib60870/hal_time.h"
#include "lib60870/hal_thread.h"

#define L1_SHIFT 12
#define L1_MASK ((1 << L1_SHIFT) - 1)
#define L1 (1 << L1_SHIFT)

#define L2_SHIFT 12
#define L2_MASK ((1 << L2_SHIFT) - 1)
#define L2 (1 << L2_SHIFT)

typedef struct _scada_iec104_var_s scada_iec104_var_t;
typedef enum
{
	TYPE_INT,
	TYPE_FLOAT,
	TYPE_SHORT,
	TYPE_BOOL,
} type_e;

typedef struct
{
	union
	{
		float val_float;
		short val_short;
		bool val_bool;
		int val_int;
	} val;
	type_e type;
	time_t update_ts;
} data_etnry_t;

typedef struct
{
	data_etnry_t *data;
	int cnt;
} L2_data_table_t;

typedef struct
{
	L2_data_table_t *L2_data[L1];
} L1_data_table_t;

typedef struct _connect_config_s
{
	struct list_head list;
	char socket_server_addr[32];
	int socket_server_port;
	CS104_Connection con;
	time_t last_send;
	time_t last_con;
	int connect_status;
	L1_data_table_t L1_data;
	scada_iec104_var_t *var;
} connect_config_t;

typedef struct
{
	struct list_head list;
	scada_iec104_var_t *var;
	char sn[SN_MAX_LEN]; ///<设备SN
	connect_config_t *connect_config;
} dev_node_t;

typedef struct _scada_iec104_var_s
{
	ipc_session_t *session;			//内部broker的MQTT session，用于进程间通信
	struct list_head connect_list;		// 连接
	struct list_head node_list;			// 节点
	nodes_cfg_table_t *nodes_cfg_table; //节点信息
	template_table_t *template_table;	//模板信息
	period_service_t *period;
	char sn_str[SN_MAX_LEN];
	char proc_name[PROGRAM_NAME_LEN];
	char gprs_no[16];
	int heartbeat_timer;
	int conn_cnt;
	int node_cnt;
    dev_status_table_t *ds; //下挂节点的状态信息
    time_t nodes_status_sync_date;
    int node_status_timer;
} scada_iec104_var_t;

typedef struct
{
	int addr;
	char id[32];
	double k;
} rglt_entry_t;

typedef struct
{
	int rglt_cnt;
	dev_node_t *node;
	bool cache_created;
	rglt_entry_t entry[0];
} rglt_table_t;

#endif
