#ifndef LIBTTN_HANDLE_H
#define LIBTTN_HANDLE_H

/****************************************************************************************************************/
//
// THIS FILE IS PRIVATE TO TTN.
//
// Included publicly to facilitate function inlining.
// Please behave. Having to wrap everything in a TTN_PRIVATE() macro like MbedTLS does is ugly.
//
/****************************************************************************************************************/

#define TTN_PROTOCOL_VERSION    1
#define TTN_PROTOCOL_REVISION   0
#define TTN_PROTOCOL_FEATURES   0

enum ttn_activity_state_t {
  TTN_ACTIVITY_OFFLINE,           // Bus is not up
  TTN_ACTIVITY_IDLE,              // Regular operation
  TTN_ACTIVITY_ITT,               // Token pass has been sent
  TTN_ACTIVITY_PACKET,            // PAC sent, waiting for ACK
  TTN_ACTIVITY_MAC_SENT,          // Probing for MAC addresses
  TTN_ACTIVITY_MAC_DETECTED,      // Probe registered some sort of response
  TTN_ACTIVITY_QUERY,             // Active properties probing
};

struct ttn_probe_state_t {
  uint8_t tps_bits_sent;
  uint8_t tps_bits;                                 // State when probing for MAC addresses
  uint8_t tps_probed_mac[6];                        // (Partial) MAC address currently being probed
  uint8_t tps_tries;                                // Retries when there is no response at all
  uint8_t tps_success;                              // The current probing round found at least one new friend
  uint64_t tps_collision;                           // Saw a collision at this bit
};

struct ttn_lnk_handle_t {
  struct ttn_lnk_device_t *ttn_device;              // Driver that transfers data on the TTN bus
  ttn_timerqueue_t *ttn_tmq;                        // Timer management

  enum ttn_lnk_state_t ttn_lnk_state;               // State machine
  enum ttn_activity_state_t ttn_activity_state;     // Current activity while online

  uint8_t ttn_myid;                                 // This station's own network ID
  uint8_t ttn_to_id;                                // The station ID that gets the token next
  uint8_t ttn_skipped;                              // Counts how many times the token did not arrive here
  uint8_t ttn_traffic_seen;                         // Receiver did see data
  uint8_t ttn_nid_tries;                            // How many unanswered attempts to pass the token where made
  uint8_t ttn_tx_busy_tries;                        // Number of tries to attempt a PAC transmit when receiver is busy
  uint8_t ttn_tx_fail_tries;                        // Number of tries to attempt a unanswered PAC transmit
  uint8_t ttn_probing_host;                         // The station that is doing the probing
  uint8_t ttn_tracelevel;                           // Packet level debug
  uint8_t ttn_last_rtr;
  uint8_t ttn_query_interval;                       // Reduce peer list update bandwidth use

  uint8_t ttn_mymac[6];                             // This station's own MAC address

  struct ttn_probe_state_t *ttn_probe;              // Used while probing for other stations

  struct list_head ttn_txq;                         // Transmit queue

  ttn_pkb_t *ttn_rxbuf;                             // Receive buffer
  ttn_pkb_t *ttn_rxbuf_next;                        // Next preallocated receive buffer

  struct list_head ttn_rxq;                         // Receive queue

  uint32_t ttn_bitspersecond;                       // Device speed

  uint32_t timeout_activity;                        // Time between packets seen on the bus
  uint32_t timeout_response;                        // Time until answer must be received
  uint32_t timeout_probe;                           // Time until answer to a probe must be received

  uint32_t ttn_txlen;                               // Bytes transmitted, for calculating response timeout

  ttn_bitmap_t ttn_seen_current;                    // Keeping track of which nodes are on the bus
  ttn_bitmap_t ttn_seen_track[3];

  ttn_bitmap_t ttn_rtr;                             // Keeping track of which nodes are ready to receive
  ttn_bitmap_t ttn_up;                              // Nodes that are considered up
  ttn_bitmap_t ttn_buzz;                            // Send a buzz over there if bit is set
  ttn_bitmap_t ttn_hasproperties;                   // Nodes that we have property data for

  ttn_timer_t ttn_timer_response;                   // Expecting a response
  ttn_timer_t ttn_timer_activity;                   // Detects silence on the bus
  ttn_timer_t ttn_timer_probe;                      // Probes for a new node

  void *ttn_data;                                   // User defined data pointer, i.e. owner

  void *ttn_allocator_data;                         // User defined data pointer for buffer allocator

  ttn_diag_event_cb_t *ttn_diag_cb;                 // Registered diagnostics handler
  void *ttn_diag_data;                              // User defined data pointer for diagnostics handler

  struct ttn_stats_t ttn_stats;                     // Statistics counter

  struct ttn_peer_properties_t ttn_peers[TTN_MAX_ID]; // Properties of all known peers

#define TTN_TEMPORARY_PEER_BUFFERS 5
  unsigned int ttn_temporary_peer_index;            // Keeping track of stations in the process of being assigned
  struct ttn_peer_properties_t ttn_temporary_peers[TTN_TEMPORARY_PEER_BUFFERS];
};

/****************************************************************************************************************/
#endif
