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

#ifndef __OPC_FIP_TYPES_H__
#define __OPC_FIP_TYPES_H__

#include <open62541/server.h>

#define OPC_FIPSTATS_DT_MEMBERS_MAX 14
typedef struct {
    /**
     * TX counters
     */
    /* physical layer (PHY) */
    UA_UInt64 TxFrameOkCount;
    UA_UInt64 TxFrameCollisionErrCount;
    UA_UInt64 TxFrameConsistencyErrCount;
    /* application layer (APP) */
    UA_UInt64 TxVarNotFreshErrCount;
    /**
     * RX counters
     */
    /* physical layer (PHY) */
    UA_UInt64 RxFrameOkCount;
    UA_UInt64 RxPreambleMissingErrCount;
    UA_UInt64 RxFrameStartDelimiterMissingErrCount;
    UA_UInt64 RxFrameStartDelimiterUnknownErrCount;
    UA_UInt64 RxFrameEndDelimiterMissingErrCount;
    /* data-link layer (DL) */
    UA_UInt64 RxCrcBadErrCount;
    /* application layer (APP) */
    UA_UInt64 RxVarPduBadErrCount;
    UA_UInt64 RxVarLengthBadErrCount;
    UA_UInt64 RxVarNotFreshErrCount;
    UA_UInt64 RxVarNotPromptErrCount;
} FipStatisticsSummary;

static UA_DataTypeMember FipStatisticsSummary_members[OPC_FIPSTATS_DT_MEMBERS_MAX] = {
    /* TxFrameOkCount */
    {
        UA_TYPENAME("TxFrameOkCount")   /* .memberName */
        &UA_TYPES[UA_TYPES_UINT64],     /* .memberType */
        0,                              /* .padding */
        false,                          /* .isArray */
        false                           /* .isOptional */
    },
    /* TxFrameCollisionErrCount */
    {
        UA_TYPENAME("TxFrameCollisionErrCount")
        &UA_TYPES[UA_TYPES_UINT64],
        offsetof(FipStatisticsSummary,TxFrameCollisionErrCount) - \
        offsetof(FipStatisticsSummary,TxFrameOkCount) - \
        sizeof(UA_UInt64),
        false,
        false
    },
    /* TxFrameConsistencyErrCount */
    {
        UA_TYPENAME("TxFrameConsistencyErrCount")
        &UA_TYPES[UA_TYPES_UINT64],
        offsetof(FipStatisticsSummary,TxFrameConsistencyErrCount) - \
        offsetof(FipStatisticsSummary,TxFrameCollisionErrCount) - \
        sizeof(UA_UInt64),
        false,
        false
    },
    /* TxVarNotFreshErrCount */
    {
        UA_TYPENAME("TxVarNotFreshErrCount")
        &UA_TYPES[UA_TYPES_UINT64],
        offsetof(FipStatisticsSummary,TxVarNotFreshErrCount) - \
        offsetof(FipStatisticsSummary,TxFrameConsistencyErrCount) - \
        sizeof(UA_UInt64),
        false,
        false
    },
    /* RxFrameOkCount */
    {
        UA_TYPENAME("RxFrameOkCount")
        &UA_TYPES[UA_TYPES_UINT64],
        offsetof(FipStatisticsSummary,RxFrameOkCount) - \
        offsetof(FipStatisticsSummary,TxVarNotFreshErrCount) - \
        sizeof(UA_UInt64),
        false,
        false
    },
    /* RxPreambleMissingErrCount */
    {
        UA_TYPENAME("RxPreambleMissingErrCount")
        &UA_TYPES[UA_TYPES_UINT64],
        offsetof(FipStatisticsSummary,RxPreambleMissingErrCount) - \
        offsetof(FipStatisticsSummary,RxFrameOkCount) - \
        sizeof(UA_UInt64),
        false,
        false
    },
    /* RxFrameStartDelimiterMissingErrCount */
    {
        UA_TYPENAME("RxFrameStartDelimiterMissingErrCount")
        &UA_TYPES[UA_TYPES_UINT64],
        offsetof(FipStatisticsSummary,RxFrameStartDelimiterMissingErrCount) - \
        offsetof(FipStatisticsSummary,RxPreambleMissingErrCount) - \
        sizeof(UA_UInt64),
        false,
        false
    },
    /* RxFrameStartDelimiterUnknownErrCount */
    {
        UA_TYPENAME("RxFrameStartDelimiterUnknownErrCount")
        &UA_TYPES[UA_TYPES_UINT64],
        offsetof(FipStatisticsSummary,RxFrameStartDelimiterUnknownErrCount) - \
        offsetof(FipStatisticsSummary,RxFrameStartDelimiterMissingErrCount) - \
        sizeof(UA_UInt64),
        false,
        false
    },
    /* RxFrameEndDelimiterMissingErrCount */
    {
        UA_TYPENAME("RxFrameEndDelimiterMissingErrCount")
        &UA_TYPES[UA_TYPES_UINT64],
        offsetof(FipStatisticsSummary,RxFrameEndDelimiterMissingErrCount) - \
        offsetof(FipStatisticsSummary,RxFrameStartDelimiterUnknownErrCount) - \
        sizeof(UA_UInt64),
        false,
        false
    },
    /* RxCrcBadErrCount */
    {
        UA_TYPENAME("RxCrcBadErrCount")
        &UA_TYPES[UA_TYPES_UINT64],
        offsetof(FipStatisticsSummary,RxCrcBadErrCount) - \
        offsetof(FipStatisticsSummary,RxFrameEndDelimiterMissingErrCount) - \
        sizeof(UA_UInt64),
        false,
        false
    },
    /* RxVarPduBadErrCount */
    {
        UA_TYPENAME("RxVarPduBadErrCount")
        &UA_TYPES[UA_TYPES_UINT64],
        offsetof(FipStatisticsSummary,RxVarPduBadErrCount) - \
        offsetof(FipStatisticsSummary,RxCrcBadErrCount) - \
        sizeof(UA_UInt64),
        false,
        false
    },
    /* RxVarLengthBadErrCount */
    {
        UA_TYPENAME("RxVarLengthBadErrCount")
        &UA_TYPES[UA_TYPES_UINT64],
        offsetof(FipStatisticsSummary,RxVarLengthBadErrCount) - \
        offsetof(FipStatisticsSummary,RxVarPduBadErrCount) - \
        sizeof(UA_UInt64),
        false,
        false
    },
    /* RxVarNotFreshErrCount */
    {
        UA_TYPENAME("RxVarNotFreshErrCount")
        &UA_TYPES[UA_TYPES_UINT64],
        offsetof(FipStatisticsSummary,RxVarNotFreshErrCount) - \
        offsetof(FipStatisticsSummary,RxVarLengthBadErrCount) - \
        sizeof(UA_UInt64),
        false,
        false
    },
    /* RxVarNotPromptErrCount */
    {
        UA_TYPENAME("RxVarNotPromptErrCount")
        &UA_TYPES[UA_TYPES_UINT64],
        offsetof(FipStatisticsSummary,RxVarNotPromptErrCount) - \
        offsetof(FipStatisticsSummary,RxVarNotFreshErrCount) - \
        sizeof(UA_UInt64),
        false,
        false
    }
};

static const UA_DataType FipStatisticsSummaryType = {
    UA_TYPENAME("FipStatisticsSummary")     /* .typeName */
    {1, UA_NODEIDTYPE_NUMERIC, {4242}},     /* .typeId */
    {1, UA_NODEIDTYPE_NUMERIC, {1}},        /* .binaryEncodingId */
    sizeof(FipStatisticsSummary),           /* .memSize */
    UA_DATATYPEKIND_STRUCTURE,              /* .typeKind */
    true,                                   /* .pointerFree */
    false,                                  /* .overlayable */
    OPC_FIPSTATS_DT_MEMBERS_MAX,            /* .membersSize */
    FipStatisticsSummary_members            /* .members */
};

void opc_fip_types_init(UA_Server *srv);

#endif
