/*
 * Created by jiaqiang.ye@lnxall.com
 *
 * IEC104 Server/Slave
 *
 * 2022/03/02
 */

#ifndef LNXALL_IEC104_H
#define LNXALL_IEC104_H 1

#include <dy_pp.h>
#include <ipc_session.h>
#include <stdint.h>
#include <pthread.h>

#ifdef __cplusplus
extern "C" {
#endif

union iec104_data {
    int32_t         val_int32;
    uint32_t        val_uint32;
    float           val_float;
};

struct iec104_point {
    const object_property_cfg_t * prop; /* corresponding property structure */
    union iec104_data pointd;           /* IEC104 point data */
    unsigned int changed;               /* mark the data as changed */
} __attribute__((aligned(4)));

#define IEC104_DEVSN_LEN 64
struct iec104_points {
    char devsn[IEC104_DEVSN_LEN];
    uint64_t changed_time;         /* mark the time in milliseconds when the group data has changed */
    uint64_t updated_time;         /* mark the time in milliseconds when the changed data has been reported */
    int iec104_offset;             /* IEC104 data base-offset */
    int report_period;             /* unit second */
    int last_period;               /* last periodic report in seconds, boot-time */
    int report_change;             /* automatic report if data has changed */
    unsigned int numpoints;        /* number of IEC-104 points in the group */
    struct iec104_point points[0];
};

struct iec104_var {
    nodes_cfg_table_t * nodecfg;
    template_table_t * tempcfg;
    object_table_t * objcfg;
    ipc_session_t * ipcsess;
    unsigned int numgroup;
    pthread_cond_t thread_cond;
    pthread_mutex_t thread_lock;
    struct iec104_points * * iec104_group;
};

struct iec104_var * iec104_server_init(void);

void iec104_server_free(struct iec104_var * ivar);

unsigned int iec104_uptime(unsigned int * secp,
    unsigned int * nsecp);

uint64_t iec104_upmsec(uint64_t * msecp);

#ifdef __cplusplus
}
#endif
#endif
