/* proto.h - Common protocol functions and structures */
 
/* Written 1995-1997 by Werner Almesberger, EPFL-LRC */
 

#ifndef PROTO_H
#define PROTO_H

#include <linux/atmsvc.h>

#include "atmsap.h"
#include "atmd.h"


typedef enum { /* formatting aligned with state_map and others */
	ss_invalid,	ss_null,	ss_listening,	ss_connecting,
	ss_connected,	ss_indicated,	ss_accepting,	ss_zombie,
	ss_wait_rel,	ss_wait_close,	ss_rel_req,	ss_rel_ind,
#ifdef Q2963_1
	ss_mod_lcl,	ss_mod_req,	ss_mod_rcv,	ss_mod_fin_ack,
	ss_mod_fin_ok,	ss_mod_fin_fail
#endif
} STATE;

typedef enum { cs_null,cs_call_init,cs_out_proc = 3,cs_conn_req = 8,
  cs_in_proc,cs_active,cs_rel_req,cs_rel_ind,
#ifdef Q2963_1
  cs_mod_req,cs_mod_rcv
#endif
  } CALL_STATE;

typedef enum { ps_null,ps_add_init,ps_add_recv = 6,ps_drop_init = 11,
  ps_drop_recv,ps_active = 10 } PARTY_STATE;

typedef struct _socket {
    STATE state;
    struct sockaddr_atmpvc pvc;
    /* --- socket layer information ---------------------------------------- */
    unsigned long id;
    struct sockaddr_atmsvc local; /* local address */
    struct sockaddr_atmsvc remote; /* remote address */
    struct atm_sap sap; /* SAP (BHLI and BLLI) */
    struct atm_qos qos; /* QOS parameters */
#ifdef Q2963_1
    struct atm_qos new_qos; /* during modification */
#endif
    int error; /* error code for close */
    /* --- UNI information ------------------------------------------------- */
    CALL_STATE call_state;
    unsigned long call_ref; /* bit 24 like when sending */
    short ep_ref; /* endpoint reference; -1 for p2p */
    TIMER *conn_timer; /* current connection timer */
    /* --- some meta-information ------------------------------------------- */
    struct _socket *listen; /* to pending connections, also used for "more" */
    struct _socket *next; /* next socket */
} SOCKET;

/*
 * SOCKET uses a horrible linked list structure. Lists should be at least
 * doubly-linked and there should be a few hashes (by id and by call_ref) for
 * reasonable fast lookup. All this will have to wait till that version is
 * stable enough to be useful to test the "real" thing against it.
 */


extern const CALL_STATE state_map[];
extern const PARTY_STATE eps_map[];
extern const char *state_name[],*cs_name[],*as_name[];

extern SOCKET *sockets;
extern unsigned char q_buffer[];

#define DEFAULT_TRACE_SIZE 20

extern int net;
extern int pretty;
extern int sig_pcr;
extern const char *sig_qos;
extern const char *dump_dir;


#define SEND_ERROR(vcc,code) \
  send_kernel(vcc,0L,as_error,code,NULL,NULL,NULL,NULL,NULL)


void poll_signals(void);

void from_kernel(struct atmsvc_msg *msg,int size);
void itf_load(int itf);

void to_uni(void *msg,int size);
void send_kernel(unsigned long vcc,unsigned long listen_vcc,
  enum atmsvc_msg_type type,int reply,const struct sockaddr_atmpvc *pvc,
  const struct sockaddr_atmsvc *svc,const struct sockaddr_atmsvc *local,
  const struct atm_sap *sap,const struct atm_qos *qos);
void from_net(void *msg,int size);
void to_signaling(void *msg,int size);
void saal_failure(void);
void saal_okay(void);
void clear_all_calls_on_T309(void);

SOCKET *new_sock(unsigned long id);
void free_sock(SOCKET *sock);
void new_state(SOCKET *sock,STATE state);
SOCKET *lookup_sap(const struct sockaddr_atmsvc *addr,
  const struct atm_sap *sap,const struct atm_qos *qos,
  struct sockaddr_atmsvc *res_addr,struct atm_sap *res_sap,
  struct atm_qos *res_qos,int exact_match);

void send_release(SOCKET *sock,unsigned char reason,...);
void send_release_complete(unsigned long call_ref,unsigned char cause);
void send_modify_reject(SOCKET *sock,unsigned char reason);

const char *mid2name(unsigned char mid);

void set_error(SOCKET *sock,int code);
void send_close(SOCKET *sock);

int get_vci(int itf);

void enter_vpci(int vpci,int itf);
int get_itf(int *vpci);
void init_addr(void);

#endif
