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