/*
 * Copyright (C) 2022 EXOLIGENT (www.exoligent.com)
 * Author: Maxime Coroyer <maxime.coroyer@exoligent.com>
 */

#ifndef __OPC_H__
#define __OPC_H__

#include <open62541/server.h>

#define OPC_TRANSPORT_PROFILE "http://opcfoundation.org/UA-Profile/Transport/pubsub-eth-uadp"
#define OPC_PUB_NAME "Publisher Connection [UADP]"
#define OPC_SUB_NAME "Subscriber Connection [UADP]"
#define OPC_READER_GROUP_NAME "RG - ReaderGroup 1"
#define OPC_WRITER_GROUP_NAME "WG - WriterGroup 1"
#define OPC_DATASET_READER_NAME "DSR - DataSetReader 1"
#define OPC_DATASET_WRITER_NAME "DSW - DataSetWriter 1"

struct opc_data {
    /* extra config fields */
    char name[255];
    uint16_t fip_id;
    UA_NodeId v_node_id;   /* opc node id attached to fip variable (var.data)
                            * note: used to attached fip data to a pub/sub
                            * dataset
                            */
    UA_ByteString data;     /* info model data */
#if defined OPC_ENABLE_REALTIME_CAP
    UA_DataValue *rt_value; /* realtime data value */
    UA_ByteString rt_data;  /* backend data */
#endif
};

#define OPC_STR_BSZ_MAX 255
struct opc_publisher {
    char net_str[OPC_STR_BSZ_MAX]; /* network interface */
    char url_str[OPC_STR_BSZ_MAX]; /* url */
    int publisher_id;
    int dataset_writer_id;
    int writer_group_id;
    int publish_period_us;
    /* objects */
    UA_NetworkAddressUrlDataType url;
    UA_NodeId co_ident;
    UA_NodeId w_group_id;
    struct opc_data data; /* useful app data container for ping/pong */
    int active;
};

struct opc_subscriber {
    char net_str[OPC_STR_BSZ_MAX]; /* network interface */
    char url_str[OPC_STR_BSZ_MAX]; /* url */
    int publisher_id;
    int dataset_writer_id;
    int writer_group_id;
    /* objects */
    UA_NetworkAddressUrlDataType url;
    UA_NodeId co_ident;
    UA_NodeId r_group_id;
    struct opc_data data; /* useful app data container for ping/pong */
};

struct opc {
    UA_Server *srv;
    UA_ServerConfig *cfg;
    UA_Boolean running;
    UA_StatusCode status;
    UA_Lock mu;
    /**
     * OPC UA Pub/Sub
     */
    /* publisher */
    struct opc_publisher pub;
    /* subscriber */
    struct opc_subscriber sub;
    pthread_t pubsub_thr_task;
    /**
     * Thread
     */
    pthread_t thr_task;
};

#endif
