#ifndef LIBTTN_TTNFREERTOS_H
#define LIBTTN_TTNFREERTOS_H

#include <stdint.h>
#include <stdarg.h>
#include <string.h>

#include "tools/lists.h"

#include "app/timer.h"
#include "app/log.h"

#include "FreeRTOS/FreeRTOS.h"

#ifdef __cplusplus
extern "C" {
#endif

/****************************************************************************************************************/
// Shamelessly assume the machinery is little endian.
// If it isn't, fix below.

#define ttn_bswap16(x) __builtin_bswap16(x)
#define ttn_bswap32(x) __builtin_bswap32(x)

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

typedef struct ttn_pkb_t {
  void *pkb_nbdptr;
  struct list_head pkb_list;
  uint32_t pkb_lsize;                                   /* Size of link layer data                              */
  uint8_t *pkb_link;
} ttn_pkb_t;

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

typedef struct timer      ttn_timer_t;
typedef struct timerqueue ttn_timerqueue_t;

static inline void ttn_glue_timer_init(ttn_timerqueue_t *tq, ttn_timer_t *tmr, ttn_timerfunc_t *func, void *data) {
  timer_init(tmr, tq, (timercallback_t *)func, data);
}

static inline void ttn_glue_timer_close(ttn_timer_t *tmr) {
  timer_stop(tmr);
}

static inline void ttn_glue_timer_stop(ttn_timer_t *tmr) {
  timer_stop(tmr);
}

static inline void ttn_glue_timer_start_single(ttn_timer_t *tmr, unsigned int ms) {
  timer_set(tmr, ms, TIMER_SINGLE_SHOT);
}

static inline void ttn_glue_timer_start_periodic(ttn_timer_t *tmr, unsigned int ms) {
  timer_set(tmr, ms, TIMER_FREE_RUNNING);
}

static inline uint32_t ttn_glue_getnow_ms(void) {
  return xTaskGetTickCount();
}

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

#include "tools/crc.h"

static inline unsigned int ttn_glue_crc16(const void *data, size_t len) {
  return crc16_buf(data, len, 0xFFFF);
}

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

#include "tlsf/tlsf-tmalloc.h"

#define ttn_glue_malloc tmalloc
#define ttn_glue_free   tfree

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

struct ttn_interface_t;
struct TCPIP_InterfaceOperations;

void ttn_srv_start(void);
struct ttn_interface_t *ttn_srv_add_tty(unsigned int nr);

const struct TCPIP_InterfaceOperations *ttn_srv_bridge_init(int ttynr, const struct TCPIP_InterfaceOperations *ethops);

struct ttn_lnk_handle_t *ttn_bridge_get_ttn(void);

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

void ttn_srv_lock(void);
void ttn_srv_release(void);

void ttn_srv_become_probing_host(void);
void ttn_srv_buzz(unsigned int tid);

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

struct parser;
void shell_cmd_ttn_probe(struct parser *prs);
void shell_cmd_ttn_buzz(struct parser *prs);

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

#define ttn_glue_vsnprintf mini_vsnprintf
#define ttn_glue_snprintf  mini_snprintf

/****************************************************************************************************************/
#ifdef __cplusplus
}
#endif

#endif
