/*
 * Created by jiaqiang.ye@lnxall.com
 *
 * OPC UA Server for LNXALL devices
 *
 * 2022/01/07
 */

#ifndef OPCUA_LNXALL_H
#define OPCUA_LNXALL_H 1

#include <open62541.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
 * OPC UA LNXALL property entry
 */
struct oulnx_property {
    void *                  prop_cfg;        /* point to `object_property_cfg_t */
    char *                  prop_path;       /* absolute path for the property, used as OPC UA node-id */
    UA_NodeId               prop_nid;        /* OPC UA node-id for the property */
#if 0
    union {
        double              prop_dval;
        int32_t             prop_i32;
        uint32_t            prop_u32;
        int64_t             prop_i64;
        uint64_t            prop_u64;
        char *              prop_str;
    } opdata;                                /* current value for the property */
#endif
};
typedef struct oulnx_property oulnx_prop_t;

/**
 * OPC UA device template node
 */
struct oulnx_device {
    void *                  dev_cfg;         /* point to `node_cfg_t */
    void *                  prop_tab;        /* point to `object_property_table_t */
    char *                  dev_path;        /* absolute path for the properties, (dynamically allocated) */
    UA_NodeId               dev_nid;         /* OPC UA node-id for the device */
    uint32_t                prop_num;        /* maximum number of properties avaliable in `props */
    oulnx_prop_t *          props;           /* dynamically allocated properties array */
};
typedef struct oulnx_device oulnx_dev_t;

#define OPCUA_USERPW_MAX    64
/**
 * OPC UA Server for LNXALL devices
 */
struct oulnx_server {
    UA_Server *             ua_server;       /* OPC UA server pointer */
    void *                  node_ctab;       /* point to nodes_cfg_table_t */
    void *                  object_ctab;     /* point to object_table_t */
    void *                  session;         /* IPC session for MQTT connection */
    uint32_t                dev_num;         /* maximum number of devices from `nodes_cfg.json */
    oulnx_dev_t *           pdev;            /* dynamically allocated devices array */
    char                    userName[OPCUA_USERPW_MAX]; /* OPC UA Server access username */
    char                    userPass[OPCUA_USERPW_MAX]; /* OPC UA Server access password */
    UA_UsernamePasswordLogin pw_login;       /* OPCUA login structure */
    char                    board_sn[64];    /* board serial number */
};
typedef struct oulnx_server oulnx_server_t;

oulnx_server_t * oulnx_server_init(UA_Server * uas);

int oulnx_server_load(oulnx_server_t * ous,
    const char * pdir, UA_ServerConfig * ua_scfg);

void oulnx_server_free(oulnx_server_t * ous);

#ifdef __cplusplus
}
#endif
#endif
