/* * Copyright (c) 1996-2003 * Fraunhofer Institute for Open Communication Systems (FhG Fokus). * All rights reserved. * * 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. * * Author: Hartmut Brandt * * $Begemot: libunimsg/netnatm/saal/sscoppriv.h,v 1.4 2004/07/08 08:22:17 brandt Exp $ * * Private SSCOP definitions. * */ #ifdef _KERNEL #ifdef __FreeBSD__ #include #endif #else /* !_KERNEL */ #include "sscopcust.h" #endif /* Argh. BSDi */ #ifndef _BYTE_ORDER #ifndef BYTE_ORDER #error "_BYTE_ORDER not defined" #endif #define _BYTE_ORDER BYTE_ORDER #define _LITTLE_ENDIAN LITTLE_ENDIAN #define _BIG_ENDIAN BIG_ENDIAN #endif /* * PDU trailer */ union pdu { u_int sscop_null; struct { #if _BYTE_ORDER == _BIG_ENDIAN u_int pl : 2; /* pad length */ u_int : 1; /* reserved field */ u_int s : 1; /* source */ u_int type : 4; /* PDU type */ u_int ns : 24; /* sequence number */ #else u_int ns : 24; /* sequence number */ u_int type : 4; /* PDU type */ u_int s : 1; /* source */ u_int : 1; /* reserved field */ u_int pl : 2; /* pad length */ #endif } ss; }; #define sscop_pl ss.pl #define sscop_s ss.s #define sscop_type ss.type #define sscop_ns ss.ns /* * seqno list entry format */ union seqno { u_int sscop_null; struct { #if _BYTE_ORDER == _BIG_ENDIAN u_int : 8; /* pad */ u_int n : 24; /* seqno */ #else u_int n : 24; /* seqno */ u_int : 8; /* pad */ #endif } ss; }; #define sscop_n ss.n /* * Begin pdu */ union bgn { u_int sscop_null; struct { #if _BYTE_ORDER == _BIG_ENDIAN u_int : 24; /* reserved */ u_int bgns : 8; /* VT_MR */ #else u_int bgns : 8; /* VT_MR */ u_int : 24; /* reserved */ #endif } ss; }; #define sscop_bgns ss.bgns /* * pdu types */ enum pdu_type { PDU_BGN = 0x1, /* request initialization */ PDU_BGAK = 0x2, /* request acknowledgement */ PDU_END = 0x3, /* disconnect command */ PDU_ENDAK = 0x4, /* disconnect acknowledgement */ PDU_RS = 0x5, /* resynchronisation command */ PDU_RSAK = 0x6, /* resynchronisation acknowledgement */ PDU_BGREJ = 0x7, /* connection reject */ PDU_SD = 0x8, /* sequenced connection-mode data */ PDU_ER = 0x9, /* recovery command */ PDU_POLL = 0xa, /* xmit state info with req. for recv state */ PDU_STAT = 0xb, /* solicited receiver state info */ PDU_USTAT = 0xc, /* unsolicited receiver state info */ PDU_UD = 0xd, /* unumbered user data */ PDU_MD = 0xe, /* unumbered management data */ PDU_ERAK = 0xf, /* recovery acknowledgement */ }; /* * These are all signals, that are used by SSCOP. Don't change the order or * number without also changing the associated tables. */ enum sscop_sigtype { /* received PDU's */ SIG_BGN, /* request initialization */ SIG_BGAK, /* request acknowledgement */ SIG_END, /* disconnect command */ SIG_ENDAK, /* disconnect acknowledgement */ SIG_RS, /* resynchronisation command */ SIG_RSAK, /* resynchronisation acknowledgement */ SIG_BGREJ, /* connection reject */ SIG_SD, /* sequenced connection-mode data */ SIG_ER, /* recovery command */ SIG_POLL, /* xmitter state info with req for recv state */ SIG_STAT, /* solicited receiver state info */ SIG_USTAT, /* unsolicited receiver state info */ SIG_UD, /* unumbered user data */ SIG_MD, /* unumbered management data */ SIG_ERAK, /* recovery acknoledgement */ /* timer expiry */ SIG_T_CC, /* CC timer */ SIG_T_POLL, /* POLL timer */ SIG_T_KA, /* KEEP ALIVE timer */ SIG_T_NR, /* NO RESPONSE timer */ SIG_T_IDLE, /* IDLE timer */ /* user originated signals */ SIG_PDU_Q, /* PDU enqueued pseudosignal */ SIG_USER_DATA, /* user data request */ SIG_ESTAB_REQ, /* establish connection request */ SIG_ESTAB_RESP, /* establish connection response */ SIG_RELEASE_REQ, /* release connection request */ SIG_RECOVER, /* automatic recover response */ SIG_SYNC_REQ, /* resynchronisation request */ SIG_SYNC_RESP, /* resynchronisation response */ SIG_UDATA, /* UDATA request */ SIG_MDATA, /* MDATA request */ SIG_UPDU_Q, /* UDATA PDU enqueued pseudosignal */ SIG_MPDU_Q, /* MDATA PDU enqueued pseudosignal */ SIG_RETRIEVE, /* RETRIEVE */ /* number of signals */ SIG_NUM }; /* * This is a message as contained in a sscop message queue. It holds a pointer * to the real message. */ struct sscop_msg { sscop_msgq_link_t link; u_int seqno; /* seq no */ u_int poll_seqno; /* poll seqno (for messages in xmit buffer) */ u_int rexmit; /* in retransmission queue? */ struct SSCOP_MBUF_T *m; /* the message */ }; /* * This structure is used to hold signals in the signal queue */ struct sscop_sig { sscop_sigq_link_t link; /* next signal */ enum sscop_sigtype sig; /* THE signal */ struct sscop_msg *msg; /* signal argument (message) */ }; /* * This structure holds the entire sscop state */ struct sscop { enum sscop_state state; /* current state */ const struct sscop_funcs *funcs; /* send state */ u_int vt_s; /* seqno for next pdu first time transmitted */ u_int vt_ps; /* current poll seqno */ u_int vt_a; /* next expected in-sequence sd pdu */ u_int vt_pa; /* poll seqno of next stat pdu */ u_int vt_ms; /* maximum allowed send sd seqno */ u_int vt_pd; /* poll data state */ u_int vt_cc; /* connection control state */ u_int vt_sq; /* transmitter connection sequence */ /* receive state */ u_int vr_r; /* receive state */ u_int vr_h; /* highes expected state */ u_int vr_mr; /* maximum acceptable */ u_int vr_sq; /* receiver connection state */ /* timers */ sscop_timer_t t_cc; /* timer_CC */ sscop_timer_t t_nr; /* timer_NO_RESPONSE */ sscop_timer_t t_ka; /* timer KEEP_ALIVE */ sscop_timer_t t_poll; /* timer_POLL */ sscop_timer_t t_idle; /* idle timer */ /* maximum values */ u_int maxj; /* maximum uu-info */ u_int maxk; /* maximum info */ u_int maxcc; /* maximum number of bgn, end, er and rs */ u_int maxpd; /* maximum value of vt_pd */ u_int maxstat; /* maximum length of list */ u_int timercc; /* connection control timer */ u_int timerka; /* keep alive timer */ u_int timernr; /* no response timer */ u_int timerpoll; /* polling */ u_int timeridle; /* idle timer */ u_int robustness; /* atmf/97-0216 robustness enhancement */ u_int poll_after_rex; /* optional POLL after re-transmission */ u_int mr; /* initial window */ /* * buffers and queues. * All expect the xq hold SD PDUs. */ sscop_msgq_head_t xq; /* xmit queue (input from user before xmit) */ sscop_msgq_head_t uxq; /* UD xmit queue */ sscop_msgq_head_t mxq; /* MD xmit queue */ sscop_msgq_head_t xbuf; /* transmission buffer (SD PDUs transmitted) */ int rxq; /* number of PDUs in retransmission queue */ sscop_msgq_head_t rbuf; /* receive buffer (SD PDUs) */ int last_end_src; /* source field from last xmitted end pdu */ int clear_buffers; /* flag */ int credit; /* send window not closed */ u_int ll_busy; /* lower layer busy */ u_int rs_mr; /* N(MR) in last RS PDU */ u_int rs_sq; /* N(SQ) in last RS PDU */ struct SSCOP_MBUF_T *uu_bgn; /* last UU data */ struct SSCOP_MBUF_T *uu_bgak; /* ... */ struct SSCOP_MBUF_T *uu_bgrej; /* ... */ struct SSCOP_MBUF_T *uu_end; /* ... */ struct SSCOP_MBUF_T *uu_rs; /* ... */ /* signal queues */ sscop_sigq_head_t sigs; /* saved signals */ sscop_sigq_head_t saved_sigs; /* saved signals */ int in_sig; /* in signal handler */ /* debugging */ u_int debug; /* AA interface */ void *aarg; }; /* * Default values for SSCOP */ enum { MAXK = 4096, MAXMAXK = 65528, MAXJ = 4096, MAXMAXJ = 65524, MAXCC = 4, MAXSTAT = 67, MAXPD = 25, MAXMR = 128, /* ??? */ TIMERCC = 1000, TIMERKA = 2000, TIMERNR = 7000, TIMERPOLL = 750, TIMERIDLE = 15000, }; /* * Sequence number arithmetic */ #define SEQNO_DIFF(A,B) (((A) < (B)) ? ((A) + (1<<24) - (B)) : ((A) - (B))) /* * Debugging */ #ifdef SSCOP_DEBUG #define VERBOSE(S,M,F) if ((S)->debug & (M)) (S)->funcs->verbose F #define VERBERR(S,M,F) if ((S)->debug & (M)) (S)->funcs->verbose F #define ISVERBOSE(S,M) ((S)->debug & (M)) #else #define VERBOSE(S,M,F) #define VERBERR(S,M,F) #define ISVERBOSE(S,M) (0) #endif