1/*
2 * Copyright (c) 1996-2003
3 *	Fraunhofer Institute for Open Communication Systems (FhG Fokus).
4 * 	All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 * Author: Hartmut Brandt <harti@freebsd.org>
28 *
29 * $Begemot: libunimsg/netnatm/saal/sscoppriv.h,v 1.4 2004/07/08 08:22:17 brandt Exp $
30 *
31 * Private SSCOP definitions.
32 *
33 */
34#ifdef _KERNEL
35#ifdef __FreeBSD__
36#include <netgraph/atm/sscop/ng_sscop_cust.h>
37#endif
38#else	/* !_KERNEL */
39#include "sscopcust.h"
40#endif
41
42/* Argh. BSDi */
43#ifndef _BYTE_ORDER
44#ifndef BYTE_ORDER
45#error "_BYTE_ORDER not defined"
46#endif
47#define _BYTE_ORDER	BYTE_ORDER
48#define _LITTLE_ENDIAN	LITTLE_ENDIAN
49#define	_BIG_ENDIAN	BIG_ENDIAN
50#endif
51
52/*
53 * PDU trailer
54 */
55union pdu {
56  u_int			sscop_null;
57  struct {
58#if _BYTE_ORDER == _BIG_ENDIAN
59	u_int		pl : 2;		/* pad length */
60	u_int		: 1;		/* reserved field */
61	u_int		s : 1;		/* source */
62	u_int		type : 4;	/* PDU type */
63	u_int		ns : 24;	/* sequence number */
64#else
65	u_int		ns : 24;	/* sequence number */
66	u_int		type : 4;	/* PDU type */
67	u_int		s : 1;		/* source */
68	u_int		: 1;		/* reserved field */
69	u_int		pl : 2;		/* pad length */
70#endif
71  } ss;
72};
73#define sscop_pl	ss.pl
74#define sscop_s		ss.s
75#define sscop_type	ss.type
76#define sscop_ns	ss.ns
77
78/*
79 * seqno list entry format
80 */
81union seqno {
82  u_int			sscop_null;
83  struct {
84#if _BYTE_ORDER == _BIG_ENDIAN
85	u_int		: 8;		/* pad */
86	u_int		n : 24;		/* seqno */
87#else
88	u_int		n : 24;		/* seqno */
89	u_int		: 8;		/* pad */
90#endif
91  } ss;
92};
93#define sscop_n	ss.n
94
95/*
96 * Begin pdu
97 */
98union bgn {
99  u_int			sscop_null;
100  struct {
101#if _BYTE_ORDER == _BIG_ENDIAN
102	u_int	: 24;			/* reserved */
103	u_int	bgns : 8;		/* VT_MR */
104#else
105	u_int	bgns : 8;		/* VT_MR */
106	u_int	: 24;			/* reserved */
107#endif
108  } ss;
109};
110#define sscop_bgns	ss.bgns
111
112/*
113 * pdu types
114 */
115enum pdu_type {
116	PDU_BGN		= 0x1,	/* request initialization */
117	PDU_BGAK	= 0x2,	/* request acknowledgement */
118	PDU_END		= 0x3,	/* disconnect command */
119	PDU_ENDAK	= 0x4,	/* disconnect acknowledgement */
120	PDU_RS		= 0x5,	/* resynchronisation command */
121	PDU_RSAK	= 0x6,	/* resynchronisation acknowledgement */
122	PDU_BGREJ	= 0x7,	/* connection reject */
123	PDU_SD		= 0x8,	/* sequenced connection-mode data */
124	PDU_ER		= 0x9,	/* recovery command */
125	PDU_POLL	= 0xa,	/* xmit state info with req. for recv state */
126	PDU_STAT	= 0xb,	/* solicited receiver state info */
127	PDU_USTAT	= 0xc,	/* unsolicited receiver state info */
128	PDU_UD		= 0xd,	/* unumbered user data */
129	PDU_MD		= 0xe,	/* unumbered management data */
130	PDU_ERAK	= 0xf,	/* recovery acknowledgement */
131};
132
133
134/*
135 * These are all signals, that are used by SSCOP. Don't change the order or
136 * number without also changing the associated tables.
137 */
138enum sscop_sigtype {
139	/* received PDU's */
140	SIG_BGN,		/* request initialization */
141	SIG_BGAK,		/* request acknowledgement */
142	SIG_END,		/* disconnect command */
143	SIG_ENDAK,		/* disconnect acknowledgement */
144	SIG_RS,			/* resynchronisation command */
145	SIG_RSAK,		/* resynchronisation acknowledgement */
146	SIG_BGREJ,		/* connection reject */
147	SIG_SD,			/* sequenced connection-mode data */
148	SIG_ER,			/* recovery command */
149	SIG_POLL,		/* xmitter state info with req for recv state */
150	SIG_STAT,		/* solicited receiver state info */
151	SIG_USTAT,		/* unsolicited receiver state info */
152	SIG_UD,			/* unumbered user data */
153	SIG_MD,			/* unumbered management data */
154	SIG_ERAK,		/* recovery acknoledgement */
155
156	/* timer expiry */
157	SIG_T_CC,		/* CC timer */
158	SIG_T_POLL,		/* POLL timer */
159	SIG_T_KA,		/* KEEP ALIVE timer */
160	SIG_T_NR,		/* NO RESPONSE timer */
161	SIG_T_IDLE,		/* IDLE timer */
162
163	/* user originated signals */
164	SIG_PDU_Q,		/* PDU enqueued pseudosignal */
165	SIG_USER_DATA,		/* user data request */
166	SIG_ESTAB_REQ,		/* establish connection request */
167	SIG_ESTAB_RESP,		/* establish connection response */
168	SIG_RELEASE_REQ,	/* release connection request */
169	SIG_RECOVER,		/* automatic recover response */
170	SIG_SYNC_REQ,		/* resynchronisation request */
171	SIG_SYNC_RESP,		/* resynchronisation response */
172	SIG_UDATA,		/* UDATA request */
173	SIG_MDATA,		/* MDATA request */
174	SIG_UPDU_Q,		/* UDATA PDU enqueued pseudosignal */
175	SIG_MPDU_Q,		/* MDATA PDU enqueued pseudosignal */
176	SIG_RETRIEVE,		/* RETRIEVE */
177
178	/* number of signals */
179	SIG_NUM
180};
181
182/*
183 * This is a message as contained in a sscop message queue. It holds a pointer
184 * to the real message.
185 */
186struct sscop_msg {
187	sscop_msgq_link_t link;
188	u_int		seqno;		/* seq no */
189	u_int		poll_seqno;	/* poll seqno (for messages in xmit buffer) */
190	u_int		rexmit;		/* in retransmission queue? */
191	struct SSCOP_MBUF_T *m;		/* the message */
192};
193
194/*
195 * This structure is used to hold signals in the signal queue
196 */
197struct sscop_sig {
198	sscop_sigq_link_t link;		/* next signal */
199	enum sscop_sigtype sig;		/* THE signal */
200	struct sscop_msg *msg;		/* signal argument (message) */
201};
202
203/*
204 * This structure holds the entire sscop state
205 */
206struct sscop {
207	enum sscop_state state;	/* current state */
208	const struct sscop_funcs *funcs;
209
210	/* send state */
211	u_int	vt_s;		/* seqno for next pdu first time transmitted */
212	u_int	vt_ps;		/* current poll seqno */
213	u_int	vt_a;		/* next expected in-sequence sd pdu */
214	u_int	vt_pa;		/* poll seqno of next stat pdu */
215	u_int	vt_ms;		/* maximum allowed send sd seqno */
216	u_int	vt_pd;		/* poll data state */
217	u_int	vt_cc;		/* connection control state */
218	u_int	vt_sq;		/* transmitter connection sequence */
219
220	/* receive state */
221	u_int	vr_r;		/* receive state */
222	u_int	vr_h;		/* highes expected state */
223	u_int	vr_mr;		/* maximum acceptable */
224	u_int	vr_sq;		/* receiver connection state */
225
226	/* timers */
227	sscop_timer_t t_cc;	/* timer_CC */
228	sscop_timer_t t_nr;	/* timer_NO_RESPONSE */
229	sscop_timer_t t_ka;	/* timer KEEP_ALIVE */
230	sscop_timer_t t_poll;	/* timer_POLL */
231	sscop_timer_t t_idle;	/* idle timer */
232
233	/* maximum values */
234	u_int	maxj;		/* maximum uu-info */
235	u_int	maxk;		/* maximum info */
236	u_int	maxcc;		/* maximum number of bgn, end, er and rs */
237	u_int	maxpd;		/* maximum value of vt_pd */
238	u_int	maxstat;	/* maximum length of list */
239	u_int	timercc;	/* connection control timer */
240	u_int	timerka;	/* keep alive timer */
241	u_int	timernr;	/* no response timer */
242	u_int	timerpoll;	/* polling */
243	u_int	timeridle;	/* idle timer */
244	u_int	robustness;	/* atmf/97-0216 robustness enhancement */
245	u_int	poll_after_rex;	/* optional POLL after re-transmission */
246	u_int	mr;		/* initial window */
247
248	/*
249	 * buffers and queues.
250	 * All expect the xq hold SD PDUs.
251	 */
252	sscop_msgq_head_t xq;	/* xmit queue (input from user before xmit) */
253	sscop_msgq_head_t uxq;	/* UD xmit queue */
254	sscop_msgq_head_t mxq;	/* MD xmit queue */
255	sscop_msgq_head_t xbuf;	/* transmission buffer (SD PDUs transmitted) */
256	int	rxq;		/* number of PDUs in retransmission queue */
257	sscop_msgq_head_t rbuf;	/* receive buffer (SD PDUs) */
258	int	last_end_src;	/* source field from last xmitted end pdu */
259	int	clear_buffers;	/* flag */
260	int	credit;		/* send window not closed */
261	u_int	ll_busy;	/* lower layer busy */
262	u_int	rs_mr;		/* N(MR) in last RS PDU */
263	u_int	rs_sq;		/* N(SQ) in last RS PDU */
264	struct SSCOP_MBUF_T *uu_bgn;	/* last UU data */
265	struct SSCOP_MBUF_T *uu_bgak;	/*  ... */
266	struct SSCOP_MBUF_T *uu_bgrej;	/*  ... */
267	struct SSCOP_MBUF_T *uu_end;	/*  ... */
268	struct SSCOP_MBUF_T *uu_rs;	/*  ... */
269
270	/* signal queues */
271	sscop_sigq_head_t	sigs;		/* saved signals */
272	sscop_sigq_head_t	saved_sigs;	/* saved signals */
273	int	in_sig;		/* in signal handler */
274
275	/* debugging */
276	u_int		debug;
277
278	/* AA interface */
279	void		*aarg;
280};
281
282
283/*
284 * Default values for SSCOP
285 */
286enum {
287	MAXK		= 4096,
288	MAXMAXK		= 65528,
289	MAXJ		= 4096,
290	MAXMAXJ		= 65524,
291	MAXCC		= 4,
292	MAXSTAT		= 67,
293	MAXPD		= 25,
294	MAXMR		= 128,		/* ??? */
295	TIMERCC		= 1000,
296	TIMERKA		= 2000,
297	TIMERNR		= 7000,
298	TIMERPOLL	= 750,
299	TIMERIDLE	= 15000,
300};
301
302/*
303 * Sequence number arithmetic
304 */
305#define SEQNO_DIFF(A,B)  (((A) < (B)) ? ((A) + (1<<24) - (B)) : ((A) - (B)))
306
307/*
308 * Debugging
309 */
310#ifdef SSCOP_DEBUG
311#define VERBOSE(S,M,F)	if ((S)->debug & (M)) (S)->funcs->verbose F
312#define VERBERR(S,M,F)	if ((S)->debug & (M)) (S)->funcs->verbose F
313#define ISVERBOSE(S,M)	((S)->debug & (M))
314#else
315#define VERBOSE(S,M,F)
316#define VERBERR(S,M,F)
317#define ISVERBOSE(S,M)	(0)
318#endif
319