1121326Sharti/*
2121326Sharti * Copyright (c) 1996-2003
3121326Sharti *	Fraunhofer Institute for Open Communication Systems (FhG Fokus).
4121326Sharti * 	All rights reserved.
5121326Sharti *
6121326Sharti * Redistribution and use in source and binary forms, with or without
7121326Sharti * modification, are permitted provided that the following conditions
8121326Sharti * are met:
9121326Sharti * 1. Redistributions of source code must retain the above copyright
10121326Sharti *    notice, this list of conditions and the following disclaimer.
11121326Sharti * 2. Redistributions in binary form must reproduce the above copyright
12121326Sharti *    notice, this list of conditions and the following disclaimer in the
13121326Sharti *    documentation and/or other materials provided with the distribution.
14121326Sharti *
15121326Sharti * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16121326Sharti * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17121326Sharti * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18121326Sharti * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19121326Sharti * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20121326Sharti * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21121326Sharti * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22121326Sharti * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23121326Sharti * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24121326Sharti * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25121326Sharti * SUCH DAMAGE.
26121326Sharti *
27121326Sharti * Author: Hartmut Brandt <harti@freebsd.org>
28121326Sharti *
29131826Sharti * $Begemot: libunimsg/netnatm/saal/sscoppriv.h,v 1.4 2004/07/08 08:22:17 brandt Exp $
30121326Sharti *
31121326Sharti * Private SSCOP definitions.
32121326Sharti *
33121326Sharti */
34121326Sharti#ifdef _KERNEL
35121326Sharti#ifdef __FreeBSD__
36121326Sharti#include <netgraph/atm/sscop/ng_sscop_cust.h>
37121326Sharti#endif
38121326Sharti#else	/* !_KERNEL */
39121326Sharti#include "sscopcust.h"
40121326Sharti#endif
41121326Sharti
42131826Sharti/* Argh. BSDi */
43131826Sharti#ifndef _BYTE_ORDER
44131826Sharti#ifndef BYTE_ORDER
45131826Sharti#error "_BYTE_ORDER not defined"
46131826Sharti#endif
47131826Sharti#define _BYTE_ORDER	BYTE_ORDER
48131826Sharti#define _LITTLE_ENDIAN	LITTLE_ENDIAN
49131826Sharti#define	_BIG_ENDIAN	BIG_ENDIAN
50131826Sharti#endif
51131826Sharti
52121326Sharti/*
53121326Sharti * PDU trailer
54121326Sharti */
55121326Shartiunion pdu {
56121326Sharti  u_int			sscop_null;
57121326Sharti  struct {
58121326Sharti#if _BYTE_ORDER == _BIG_ENDIAN
59121326Sharti	u_int		pl : 2;		/* pad length */
60121326Sharti	u_int		: 1;		/* reserved field */
61121326Sharti	u_int		s : 1;		/* source */
62121326Sharti	u_int		type : 4;	/* PDU type */
63121326Sharti	u_int		ns : 24;	/* sequence number */
64121326Sharti#else
65121326Sharti	u_int		ns : 24;	/* sequence number */
66121326Sharti	u_int		type : 4;	/* PDU type */
67121326Sharti	u_int		s : 1;		/* source */
68121326Sharti	u_int		: 1;		/* reserved field */
69121326Sharti	u_int		pl : 2;		/* pad length */
70121326Sharti#endif
71121326Sharti  } ss;
72121326Sharti};
73121326Sharti#define sscop_pl	ss.pl
74121326Sharti#define sscop_s		ss.s
75121326Sharti#define sscop_type	ss.type
76121326Sharti#define sscop_ns	ss.ns
77121326Sharti
78121326Sharti/*
79121326Sharti * seqno list entry format
80121326Sharti */
81121326Shartiunion seqno {
82121326Sharti  u_int			sscop_null;
83121326Sharti  struct {
84121326Sharti#if _BYTE_ORDER == _BIG_ENDIAN
85121326Sharti	u_int		: 8;		/* pad */
86121326Sharti	u_int		n : 24;		/* seqno */
87121326Sharti#else
88121326Sharti	u_int		n : 24;		/* seqno */
89121326Sharti	u_int		: 8;		/* pad */
90121326Sharti#endif
91121326Sharti  } ss;
92121326Sharti};
93121326Sharti#define sscop_n	ss.n
94121326Sharti
95121326Sharti/*
96121326Sharti * Begin pdu
97121326Sharti */
98121326Shartiunion bgn {
99121326Sharti  u_int			sscop_null;
100121326Sharti  struct {
101121326Sharti#if _BYTE_ORDER == _BIG_ENDIAN
102121326Sharti	u_int	: 24;			/* reserved */
103121326Sharti	u_int	bgns : 8;		/* VT_MR */
104121326Sharti#else
105121326Sharti	u_int	bgns : 8;		/* VT_MR */
106121326Sharti	u_int	: 24;			/* reserved */
107121326Sharti#endif
108121326Sharti  } ss;
109121326Sharti};
110121326Sharti#define sscop_bgns	ss.bgns
111121326Sharti
112121326Sharti/*
113121326Sharti * pdu types
114121326Sharti */
115121326Shartienum pdu_type {
116121326Sharti	PDU_BGN		= 0x1,	/* request initialization */
117121326Sharti	PDU_BGAK	= 0x2,	/* request acknowledgement */
118121326Sharti	PDU_END		= 0x3,	/* disconnect command */
119121326Sharti	PDU_ENDAK	= 0x4,	/* disconnect acknowledgement */
120121326Sharti	PDU_RS		= 0x5,	/* resynchronisation command */
121121326Sharti	PDU_RSAK	= 0x6,	/* resynchronisation acknowledgement */
122121326Sharti	PDU_BGREJ	= 0x7,	/* connection reject */
123121326Sharti	PDU_SD		= 0x8,	/* sequenced connection-mode data */
124121326Sharti	PDU_ER		= 0x9,	/* recovery command */
125121326Sharti	PDU_POLL	= 0xa,	/* xmit state info with req. for recv state */
126121326Sharti	PDU_STAT	= 0xb,	/* solicited receiver state info */
127121326Sharti	PDU_USTAT	= 0xc,	/* unsolicited receiver state info */
128121326Sharti	PDU_UD		= 0xd,	/* unumbered user data */
129121326Sharti	PDU_MD		= 0xe,	/* unumbered management data */
130121326Sharti	PDU_ERAK	= 0xf,	/* recovery acknowledgement */
131121326Sharti};
132121326Sharti
133121326Sharti
134121326Sharti/*
135121326Sharti * These are all signals, that are used by SSCOP. Don't change the order or
136121326Sharti * number without also changing the associated tables.
137121326Sharti */
138121326Shartienum sscop_sigtype {
139121326Sharti	/* received PDU's */
140121326Sharti	SIG_BGN,		/* request initialization */
141121326Sharti	SIG_BGAK,		/* request acknowledgement */
142121326Sharti	SIG_END,		/* disconnect command */
143121326Sharti	SIG_ENDAK,		/* disconnect acknowledgement */
144121326Sharti	SIG_RS,			/* resynchronisation command */
145121326Sharti	SIG_RSAK,		/* resynchronisation acknowledgement */
146121326Sharti	SIG_BGREJ,		/* connection reject */
147121326Sharti	SIG_SD,			/* sequenced connection-mode data */
148121326Sharti	SIG_ER,			/* recovery command */
149121326Sharti	SIG_POLL,		/* xmitter state info with req for recv state */
150121326Sharti	SIG_STAT,		/* solicited receiver state info */
151121326Sharti	SIG_USTAT,		/* unsolicited receiver state info */
152121326Sharti	SIG_UD,			/* unumbered user data */
153121326Sharti	SIG_MD,			/* unumbered management data */
154121326Sharti	SIG_ERAK,		/* recovery acknoledgement */
155121326Sharti
156121326Sharti	/* timer expiry */
157121326Sharti	SIG_T_CC,		/* CC timer */
158121326Sharti	SIG_T_POLL,		/* POLL timer */
159121326Sharti	SIG_T_KA,		/* KEEP ALIVE timer */
160121326Sharti	SIG_T_NR,		/* NO RESPONSE timer */
161121326Sharti	SIG_T_IDLE,		/* IDLE timer */
162121326Sharti
163121326Sharti	/* user originated signals */
164121326Sharti	SIG_PDU_Q,		/* PDU enqueued pseudosignal */
165121326Sharti	SIG_USER_DATA,		/* user data request */
166121326Sharti	SIG_ESTAB_REQ,		/* establish connection request */
167121326Sharti	SIG_ESTAB_RESP,		/* establish connection response */
168121326Sharti	SIG_RELEASE_REQ,	/* release connection request */
169121326Sharti	SIG_RECOVER,		/* automatic recover response */
170121326Sharti	SIG_SYNC_REQ,		/* resynchronisation request */
171121326Sharti	SIG_SYNC_RESP,		/* resynchronisation response */
172121326Sharti	SIG_UDATA,		/* UDATA request */
173121326Sharti	SIG_MDATA,		/* MDATA request */
174121326Sharti	SIG_UPDU_Q,		/* UDATA PDU enqueued pseudosignal */
175121326Sharti	SIG_MPDU_Q,		/* MDATA PDU enqueued pseudosignal */
176121326Sharti	SIG_RETRIEVE,		/* RETRIEVE */
177121326Sharti
178121326Sharti	/* number of signals */
179121326Sharti	SIG_NUM
180121326Sharti};
181121326Sharti
182121326Sharti/*
183121326Sharti * This is a message as contained in a sscop message queue. It holds a pointer
184121326Sharti * to the real message.
185121326Sharti */
186121326Shartistruct sscop_msg {
187121326Sharti	sscop_msgq_link_t link;
188121326Sharti	u_int		seqno;		/* seq no */
189121326Sharti	u_int		poll_seqno;	/* poll seqno (for messages in xmit buffer) */
190121326Sharti	u_int		rexmit;		/* in retransmission queue? */
191121326Sharti	struct SSCOP_MBUF_T *m;		/* the message */
192121326Sharti};
193121326Sharti
194121326Sharti/*
195121326Sharti * This structure is used to hold signals in the signal queue
196121326Sharti */
197121326Shartistruct sscop_sig {
198121326Sharti	sscop_sigq_link_t link;		/* next signal */
199121326Sharti	enum sscop_sigtype sig;		/* THE signal */
200121326Sharti	struct sscop_msg *msg;		/* signal argument (message) */
201121326Sharti};
202121326Sharti
203121326Sharti/*
204121326Sharti * This structure holds the entire sscop state
205121326Sharti */
206121326Shartistruct sscop {
207121326Sharti	enum sscop_state state;	/* current state */
208121326Sharti	const struct sscop_funcs *funcs;
209121326Sharti
210121326Sharti	/* send state */
211121326Sharti	u_int	vt_s;		/* seqno for next pdu first time transmitted */
212121326Sharti	u_int	vt_ps;		/* current poll seqno */
213121326Sharti	u_int	vt_a;		/* next expected in-sequence sd pdu */
214121326Sharti	u_int	vt_pa;		/* poll seqno of next stat pdu */
215121326Sharti	u_int	vt_ms;		/* maximum allowed send sd seqno */
216121326Sharti	u_int	vt_pd;		/* poll data state */
217121326Sharti	u_int	vt_cc;		/* connection control state */
218121326Sharti	u_int	vt_sq;		/* transmitter connection sequence */
219121326Sharti
220121326Sharti	/* receive state */
221121326Sharti	u_int	vr_r;		/* receive state */
222121326Sharti	u_int	vr_h;		/* highes expected state */
223121326Sharti	u_int	vr_mr;		/* maximum acceptable */
224121326Sharti	u_int	vr_sq;		/* receiver connection state */
225121326Sharti
226121326Sharti	/* timers */
227121326Sharti	sscop_timer_t t_cc;	/* timer_CC */
228121326Sharti	sscop_timer_t t_nr;	/* timer_NO_RESPONSE */
229121326Sharti	sscop_timer_t t_ka;	/* timer KEEP_ALIVE */
230121326Sharti	sscop_timer_t t_poll;	/* timer_POLL */
231121326Sharti	sscop_timer_t t_idle;	/* idle timer */
232121326Sharti
233121326Sharti	/* maximum values */
234121326Sharti	u_int	maxj;		/* maximum uu-info */
235121326Sharti	u_int	maxk;		/* maximum info */
236121326Sharti	u_int	maxcc;		/* maximum number of bgn, end, er and rs */
237121326Sharti	u_int	maxpd;		/* maximum value of vt_pd */
238121326Sharti	u_int	maxstat;	/* maximum length of list */
239121326Sharti	u_int	timercc;	/* connection control timer */
240121326Sharti	u_int	timerka;	/* keep alive timer */
241121326Sharti	u_int	timernr;	/* no response timer */
242121326Sharti	u_int	timerpoll;	/* polling */
243121326Sharti	u_int	timeridle;	/* idle timer */
244121326Sharti	u_int	robustness;	/* atmf/97-0216 robustness enhancement */
245121326Sharti	u_int	poll_after_rex;	/* optional POLL after re-transmission */
246121326Sharti	u_int	mr;		/* initial window */
247121326Sharti
248121326Sharti	/*
249121326Sharti	 * buffers and queues.
250121326Sharti	 * All expect the xq hold SD PDUs.
251121326Sharti	 */
252121326Sharti	sscop_msgq_head_t xq;	/* xmit queue (input from user before xmit) */
253121326Sharti	sscop_msgq_head_t uxq;	/* UD xmit queue */
254121326Sharti	sscop_msgq_head_t mxq;	/* MD xmit queue */
255121326Sharti	sscop_msgq_head_t xbuf;	/* transmission buffer (SD PDUs transmitted) */
256121326Sharti	int	rxq;		/* number of PDUs in retransmission queue */
257121326Sharti	sscop_msgq_head_t rbuf;	/* receive buffer (SD PDUs) */
258121326Sharti	int	last_end_src;	/* source field from last xmitted end pdu */
259121326Sharti	int	clear_buffers;	/* flag */
260121326Sharti	int	credit;		/* send window not closed */
261121326Sharti	u_int	ll_busy;	/* lower layer busy */
262121326Sharti	u_int	rs_mr;		/* N(MR) in last RS PDU */
263121326Sharti	u_int	rs_sq;		/* N(SQ) in last RS PDU */
264121326Sharti	struct SSCOP_MBUF_T *uu_bgn;	/* last UU data */
265121326Sharti	struct SSCOP_MBUF_T *uu_bgak;	/*  ... */
266121326Sharti	struct SSCOP_MBUF_T *uu_bgrej;	/*  ... */
267121326Sharti	struct SSCOP_MBUF_T *uu_end;	/*  ... */
268121326Sharti	struct SSCOP_MBUF_T *uu_rs;	/*  ... */
269121326Sharti
270121326Sharti	/* signal queues */
271121326Sharti	sscop_sigq_head_t	sigs;		/* saved signals */
272121326Sharti	sscop_sigq_head_t	saved_sigs;	/* saved signals */
273121326Sharti	int	in_sig;		/* in signal handler */
274121326Sharti
275121326Sharti	/* debugging */
276121326Sharti	u_int		debug;
277121326Sharti
278121326Sharti	/* AA interface */
279121326Sharti	void		*aarg;
280121326Sharti};
281121326Sharti
282121326Sharti
283121326Sharti/*
284121326Sharti * Default values for SSCOP
285121326Sharti */
286121326Shartienum {
287121326Sharti	MAXK		= 4096,
288121326Sharti	MAXMAXK		= 65528,
289121326Sharti	MAXJ		= 4096,
290121326Sharti	MAXMAXJ		= 65524,
291121326Sharti	MAXCC		= 4,
292121326Sharti	MAXSTAT		= 67,
293121326Sharti	MAXPD		= 25,
294121326Sharti	MAXMR		= 128,		/* ??? */
295121326Sharti	TIMERCC		= 1000,
296121326Sharti	TIMERKA		= 2000,
297121326Sharti	TIMERNR		= 7000,
298121326Sharti	TIMERPOLL	= 750,
299121326Sharti	TIMERIDLE	= 15000,
300121326Sharti};
301121326Sharti
302121326Sharti/*
303121326Sharti * Sequence number arithmetic
304121326Sharti */
305121326Sharti#define SEQNO_DIFF(A,B)  (((A) < (B)) ? ((A) + (1<<24) - (B)) : ((A) - (B)))
306121326Sharti
307121326Sharti/*
308121326Sharti * Debugging
309121326Sharti */
310121326Sharti#ifdef SSCOP_DEBUG
311121326Sharti#define VERBOSE(S,M,F)	if ((S)->debug & (M)) (S)->funcs->verbose F
312121326Sharti#define VERBERR(S,M,F)	if ((S)->debug & (M)) (S)->funcs->verbose F
313121326Sharti#define ISVERBOSE(S,M)	((S)->debug & (M))
314121326Sharti#else
315121326Sharti#define VERBOSE(S,M,F)
316121326Sharti#define VERBERR(S,M,F)
317121326Sharti#define ISVERBOSE(S,M)	(0)
318121326Sharti#endif
319