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 <[email protected]>
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  */
55 union 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  */
81 union 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  */
98 union 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  */
115 enum 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  */
138 enum 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  */
186 struct 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  */
197 struct 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  */
206 struct 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  */
286 enum {
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