/*
  LinPac - application interface library
  (c) by Radek Burget (OK2JBG) 1998
*/
#ifndef LIN_PAC_APPL
#define LIN_PAC_APPL

#include <stdio.h>
#include "tevent.h"

#define LPAPP_VERSION "0.06"

#define LP_PIPE_PATH "/tmp/LinPac"
#define AXPORTS "/etc/ax25/axports"
#define MAX_CHN 8
#define ENV_SIZE 1024

/* connection status constants */
#define ST_DISC 0 /* disconnected */
#define ST_DISP 1 /* disconnecting */
#define ST_TIME 2 /* disconnecting for timeout */
#define ST_CONN 3 /* connected */
#define ST_CONP 4 /* connectin in progress */

/* shared data structure */
typedef struct
{
  char call[MAX_CHN+1][10];       /* callsign for each channel */
  char cwit[MAX_CHN+1][10];       /* connected with callsign */
  char cphy[MAX_CHN+1][10];       /* physical connection to */
  int port[MAX_CHN+1];            /* connected on which port */
  char descript[MAX_CHN+1][128];  /* station description - not used */
  int state[MAX_CHN+1];           /* connection status */
  char env[MAX_CHN+1][ENV_SIZE];  /* channel environment */
} shared_data;

extern shared_data *shd;

typedef void (*handler_type)(Event *);

/* ax25 status structure */
typedef struct
{
  char devname[8];
  int state;
  int vs, vr, va;
  int t1, t2, t3, t1max, t2max, t3max;
  int idle, idlemax;
  int n2, n2max;
  int rtt;
  int window;
  int paclen;
  bool dama;
  int sendq, recvq;
} ax25_status;


/*=================== Safe versions of syscalls ==========================*/
/*!! These functions are interrupt-safe, use them rather than originals !!*/
size_t safe_read(int fd, void *buf, size_t count);
size_t safe_write(int fd, const void *buf, size_t count);
char *safe_fgets(char *s, int size, FILE *stream);
int safe_fgetc(FILE *stream);

/*==================== Low-level IPC functions ===========================*/

/* app_chn - application is running on this channel of LinPac */
extern int app_chn;

/* app_pid - application pid */
extern int app_pid;

/* setup application identification string */
void appl_ident(char *id); /* currently useless */

/* start application - this must be used first of all */
int start_appl(char *pipename);

/* get event, return 0 if no event is present */
int get_event(Event *ev);

/* send event */
int emit_event(int chn, int type, int x, void *data);

/* wait for specified event at specified channel*/
void wait_event(int chn, int type);

/* discard the event, free memory */
void discard_event(Event *ev);

/* discard all events from pipe */
void clear_pipe();

/* end application */
void end_appl();

/*====================== Environment functions ===========================*/

/* create/modify variable */
void set_var(int chn, char *name, char *contents);

/* delete variable */
void del_var(int chn, char *var);

/* delete all variables with name starting with <names> */
void clear_var_names(int chn, char *names);

/* find the begining of variable record */
char *find_var(int chn, char *name);

/* returns the value of specified variable */
char *get_var(int chn, char *name);

/* returns the end of environment */
char *env_end(int chn);

/*========================== Event handling ===========================*/

/* Switch automatic event reading on (default). When event_handler
   function is set, it's called automatically for each event */
void event_handling_on();

/* Switch automatic event reading off. Application *must* call get_event()
   periodicaly not to overflow the event pipe. NOT RECOMMENDED. */
void event_handling_off();

/* Set user event handler - a function like
          void my_handler(Event *ev)
   This function is called for each event, when automatic event handling
   is on. */
void set_event_handler(handler_type handler);

/*========================== User functions ==============================*/

/* return result string */
void appl_result(const char *fmt, ...);

/* change application's status line */
void statline(const char *fmt, ...);

/* remove status line */
void remove_statline();

/* disable writing data to screen */
void disable_screen();

/* enable writing data to screen */
void enable_screen();

/*============================== Tools ====================================*/

/* return actual time string (or UTC time if utc != 0)*/
char *time_stamp(int utc);

/* return actual date string (or UTC date if utc != 0)*/
char *date_stamp(int utc);

/* replace % macros in this string */
void replace_macros(int chn, char *s);

/* find the name of n-th port (first is 0) */
char *get_port_name(int n);

#endif

