/* Copyright (c) 2023 SCANLAB GmbH */

#ifndef REMOTE_INTERFACE_TELEGRAMS_H_
#define REMOTE_INTERFACE_TELEGRAMS_H_

#include <stdint.h>
#include <stddef.h>
#include <stdlib.h>

#ifndef UINT_MAX
    #define UINT_MAX 4294967295U
#endif

namespace remote_interface
{

#pragma pack(push, 1)

// ----------------------------------------------------------------------------
// Telegram Header
// ----------------------------------------------------------------------------

static constexpr uint32_t TGM_VERSION = 0x01000000; // 1.0.0.0
static constexpr size_t TGM_MAX_SIZE = 1400;        // < Ethernet MTU (1500 bytes)

static constexpr uint32_t LAST_ERROR_TGM_ERROR = UINT32_C(1) << 31; // last error related to Remote Interface only, query specific error code with get_remote_error

enum TGM_ERROR
{
    ERROR_NO_ERROR = 0,
    ERROR_TGM_SIZE = 1 << 0,               // received telegram size <= sizeof(TGM_HEADER) or > TGM_MAX_SIZE
    ERROR_HEADER_VERSION = 1 << 1,         // invalid version in telegram header
    ERROR_HEADER_LENGTH = 1 << 2,          // header length != received size - sizeof(TGM_HEADER)
    ERROR_HEADER_TYPE = 1 << 3,            // invalid type (should always be COMMAND for incoming telegrams, other types are set by card for answer telegrams)
    ERROR_HEADER_FORMAT = 1 << 4,          // header format doesn't match with the one configured via eth_set_remote_tgm_format
    ERROR_PAYLOAD_UNKNOWN_CMD_ID = 1 << 5, // no command matches given command id
    ERROR_PAYLOAD_INVALID = 1 << 6         // invalid payload, e.g. more than one control command or a mix of control and list commands
};

enum class TGM_TYPE : uint32_t
{
    COMMAND = 0,
    ANSWER = 1,

    INVALID = UINT_MAX
};

enum class TGM_FORMAT : uint32_t
{
    NONE = 0,
    RAW = 1,

    INVALID = UINT_MAX
};

struct TGM_HEADER
{
    uint32_t length;
    uint32_t version;
    uint32_t seqnum;
    TGM_TYPE type;
    TGM_FORMAT format;
};

// ----------------------------------------------------------------------------
// Telegram Payloads
// ----------------------------------------------------------------------------

struct TGM_PL_CMD_RAW
{
    // Can consist of multiple commands in following form:
    // uint32_t CmdID_0, uint32_t* CmdBuffer_0,
    // ...,
    // uint32_t CmdID_n, uint32_t* CmdBuffer_n
    uint32_t buffer[(TGM_MAX_SIZE - sizeof(TGM_HEADER)) / sizeof(uint32_t)];
};

struct TGM_PL_ANSW_RAW
{
    // Can consist of multiple answers in following form:
    // uint32_t LastError_0, uint32_t CmdID_0, uint32_t* AnswerBuffer_0,
    // ...,
    // uint32_t LastError_n, uint32_t CmdID_n, uint32_t* AnswerBuffer_n
    uint32_t buffer[(TGM_MAX_SIZE - sizeof(TGM_HEADER)) / sizeof(uint32_t)];
};

// ----------------------------------------------------------------------------
// Telegrams
// ----------------------------------------------------------------------------

struct TGM_CMD_RAW
{
    TGM_HEADER header;
    TGM_PL_CMD_RAW payload;
};

struct TGM_ANSW_RAW
{
    TGM_HEADER header;
    TGM_PL_ANSW_RAW payload;
};

// ----------------------------------------------------------------------------
// Remote command IDs
// ----------------------------------------------------------------------------

enum REMOTE_ID
{
    R_DC_NO_COMMAND = 0,
    R_DC_CONFIG_LIST = 1,
    R_DC_GET_CONFIG_LIST = 2,
    R_DC_SET_START_LIST_POS = 3,
    R_DC_GET_INPUT_POINTER = 4,
    R_DC_GET_LIST_SPACE = 5,
    R_DC_LOAD_LIST_POS = 6,
    R_DC_LOAD_SUB = 7,
    R_DC_LOAD_CHAR = 8,
    R_DC_LOAD_TEXT_TABLE = 9,
    R_DC_SET_EXTSTART_POS = 10,
    R_DC_SET_MAX_COUNT = 11,
    R_DC_GET_COUNTS = 12,
    R_DC_STORE_TIMESTAMP = 13,
    R_DC_SIMULATE_EXT_START = 14,
    R_DC_EXECUTE_LIST_POS = 15,
    R_DC_STOP_EXECUTION = 16,
    R_DC_SIMULATE_EXT_STOP = 17,
    R_DC_EXTERN_START_DELAY = 18,
    R_DC_AUTO_CHANGE_POS = 19,
    R_DC_START_LOOP = 20,
    R_DC_QUIT_LOOP = 21,
    R_DC_PAUSE_LIST = 22,
    R_DC_RESTART_LIST = 23,
    R_DC_RELEASE_WAIT = 24,
    R_DC_GET_WAIT_STATUS = 25,
    R_DC_SET_PAUSE_LIST_COND = 26,
    R_DC_GET_TIME = 27,
    R_DC_GET_LAP_TIME = 28,
    R_DC_SET_CONTROL_MODE = 29,
    R_DC_READ_STATUS = 30,
    R_DC_GET_STATUS = 31,
    R_DC_GET_STARTSTOP_INFO = 32,
    R_DC_GET_OVERRUN = 33,
    R_DC_CONTROL_COMMAND = 34,
    R_DC_GET_VALUE = 35,
    R_DC_GET_VALUES = 36,
    R_DC_GET_HEAD_STATUS = 37,
    R_DC_GET_HEAD_PARA = 38,
    R_DC_GET_TABLE_PARA = 39,
    R_DC_GET_Z_DISTANCE = 40,
    R_DC_GET_GALVO_CONTROLS = 41,
    R_DC_SET_LASER_CONTROL = 42,
    R_DC_SET_LASER_MODE = 43,
    R_DC_ENABLE_LASER = 44,
    R_DC_DISABLE_LASER = 45,
    R_DC_LASER_SIGNAL_ON = 46,
    R_DC_LASER_SIGNAL_OFF = 47,
    R_DC_SET_QSWITCH_DELAY = 48,
    R_DC_SET_LASER_TIMING = 49,
    R_DC_SET_FIRST_PULSE_KILLER = 50,
    R_DC_SET_LASER_PIN_OUT = 51,
    R_DC_GET_LASER_PIN_IN = 52,
    R_DC_SET_STANDBY_TIMING = 53,
    R_DC_GET_STANDBY = 54,
    R_DC_PULSE_PICKING = 55,
    R_DC_PULSE_PICKING_LENGTH = 56,
    R_DC_CONFIG_LASER_SIGNALS = 57,
    R_DC_SET_AUTO_LASER_CONTROL = 58,
    R_DC_SET_AUTO_LASER_PARAMS = 59,
    R_DC_SPOT_DISTANCE = 60,
    R_DC_SET_ENCODER_SPEED = 61,
    R_DC_SET_DEFAULT_PIXEL = 62,
    R_DC_SET_PORT_DEFAULT = 63,
    R_DC_WRITE_8BIT_PORT = 64,
    R_DC_WRITE_IO_PORT_MASK = 65,
    R_DC_GET_IO_STATUS = 66,
    R_DC_READ_IO_PORT = 67,
    R_DC_READ_IO_PORT_BUF = 68,
    R_DC_WRITE_DA_X = 69,
    R_DC_READ_ANALOG_IN = 70,
    R_DC_SET_JUMP_SPEED = 71,
    R_DC_SET_MARK_SPEED = 72,
    R_DC_SET_DEFOCUS = 73,
    R_DC_SET_DEFOCUS_OFFSET = 74,
    R_DC_SET_DELAY_MODE = 75,
    R_DC_GOTO_XYZ = 76,
    R_DC_SET_OFFSET_XYZ = 77,
    R_DC_HOME_POSITION_XYZ = 78,
    R_DC_TIME_UPDATE = 79,
    R_DC_TIME_CONTROL_ETH = 80,
    R_DC_SET_SERIAL = 81,
    R_DC_SELECT_SERIAL_SET = 82,
    R_DC_GET_SERIAL = 83,
    R_DC_GET_LIST_SERIAL = 84,
    R_DC_SET_ZOOM = 85,
    R_DC_SET_MATRIX = 86,
    R_DC_SET_ANGLE = 87,
    R_DC_SET_SCALE = 88,
    R_DC_SIMULATE_ENCODER = 89,
    R_DC_READ_ENCODER = 90,
    R_DC_GET_ENCODER = 91,
    R_DC_INIT_FLY_2D = 92,
    R_DC_GET_FLY_2D_OFFSET = 93,
    R_DC_GET_MARKING_INFO = 94,
    R_DC_ROT_CENTER = 95,
    R_DC_SET_MCBSP_FREQ = 96,
    R_DC_MCBSP_INIT = 97,
    R_DC_SET_MCBSP_MODE = 98,
    R_DC_SET_MCBSP_MODE_GLOBAL = 99,
    R_DC_SET_MCBSP_IN = 100,
    R_DC_SET_MULTI_MCBSP_IN = 101,
    R_DC_READ_MCBSP = 102,
    R_DC_READ_MULTI_MCBSP = 103,
    R_DC_APPLY_MCBSP = 104,
    R_DC_GET_SCANAHEAD_PARAMS = 105,
    R_DC_SCANAHEAD_ACTIVATE_AUTO = 106,
    R_DC_SET_SCANAHEAD_LASER_SHIFT = 107,
    R_DC_SET_SCANAHEAD_LINE_PARAMS = 108,
    R_DC_SET_SCANAHEAD_PARAMS = 109,
    R_DC_SET_SCANAHEAD_SPEED_CTRL = 110,
    R_DC_STEPPER_INIT = 111,
    R_DC_STEPPER_ENABLE = 112,
    R_DC_STEPPER_DISABLE_SWITCH = 113,
    R_DC_STEPPER_CTRL = 114,
    R_DC_STEPPER_NO_ABS = 115,
    R_DC_STEPPER_NO_REL = 116,
    R_DC_STEPPER_ABS = 117,
    R_DC_STEPPER_REL = 118,
    R_DC_GET_STEPPER_STATUS = 119,
    R_DC_SET_SKY_WRITING_PARA = 120,
    R_DC_SET_SKY_WRITING_ANGLE = 121,
    R_DC_SET_SKY_WRITING_MODE = 122,
    R_DC_UART_CONFIG = 123,
    R_DC_RS232_WRITE_DATA = 124,
    R_DC_RS232_WRITE_TEXT = 125,
    R_DC_RS232_READ_DATA = 126,
    R_DC_BOUNCE_SUPP = 127,
    R_DC_SET_HI = 128,
    R_DC_SET_JUMP_MODE = 129,
    R_DC_SELECT_COR_TABLE = 130,
    R_DC_SET_FREE_VAR = 131,
    R_DC_GET_FREE_VAR = 132,
    R_DC_SET_MCBSP_OUT_PTR = 133,
    R_DC_PERIODIC_TOGGLE = 134,
    R_DC_ENDURING_WOBBEL_1 = 135,
    R_DC_ENDURING_WOBBEL_2 = 136,
    R_DC_STOP_TRIGGER = 137,
    R_DC_MEASUREMENT_STATUS = 138,
    R_DC_GET_WAVEFORM = 139,
    R_DC_SET_VERIFY = 140,
    R_DC_GET_HEX_VERSION = 141,
    R_DC_GET_RTC_VERSION = 142,
    R_DC_GET_BIOS_VERSION = 143,
    R_DC_GET_SERIAL_NUMBER = 144,
    R_DC_SET_INPUT_POINTER = 145,
    R_DC_GET_LIST_POINTER = 146,
    R_DC_EXECUTE_AT_POINTER = 147,
    R_DC_GET_REMOTE_ERROR = 148,
    R_DC_SET_LASER_PULSE_SYNC = 149,
    R_DC_GET_TIMESTAMP_LONG = 150,
    R_DC_CLEAR_FLY_OVERFLOW = 151,
    R_DC_GET_TEMPERATURE = 152,
    R_DC_SET_MCBSP_OUT_OIE = 153,
    R_DC_LOAD_CORRECTION_FILE = 154,
    R_DC_NUMBER_OF_COR_TABLES = 155,
    R_DC_LOAD_Z_TABLE = 156,
    R_DC_LOAD_OCT_TABLE = 157,
    R_DC_SET_TIMELAG_COMPENSATION = 158,
    R_DC_SET_ENCODER_FILTER = 159,
    R_DC_GET_MASTER_SLAVE = 160,
    R_DC_GET_SYNC_STATUS = 161,
    R_DC_MASTER_SLAVE_CONFIG = 162,
    R_DC_GET_STATIC_IP = 163,
    R_DC_SET_STATIC_IP = 164,
    R_DC_GET_PORT_NUMBERS = 165,
    R_DC_SET_PORT_NUMBERS = 166,
    R_DC_CONFIGURE_LINK_LOSS = 167,
    R_DC_SET_SKY_WRITING_MIN_SPEED = 168,
    R_DC_SET_CTRL_PREVIEW_COMP = 169,
    R_DC_SET_FLY_TRACKING_ERROR = 170,
    R_DC_SET_LASER_DELAYS = 171,
    R_DC_SET_SCANNER_DELAYS = 172,
    R_DC_SET_SKY_WRITING_SCALE = 173,
    R_DC_GET_EXTENDED_HEAD_STATUS_VALUE = 174,
    R_DC_GET_EXTENDED_HEAD_STATUS_BLOCK = 175,
    R_DC_GET_RCM_VALUE = 176,
    R_DC_MASTER_SLAVE_SET_OFFSET = 177,
    R_DC_MARKING_INFO_ACK = 178,
    R_DC_SET_SL2_100_ERROR_TOLERANCE = 179,
    R_DC_GET_SL2_100_ERROR_TOLERANCE = 180,
    R_DC_SET_SL2_100_ERROR_TOLERANCE_ENABLE = 181,
    R_DC_GET_SL2_100_ERROR_TOLERANCE_ENABLE = 182,
    R_DC_SET_EXPLICIT_ACK_MODE = 183,
    R_DC_STARTSTOP_INFO_ACK = 184,
    R_DC_GET_HARDWARE_REVISION = 185,

    R_LC_NO_COMMAND = 256,
    R_LC_CONTINUE = 257,
    R_LC_NEXT = 258,
    R_LC_END_OF_LIST = 259,
    R_LC_LIST_RETURN = 260,
    R_LC_REPEAT = 261,
    R_LC_UNTIL = 262,
    R_LC_LIST_JUMP_POS = 263,
    R_LC_LIST_JUMP_REL = 264,
    R_LC_SET_WAIT = 265,
    R_LC_LONG_DELAY = 266,
    R_LC_SET_EXTSTART_POS = 267,
    R_LC_SIMULATE_EXTERN_START = 268,
    R_LC_LIST_CALL = 269,
    R_LC_SUB_CALL = 270,
    R_LC_IF_COND = 271,
    R_LC_IF_PIN_COND = 272,
    R_LC_CLEAR_IO_COND = 273,
    R_LC_SET_IO_COND = 274,
    R_LC_SWITCH_IOPORT = 275,
    R_LC_LIST_CALL_COND = 276,
    R_LC_SUB_CALL_COND = 277,
    R_LC_LIST_JUMP_POS_COND = 278,
    R_LC_LIST_JUMP_REL_COND = 279,
    R_LC_CONFIG_LASER_SIGNALS = 280,
    R_LC_LASER_SIGNAL_ON = 281,
    R_LC_LASER_SIGNAL_OFF = 282,
    R_LC_SET_LASER_TIMING = 283,
    R_LC_SET_FIRST_PULSE_KILLER = 284,
    R_LC_SET_QSWITCH_DELAY = 285,
    R_LC_SET_LASER_PIN_OUT = 286,
    R_LC_PULSE_PICKING = 287,
    R_LC_SET_STANDBY_TIMING = 288,
    R_LC_SET_AUTO_LASER_PARAMS = 289,
    R_LC_LASER_POWER = 290,
    R_LC_SPOT_DISTANCE = 291,
    R_LC_SET_ENCODER_SPEED = 292,
    R_LC_SET_DEFAULT_PIXEL = 293,
    R_LC_SET_PORT_DEFAULT = 294,
    R_LC_SET_PIXEL_LINE = 295,
    R_LC_SET_N_PIXEL_DATA = 296,
    R_LC_WRITE_8BIT_PORT = 297,
    R_LC_WRITE_IO_PORT_MASK = 298,
    R_LC_READ_IO_PORT = 299,
    R_LC_WRITE_DA_X = 300,
    R_LC_SET_MARK_SPEED = 301,
    R_LC_SET_JUMP_SPEED = 302,
    R_LC_SET_SCANNER_DELAYS = 303,
    R_LC_SET_LASER_DELAYS = 304,
    R_LC_SET_DEFOCUS = 305,
    R_LC_SET_DEFOCUS_OFFSET = 306,
    R_LC_SET_ZOOM = 307,
    R_LC_SET_OFFSET_XYZ = 308,
    R_LC_SET_MATRIX = 309,
    R_LC_SET_ANGLE = 310,
    R_LC_SET_SCALE = 311,
    R_LC_MARK_XYZT_ABS = 312,
    R_LC_MARK_XYZT_REL = 313,
    R_LC_ARC_XYAT_ABS = 314,
    R_LC_ARC_XYAT_REL = 315,
    R_LC_ARC_XYZA_ABS = 316,
    R_LC_ARC_XYZA_REL = 317,
    R_LC_SET_ELLIPSE = 318,
    R_LC_ELLIPSE_ABS = 319,
    R_LC_ELLIPSE_REL = 320,
    R_LC_JUMP_XY_ABS = 321,
    R_LC_JUMP_XY_REL = 322,
    R_LC_JUMP_XYZT_ABS = 323,
    R_LC_JUMP_XYZT_REL = 324,
    R_LC_JUMP_XY_DRILL_ABS = 325,
    R_LC_JUMP_XY_DRILL_REL = 326,
    R_LC_SET_VECTOR_CONTROL = 327,
    R_LC_LASER_ON_PULSES_PARA = 328,
    R_LC_MARK_XYZP_ABS = 329,
    R_LC_MARK_XYZP_REL = 330,
    R_LC_MARK_XYZPT_ABS = 331,
    R_LC_MARK_XYZPT_REL = 332,
    R_LC_JUMP_XYZP_ABS = 333,
    R_LC_JUMP_XYZP_REL = 334,
    R_LC_JUMP_XYZPT_ABS = 335,
    R_LC_JUMP_XYZPT_REL = 336,
    R_LC_MICRO_VECTOR_ABS_3D = 337,
    R_LC_MICRO_VECTOR_REL_3D = 338,
    R_LC_MARK_CHAR = 339,
    R_LC_SELECT_CHAR_SET = 340,
    R_LC_MARK_TEXT = 341,
    R_LC_MARK_SERIAL = 342,
    R_LC_SET_SERIAL = 343,
    R_LC_SELECT_SERIAL_SET = 344,
    R_LC_TIME_FIX_F_OFF = 345,
    R_LC_MARK_DATE = 346,
    R_LC_MARK_TIME = 347,
    R_LC_SET_WOBBEL_MODE_PHASE = 348,
    R_LC_SET_WOBBEL_MODE = 349,
    R_LC_SET_WOBBEL_DIR = 350,
    R_LC_SET_WOBBEL_CONTROL = 351,
    R_LC_SET_WOBBEL_VECTOR = 352,
    R_LC_SET_WOBBEL_OFFSET = 353,
    R_LC_SET_SKY_WRITING_PARA = 354,
    R_LC_SET_SKY_WRITING_ANGLE = 355,
    R_LC_SET_SKY_WRITING_MODE = 356,
    R_LC_SET_CONTROL_MODE = 357,
    R_LC_STORE_ENCODER = 358,
    R_LC_START_TIMER = 359,
    R_LC_STORE_TIMESTAMP = 360,
    R_LC_WAIT_FOR_TIMESTAMP = 361,
    R_LC_SET_TRIGGER = 362,
    R_LC_EXTERN_START_DELAY = 363,
    R_LC_SET_FLY = 364,
    R_LC_ROT_CENTER = 365,
    R_LC_SET_FLY_2D = 366,
    R_LC_FLY_RETURN_Z = 367,
    R_LC_SET_FLY_LIMITS = 368,
    R_LC_SET_FLY_LIMITS_Z = 369,
    R_LC_IF_FLY_OVERFLOW = 370,
    R_LC_IF_NOT_FLY_OVERFLOW = 371,
    R_LC_CLEAR_FLY_OVERFLOW = 372,
    R_LC_PARK_POSITION = 373,
    R_LC_PARK_RETURN = 374,
    R_LC_ACTIVATE_FLY_ENC_XY = 375,
    R_LC_ACTIVATE_FLY_ENC_2D = 376,
    R_LC_WAIT_FOR_ENCODER_MODE = 377,
    R_LC_WAIT_FOR_ENCODER_RANGE = 378,
    R_LC_IF_NOT_ACTIVATED = 379,
    R_LC_RANGE_CHECKING = 380,
    R_LC_SET_FLY_POS = 381,
    R_LC_WAIT_FOR_MCBSP = 382,
    R_LC_SET_MCBSP_IN = 383,
    R_LC_SET_MULTI_MCBSP_IN = 384,
    R_LC_SET_MCBSP_MODE = 385,
    R_LC_APPLY_MCBSP = 386,
    R_LC_SET_MCBSP_MODE_GLOBAL = 387,
    R_LC_SET_FLY_1 = 388,
    R_LC_FLY_RETURN_1 = 389,
    R_LC_WAIT_FOR_1 = 390,
    R_LC_ACTIVATE_FLY_1 = 391,
    R_LC_PARK_POSITION_1 = 392,
    R_LC_PARK_RETURN_1 = 393,
    R_LC_SET_FLY_2 = 394,
    R_LC_FLY_RETURN_2 = 395,
    R_LC_WAIT_FOR_2 = 396,
    R_LC_ACTIVATE_FLY_2 = 397,
    R_LC_PARK_POSITION_2 = 398,
    R_LC_PARK_RETURN_2 = 399,
    R_LC_SET_FLY_3 = 400,
    R_LC_FLY_RETURN_3 = 401,
    R_LC_RS232_WRITE_TEXT = 402,
    R_LC_SET_MCBSP_OUT = 403,
    R_LC_PERIODIC_TOGGLE = 404,
    R_LC_SET_FREE_VAR = 405,
    R_LC_SELECT_COR_TABLE = 406,
    R_LC_SET_DELAY_MODE = 407,
    R_LC_SCANAHEAD_ACTIVATE_AUTO = 408,
    R_LC_SET_SCANAHEAD_LASER_SHIFT = 409,
    R_LC_SET_SCANAHEAD_LINE_PARAMS = 410,
    R_LC_STEPPER_ENABLE = 411,
    R_LC_STEPPER_CTRL = 412,
    R_LC_STEPPER_NO_ABS = 413,
    R_LC_STEPPER_NO_REL = 414,
    R_LC_STEPPER_ABS = 415,
    R_LC_STEPPER_REL = 416,
    R_LC_STEPPER_WAIT = 417,
    R_LC_CAMMING = 418,
    R_LC_SET_JUMP_MODE = 419,
    R_LC_ENDURING_WOBBEL = 420,
    R_LC_FLY_PREDICTION = 421,
    R_LC_WAIT_FOR_TIMESTAMP_LONG = 422,
    R_LC_SET_TRIGGER_8 = 423,
    R_LC_SET_WOBBEL_VECTOR_2 = 424,
    R_LC_SET_MCBSP_OUT_PTR = 425,
    R_LC_SET_MCBSP_OUT_OIE = 426,
    R_LC_WRITE_PORT = 427,
    R_LC_FLY_DISABLE = 428,
    R_LC_INIT_FLY_2D = 429,
    R_LC_SET_DEFOCUS_2 = 430,
    R_LC_SET_SKY_WRITING_MIN_SPEED = 431,
    R_LC_SET_SKY_WRITING_SCALE = 432,
    R_LC_WRITE_IO_PORT_MASK_EX = 433,
    R_LC_TIMED_APPLY_MCBSP = 434,
    //  reserved
    R_LC_ACTIVATE_FLY = R_LC_NO_COMMAND + 252,
    R_LC_IF_NOT_COND = R_LC_NO_COMMAND + 253,
    R_LC_IF_NOT_PIN_COND
};

#pragma pack(pop)

}

#endif /* REMOTE_INTERFACE_TELEGRAMS_H_ */
