#ifndef LIBTTN_STRUCT_H
#define LIBTTN_STRUCT_H
/****************************************************************************************************************/
//
// This must be includable stand alone
// Used by Core4 application layer code that has no access to in-kernel includes
//

#ifdef _CORE4_
#include <core/types.h>
#else
#include <stdint.h>
#endif

#include <stdbool.h>
#include <stddef.h>

/****************************************************************************************************************/

#define TTN_MAX_ID             31

// An integer that can hold enough bits to have one bit for each possible TID
typedef uint32_t ttn_bitmap_t;

/****************************************************************************************************************/

enum ttn_lnk_state_t {
  TTN_STATE_STOP,                 // Inactive
  TTN_STATE_RESET,                // Starting over, waiting for bus idle
  TTN_STATE_RECON,                // Waiting the identifier precedence timeout
  TTN_STATE_ENUM,                 // Probing for at least one other station
  TTN_STATE_ONLINE,               // Token is orbiting
};

/****************************************************************************************************************/

struct ttn_state_t {
  enum ttn_lnk_state_t tif_state;
  unsigned int tif_tid;
  unsigned int tif_next_tid;
  unsigned int tif_probe_tid;
};

/****************************************************************************************************************/

enum ttn_diag_event_type_t {
  ttnDiagStateChange,
  ttnDiagPopulationReport,
  ttnDiagProbing,
  ttnDiagBeingProbed,
  ttnDiagBeingAssigned,
  ttnDiagProbingHost,
  ttnDiagTraffic,
  ttnDiagBuzzed,
};

// This structure must be copyable (through a FreeRTOS queue)
struct ttn_diag_event_t {
  enum ttn_diag_event_type_t ev;

  union {
    // ttnDiagStateChange
    struct {
      enum ttn_lnk_state_t state;
      bool online;
    } state_change;

    // ttnDiagPopulationReport
    struct {
      ttn_bitmap_t before;
      ttn_bitmap_t after;
      } census;

    // ttnDiagProbing
    // ttnDiagBeingProbed
    struct {
      uint8_t bits;
      uint8_t mac[6];
    } probe;

    // ttnDiagBeingAssigned
    struct {
      uint8_t tid;
      uint8_t next_tid;
      uint8_t from_tid;
      uint8_t from_mac[6];
    } assign;

    // ttnDiagProbingHost
    struct {
      uint8_t tid;
    } probing_host;

    // ttnDiagBuzzed
    struct {
      uint8_t tid;
    } buzzed;

    // ttnDiagTraffic
    struct {
      uint8_t sid;
      uint8_t did;
    } traffic;

  };
};

/****************************************************************************************************************/

struct ttn_peer_properties_t {
  uint8_t tmm_mac[6];
  uint8_t tmm_assigned:1;
  uint8_t tmm_valid:1;
  uint8_t tmm_version;
  uint8_t tmm_revision;
  uint32_t tmm_features;
};

/****************************************************************************************************************/

struct ttn_stats_t {
  unsigned int stat_tx_tokens_sent;                 // Increments each time an ITT is transmitted
  unsigned int stat_tx_tokens_retries;              // Number of tokens retransmitted because there was no reaction

  unsigned int stat_bus_resets;                     // Number of bus resets due to an error
  unsigned int stat_device_lost;                    // Counts when a device drops out of the list of active duty

  unsigned int stat_assignments_made;               // Number of times this stations assigned a TID to another
  unsigned int stat_probes_answered;                // Number of times a bus probe has been answered

  unsigned int stat_tx_pac_total;                   // Total number of PACs queued for transmit
  unsigned int stat_tx_pac_retries_busy;            // Number of times a PAC was held back because target RTR was false.
  unsigned int stat_tx_pac_retries_nak;             // Number of PACs retransmitted because target responded with NAK.
  unsigned int stat_tx_pac_retries_timeout;         // Number of PACs retransmitted because target did not respond.
  unsigned int stat_tx_pac_dropped;                 // Number of PACs dropped

  unsigned int stat_rx_pac_seen;                    // Total number of PACs seen, regardless of destination address
  unsigned int stat_rx_pac_received_total;          // Total number of PACs received
  unsigned int stat_rx_pac_received_unicast;        // Total number of PACs received targeted at this station
  unsigned int stat_rx_pac_received_broadcast;      // Total number of broadcast PACs received
  unsigned int stat_rx_pac_dropped_nomem;           // Received packets dropped because there are no buffers
};

/****************************************************************************************************************/

#endif
