/*
 *	Declarations of AX.25 type objects.
 *
 *	Alan Cox (GW4PTS) 	10/11/93
 */
 
#ifndef _AX25_H
#define _AX25_H 
#include <linux/ax25.h>
 
#define AX25_P_IP	0xCC
#define AX25_P_ARP	0xCD
#define AX25_P_TEXT 	0xF0
#define AX25_P_NETROM 	0xCF

#define LAPB_UI	0x03
#define LAPB_C	0x80
#define LAPB_E	0x01

#define SSID_SPARE	0x60		/* Unused bits (DAMA bit and spare must be 1) */

#define AX25_REPEATED	0x80

#define TIMER_RECOVERY_CONDITION        0x01
#define REJ_CONDITION                   0x02
#define REMOTE_RNR_CONDITION            0X04
#define HAS_ACKED_DATA			0x08	/* For connect up UA repeat */

#ifndef _LINUX_NETDEVICE_H
#include <linux/netdevice.h>
#endif

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

	This work is derived from material 
	
****************************************************************/

/*-
 * Copyright (c) University of British Columbia, 1984
 * Copyright (c) 1991 The Regents of the University of California.
 * All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by the
 * Laboratory for Computation Vision and the Computer Science Department
 * of the University of British Columbia.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by the University of
 *	California, Berkeley and its contributors.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *	@(#)hdlc.h	7.4 (Berkeley) 5/6/91
 */

#ifndef TRUE
#define FALSE   0
#define TRUE    1
typedef unsigned char octet;
typedef char    bool;
#endif

/*
 *  HDLC Packet format definitions
 *  This will eventually have to be rewritten without reference
 *  to bit fields, to be compliant with ANSI C and alignment safe.
 */

/*
#if BYTE_ORDER == BIG_ENDIAN
#define ORDER4(a, b, c, d) a , b , c , d
#define ORDER5(a, b, c, d, e) a , b , c , d , e
#endif

#if BYTE_ORDER == LITTLE_ENDIAN
*/
#define ORDER4(a, b, c, d) d , c , b , a
#define ORDER5(a, b, c, d, e) e , d , c , b , a
/*
#endif
#endif
*/

#define MAX_INFO_LEN    4096+3+4
#define ADDRESS_A       3	/* B'00000011' */
#define ADDRESS_B       1	/* B'00000001' */

struct Hdlc_iframe {
	octet	ORDER4(nr:3, pf:1, ns:3, hdlc_0:1);
	octet	address;
	octet    i_field[MAX_INFO_LEN];
};

struct Hdlc_sframe {
	octet	ORDER4(nr:3, pf:1, s2:2, hdlc_01:2);
/*	octet	address;*/
};

struct	Hdlc_uframe {
	octet	ORDER4(m3:3, pf:1, m2:2, hdlc_11:2);
	octet   address;
};

struct	Frmr_frame {
	octet	control;
	octet	address;
	octet	frmr_control;
	octet	ORDER4(frmr_nr:3, frmr_f1_0:1, frmr_ns:3, frmr_f2_0:1);
	octet	ORDER5(frmr_0000:4, frmr_z:1, frmr_y:1, frmr_x:1, frmr_w:1);
};

#define HDHEADERLN	2
#define MINFRLN		2		/* Minimum frame length. */

struct	Hdlc_frame {
	octet	control;
	octet	address;
	octet	info[3];				/* min for FRMR */
};

#define SABM_CONTROL 057	/* B'00101111' */
#define UA_CONTROL   0143	/* B'01100011' */
#define DISC_CONTROL 0103	/* B'01000011' */
#define DM_CONTROL   017	/* B'00001111' */
#define FRMR_CONTROL 0207	/* B'10000111' */
#define RR_CONTROL   01		/* B'00000001' */
#define RNR_CONTROL  05		/* B'00000101' */
#define REJ_CONTROL  011	/* B'00001001' */

#define POLLOFF  0
#define POLLON   1

/* AX25 L2 C-bit */

#define C_COMMAND	1	/* C_ otherwise it clashes with the de600 defines (sigh)) */
#define C_RESPONSE	2

/* Define Link State constants. */

#define INIT		0
#define DM_SENT		1
#define SABM_SENT	2
#define ABM		3
#define WAIT_SABM	4
#define WAIT_UA		5
#define DISC_SENT	6
#define DISCONNECTED	7
#define MAXSTATE	8

/* The following constants are used in a switch statement to process
   frames read from the communications line. */

#define SABM     0 * MAXSTATE
#define DM       1 * MAXSTATE
#define DISC     2 * MAXSTATE
#define UA       3 * MAXSTATE
#define FRMR     4 * MAXSTATE
#define RR       5 * MAXSTATE
#define RNR      6 * MAXSTATE
#define REJ      7 * MAXSTATE
#define IFRAME   8 * MAXSTATE
#define ILLEGAL  9 * MAXSTATE

#define PR_SLOWHZ	10			/*  Run timing at 1/10 second - gives us better resolution for 56kbit links */
#define DEFAULT_T1	(10 * PR_SLOWHZ)		/*  IFRAME TIMEOUT - 10 seconds */
#define DEFAULT_T3	(30 * PR_SLOWHZ)	/*  RR generate timeout - 15 seconds */
#define DEFAULT_N2	15			/*  Number of retries */
#define MODULUS 8
#define MAX_WINDOW_SIZE 7			/*  Maximum window allowable */

#define Z  0
#define Y  1
#define X  2
#define W  3
#define A  4

#define TX 0
#define RX 1

extern struct Frmr_frame ax25_frmr;

typedef struct sock ax25_socket;

typedef struct
{
	ax25_address calls[6];
	unsigned char repeated[6];
	unsigned char ndigi;
	char lastrepeat;
} ax25_digi;


/* ax25.c */
extern char *ax2asc(ax25_address *);
extern int ax25cmp(ax25_address *, ax25_address *);
extern int ax25_input(struct protocol *p, struct protocol *lower, sk_buff *skb, void *saddr, void *daddr);
extern void ax25_destroy_socket(ax25_socket *);
extern struct protocol *ax25rtr_get_dev(ax25_address *);
extern int ax25_encapsulate(unsigned char *buff, struct device *dev, unsigned short type, void *daddr,
	void *saddr, unsigned len, sk_buff *skb);
extern int ax25_rebuild_header(unsigned char *bp, struct device *dev, unsigned long raddr, sk_buff *skb);
extern int ax25_get_info(char *, char **, off_t, int);
#include "ax25call.h"
/* ax25_input.c */
extern int ax25_process_rx_frame(ax25_socket *sk, sk_buff *skb, int);
extern int ax25_rx_iframe(ax25_socket *sk, sk_buff *skb, struct Hdlc_iframe *frame);
extern bool range_check(int,int,int);
extern void ax25_send_frmr(ax25_socket *sk,int, struct Hdlc_iframe *frame);
extern void ax25_rx_sframe(ax25_socket *sk,struct Hdlc_sframe *frame, int frametype, int type);
extern bool valid_nr(ax25_socket *sk,int,int);
extern void ax25_reject(ax25_socket *,int);
extern void ax25_free_iframes(ax25_socket *sk, int *nr, int finalbit);
/* ax25_output */
extern int ax25_output(ax25_socket *,sk_buff *);
extern void ax25_kick(ax25_socket *);
extern void ax25_send_iframe(ax25_socket *,sk_buff *, int);
extern void ax25_resend_iframe(ax25_socket *sk);
extern void ax25_transmit_buffer(ax25_socket *sk,sk_buff *skb,int, int);
/* ax25_route */
extern void ax25_rt_rx_frame(ax25_address *, struct device *);
extern int ax25_rt_get_info(char *, char **, off_t, int);
/* ax25_subr */
extern void ax25_init_vars(ax25_socket *);
extern int ax25_decode(ax25_socket *, struct Hdlc_frame *);
extern void ax25_write_internal(ax25_socket*,int,int,int);
extern unsigned char *ax25_parse_addr(sk_buff *skb, int len, ax25_address *src, ax25_address *dest, ax25_digi *digi, int *flags);
extern int build_ax25_addr(sk_buff *skb, ax25_address *src, ax25_address *dest, ax25_digi *d,int flag);
extern int size_ax25_addr(ax25_digi *dp);
extern void ax25_digi_invert(ax25_digi *in,ax25_digi *out);
extern void ax25_return_dm(ax25_address *src,ax25_address *dest, ax25_digi *d);

/* ax25_timer */
extern void ax25_timer(unsigned long);
extern void ax25_set_timer(ax25_socket *);

#define KILL_TIMER(sk)	(del_timer(&(sk)->timer))
#define SET_TIMER(sk)   ax25_set_timer(sk)

extern struct protocol proto_ax25;

#endif
