#ifndef REWIND_H
#define REWIND_H

#include <stdint.h>
#include <netinet/in.h>

#ifdef __cplusplus
extern "C"
{
#endif

#pragma pack(push, 1)

#define REWIND_DEFAULT_PORT          54004
#define REWIND_KEEP_ALIVE_INTERVAL   2

#define REWIND_SIGN_LENGTH           8
#define REWIND_PROTOCOL_SIGN         "REWIND01"

#define REWIND_CLASS_REWIND_CONTROL  0x0000
#define REWIND_CLASS_SYSTEM_CONSOLE  0x0100
#define REWIND_CLASS_SERVER_NOTICE   0x0200
#define REWIND_CLASS_KAIROS_DATA     0x0800

#define REWIND_TYPE_KEEP_ALIVE       (REWIND_CLASS_REWIND_CONTROL + 0)
#define REWIND_TYPE_CLOSE            (REWIND_CLASS_REWIND_CONTROL + 1)
#define REWIND_TYPE_CHALLENGE        (REWIND_CLASS_REWIND_CONTROL + 2)
#define REWIND_TYPE_AUTHENTICATION   (REWIND_CLASS_REWIND_CONTROL + 3)

#define REWIND_TYPE_REPORT           (REWIND_CLASS_SYSTEM_CONSOLE + 0)

#define REWIND_TYPE_BUSY_NOTICE      (REWIND_CLASS_SERVER_NOTICE + 0)
#define REWIND_TYPE_ADDRESS_NOTICE   (REWIND_CLASS_SERVER_NOTICE + 1)

#define REWIND_TYPE_EXTERNAL_SERVER  (REWIND_CLASS_KAIROS_DATA + 0)
#define REWIND_TYPE_REMOTE_CONTROL   (REWIND_CLASS_KAIROS_DATA + 1)
#define REWIND_TYPE_SNMP_TRAP        (REWIND_CLASS_KAIROS_DATA + 2)

#define REWIND_FLAG_SLOT_1           (1 << 0)
#define REWIND_FLAG_SLOT_2           (1 << 1)

struct RewindVersionData
{
  uint32_t number;  // Agent ID
  char version[0];  // Software version
};

struct RewindAddressData
{
  struct in_addr address;
  uint16_t port;
};

struct RewindData
{
  char sign[REWIND_SIGN_LENGTH];
  uint16_t type;    // REWIND_TYPE_*
  uint16_t flags;   // REWIND_FLAG_*
  uint32_t number;  // Packet sequence number
  uint16_t length;  // Length of following data
  uint8_t data[0];  //
};

#pragma pack(pop)

#ifdef __cplusplus
}
#endif

#endif