#ifndef LIP_OPCUA_UACP_PROTO_DEFS_H
#define LIP_OPCUA_UACP_PROTO_DEFS_H

/* OPC UA Connection Protocol  (10000-006, 7) */

#include "lip/lip_defs.h"


#define LIP_OPCUA_UACP_PROTOCOL_VERSION     0

#define LIP_OPCUA_MSGTYPE_UACP_HELLO         0x464C4548 /* Hello Message (HEL) */
#define LIP_OPCUA_MSGTYPE_UACP_ACK           0x464B4341 /* Acknowledge Message (ACK) */
#define LIP_OPCUA_MSGTYPE_UACP_ERROR         0x46525245 /* Error Message (ERR) */
#define LIP_OPCUA_MSGTYPE_UACP_REVHELLO      0x46454852 /* ReverseHello Message (RHE) */

#define LIP_OPCUA_MSGTYPE_UASC_OPEN          0x464E504F /* Open Secure Channel (OPN) */
#define LIP_OPCUA_MSGTYPE_UASC_CLO           0x464F4C43 /* Close Secure Channel (CLO) */
#define LIP_OPCUA_MSGTYPE_UASC_MSG           0x4647534D /* Secure Channel Message (MSG) */


#define LIP_OPCUA_CHUNKTYPE_FINAL


#define LIP_OPCUA_MSGCHUNK_MIN_LIMIT         8192 /**< Минимальный размер MessageChunk, который можно заявить */
#define LIP_OPCUA_MSGCHUNK_ECC_MIN_LIMIT     1024 /**< Минимальный размер MessageChunk, который можно заявить для ECC SecurityPolicy */
#define LIP_OPCUA_ENDPOINT_URL_MAX_SIZE      4096 /**< Максимально допустимая длина EndpointUrl */
#define LIP_OPCUA_ERRMSG_REASON_MAX_SIZE     4096 /**< Максимально допустимая длина описания ошибки */
#define LIP_OPCUA_HELLO_WAIT_MAX_TIME

typedef struct {
    int32_t Size;
    uint8_t Data[0];
} t_lip_opcua_string_hdr;


typedef struct {
    uint32_t MessageType; /**< Тип сообщения из LIP_OPCUA_MSGTYPE */
    uint32_t MessageSize; /**< Размер сообщения в байтах включая заголовок */
} t_lip_opcua_msg_hdr;


#define LIP_OPCUA_MSG_HDR_SIZE                  sizeof(t_lip_opcua_msg_hdr)

typedef struct {
    uint32_t ProtocolVersion;   /**< Версия протокола (текущая 0) */
    uint32_t ReceiveBufferSize; /**< Максимальный размер MessageChunk, который может принять (мин. 8192 или 1024 для ECC SecurityPolicy) */
    uint32_t SendBufferSize;    /**< Максимальный размер MessageChunk, который может передать (мин. 8192 или 1024 для ECC SecurityPolicy) */
    uint32_t MaxMessageSize;    /**< Максимальный размер ответного сообщения (0 - не ограничен) */
    uint32_t MaxChunkCount;     /**< Максимальное число частей в ответном сообщении (0 - не ограничено) */
    t_lip_opcua_string_hdr EndpointUrl;   /**< EndpointUrl */
} t_lip_opcua_uacp_msg_hello_data;

#define LIP_OPCUA_MSG_UACP_HELLO_MIN_SIZE       sizeof(t_lip_opcua_uacp_msg_hello_data)


typedef struct {
    uint32_t ProtocolVersion;   /**< Версия протокола (не выше версии в Hello) */
    uint32_t ReceiveBufferSize; /**< Максимальный размер MessageChunk, который может принять (не больше SendBufferSize из Hello) */
    uint32_t SendBufferSize;    /**< Максимальный размер MessageChunk, который может передать (не больше ReceiveBufferSize из Hello) */
    uint32_t MaxMessageSize;    /**< Максимальный размер ответного сообщения (0 - не ограничен) */
    uint32_t MaxChunkCount;     /**< Максимальное число частей в ответном сообщении (0 - не ограничено) */
} t_lip_opcua_uacp_msg_ack_data;

typedef struct {
    t_lip_opcua_msg_hdr hdr;
    t_lip_opcua_uacp_msg_ack_data data;
} t_lip_opcua_uacp_msg_ack;



typedef struct {
    uint32_t Error;   /**< Код ошибки */
    t_lip_opcua_string_hdr Reason;   /**< Описание причины ошибки */
} t_lip_opcua_uacp_msg_err_data;

typedef struct {
    t_lip_opcua_msg_hdr hdr;
    t_lip_opcua_uacp_msg_err_data data;
} t_lip_opcua_uacp_msg_err;




#endif // LIP_OPCUA_UACP_PROTO_DEFS_H
