2 * Copyright (c) 1996-2003
3 * Fraunhofer Institute for Open Communication Systems (FhG Fokus).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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.
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
27 * Author: Hartmut Brandt <harti@freebsd.org>
29 * $Begemot: libunimsg/netnatm/saal/saal_sscop.c,v 1.11 2004/07/08 08:22:13 brandt Exp $
31 * Core SSCOP code (ITU-T Q.2110)
34 #include <netnatm/saal/sscop.h>
35 #include <netnatm/saal/sscoppriv.h>
43 static const char *const sscop_sigs[] = {
44 MKSTR(SSCOP_ESTABLISH_request),
45 MKSTR(SSCOP_ESTABLISH_indication),
46 MKSTR(SSCOP_ESTABLISH_response),
47 MKSTR(SSCOP_ESTABLISH_confirm),
48 MKSTR(SSCOP_RELEASE_request),
49 MKSTR(SSCOP_RELEASE_indication),
50 MKSTR(SSCOP_RELEASE_confirm),
51 MKSTR(SSCOP_DATA_request),
52 MKSTR(SSCOP_DATA_indication),
53 MKSTR(SSCOP_UDATA_request),
54 MKSTR(SSCOP_UDATA_indication),
55 MKSTR(SSCOP_RECOVER_indication),
56 MKSTR(SSCOP_RECOVER_response),
57 MKSTR(SSCOP_RESYNC_request),
58 MKSTR(SSCOP_RESYNC_indication),
59 MKSTR(SSCOP_RESYNC_response),
60 MKSTR(SSCOP_RESYNC_confirm),
61 MKSTR(SSCOP_RETRIEVE_request),
62 MKSTR(SSCOP_RETRIEVE_indication),
63 MKSTR(SSCOP_RETRIEVE_COMPL_indication),
66 static const char *const sscop_msigs[] = {
67 MKSTR(SSCOP_MDATA_request),
68 MKSTR(SSCOP_MDATA_indication),
69 MKSTR(SSCOP_MERROR_indication),
72 static const char *const states[] = {
74 MKSTR(SSCOP_OUT_PEND),
76 MKSTR(SSCOP_OUT_DIS_PEND),
77 MKSTR(SSCOP_OUT_RESYNC_PEND),
78 MKSTR(SSCOP_IN_RESYNC_PEND),
79 MKSTR(SSCOP_OUT_REC_PEND),
80 MKSTR(SSCOP_REC_PEND),
81 MKSTR(SSCOP_IN_REC_PEND),
86 static const char *const events[] = {
110 MKSTR(SIG_USER_DATA),
111 MKSTR(SIG_ESTAB_REQ),
112 MKSTR(SIG_ESTAB_RESP),
113 MKSTR(SIG_RELEASE_REQ),
116 MKSTR(SIG_SYNC_RESP),
124 static const char *const pdus[] = {
125 "illegale PDU type 0", /* no PDU type 0 */
146 static void sscop_signal(struct sscop *, u_int, struct sscop_msg *);
147 static void sscop_save_signal(struct sscop *, u_int, struct sscop_msg *);
148 static void handle_sigs(struct sscop *);
149 static void sscop_set_state(struct sscop *, u_int);
151 /************************************************************/
154 /************************************************************/
158 #define SSCOP_MSG_FREE(MSG) \
161 MBUF_FREE((MSG)->m); \
167 #define QFIND(Q,RN) \
169 struct sscop_msg *_msg = NULL, *_m; \
170 MSGQ_FOREACH(_m, (Q)) { \
171 if(_m->seqno == (RN)) { \
179 #define QINSERT(Q,M) \
181 struct sscop_msg *_msg = NULL, *_m; \
182 MSGQ_FOREACH(_m, (Q)) { \
183 if (_m->seqno > (M)->seqno) { \
189 MSGQ_INSERT_BEFORE(_msg, (M)); \
191 MSGQ_APPEND((Q), (M)); \
196 * Send an error indication to the management plane.
198 #define MAAL_ERROR(S,E,C) \
200 VERBOSE(S, SSCOP_DBG_USIG, ((S), (S)->aarg, \
201 "MAA-Signal %s in state %s", \
202 sscop_msigs[SSCOP_MERROR_indication], states[(S)->state])); \
203 (S)->funcs->send_manage((S), (S)->aarg, \
204 SSCOP_MERROR_indication, NULL, (E), (C)); \
207 #define MAAL_DATA(S,M) \
209 VERBOSE(S, SSCOP_DBG_USIG, ((S), (S)->aarg, \
210 "MAA-Signal %s in state %s", \
211 sscop_msigs[SSCOP_MDATA_indication], states[(S)->state])); \
212 (S)->funcs->send_manage((S), (S)->aarg, \
213 SSCOP_MDATA_indication, (M), 0, 0); \
216 #define AAL_DATA(S,D,M,N) \
218 VERBOSE(S, SSCOP_DBG_USIG, ((S), (S)->aarg, \
219 "AA-Signal %s in state %s", \
220 sscop_sigs[D], states[(S)->state])); \
221 (S)->funcs->send_upper((S), (S)->aarg, (D), (M), (N)); \
224 #define AAL_SIG(S,D) \
226 VERBOSE(S, SSCOP_DBG_USIG, ((S), (S)->aarg, \
227 "AA-Signal %s in state %s", \
228 sscop_sigs[D], states[(S)->state])); \
229 (S)->funcs->send_upper((S), (S)->aarg, (D), NULL, 0); \
233 #define AAL_SEND(S,M) do { \
234 if (ISVERBOSE(S, SSCOP_DBG_PDU)) \
235 sscop_dump_pdu(S, "tx", (M)); \
236 (S)->funcs->send_lower((S), (S)->aarg, (M)); \
239 #define AAL_SEND(S,M) (S)->funcs->send_lower((S), (S)->aarg, (M))
244 * Free a save user-to-user data buffer and set the pointer to zero
245 * to signal, that it is free.
250 MBUF_FREE(sscop->F); \
255 #define SET_UU(F,U) \
263 #define AAL_UU_SIGNAL(S, SIG, M, PL, SN) \
265 if(MBUF_LEN((M)->m) > 0) { \
266 MBUF_UNPAD((M)->m,(PL)); \
267 AAL_DATA((S), (SIG), (M)->m, (SN)); \
270 AAL_DATA((S), (SIG), NULL, (SN)); \
272 SSCOP_MSG_FREE((M)); \
280 TIMER_FUNC(poll, POLL)
281 TIMER_FUNC(idle, IDLE)
283 /************************************************************/
285 * INSTANCE AND TYPE HANDLING.
289 sscop_dump_pdu(struct sscop *sscop, const char *dir,
290 const struct SSCOP_MBUF_T *m)
292 u_int32_t v1, v2, v3, v4;
293 u_int size = MBUF_LEN(m);
299 v1 = MBUF_TRAIL32(m, -1);
300 v2 = MBUF_TRAIL32(m, -2);
302 switch ((v1 >> 24) & 0xf) {
308 sscop->funcs->verbose(sscop, sscop->aarg,
309 "%s BGN n(mr)=%u n(sq)=%u pl=%u",
310 dir, v1 & 0xffffff, v2 & 0xff, (v1 >> 30) & 0x3);
314 sscop->funcs->verbose(sscop, sscop->aarg,
315 "%s BGAK n(mr)=%u pl=%u",
316 dir, v1 & 0xffffff, (v1 >> 30) & 0x3);
320 sscop->funcs->verbose(sscop, sscop->aarg,
321 "%s END r=%u s=%u pl=%u",
322 dir, (v1 >> 29) & 1, (v1 >> 28) & 1, (v1 >> 30) & 0x3);
326 sscop->funcs->verbose(sscop, sscop->aarg, "%s ENDAK", dir);
330 sscop->funcs->verbose(sscop, sscop->aarg,
331 "%s RS n(mr)=%u n(sq)=%u pl=%u",
332 dir, v1 & 0xffffff, v2 & 0xff, (v1 >> 30) & 0x3);
336 sscop->funcs->verbose(sscop, sscop->aarg, "%s RSAK n(mr)=%u",
341 sscop->funcs->verbose(sscop, sscop->aarg, "%s BGREJ pl=%u",
342 dir, (v1 >> 30) & 0x3);
346 sscop->funcs->verbose(sscop, sscop->aarg, "%s SD n(s)=%u pl=%u",
347 dir, v1 & 0xffffff, (v1 >> 30) & 0x3);
351 sscop->funcs->verbose(sscop, sscop->aarg, "%s ER n(mr)=%u n(sq)=%u",
352 dir, v1 & 0xffffff, v2 & 0xff);
356 sscop->funcs->verbose(sscop, sscop->aarg, "%s POLL n(s)=%u n(ps)=%u",
357 dir, v1 & 0xffffff, v2 & 0xffffff);
363 v3 = MBUF_TRAIL32(m, -3);
364 sscop->funcs->verbose(sscop, sscop->aarg,
365 "%s STAT n(r)=%u n(mr)=%u n(ps)=%u",
366 dir, v1 & 0xffffff, v2 & 0xffffff, v3 & 0xffffff);
368 for (i = 0; i < (size - 12) / 4; i++, n--) {
369 v4 = MBUF_TRAIL32(m, -4 - (int)i);
370 sscop->funcs->verbose(sscop, sscop->aarg,
371 " LE(%u)=%u", n, v4 & 0xffffff);
378 sscop->funcs->verbose(sscop, sscop->aarg,
379 "%s STAT n(r)=%u n(mr)=%u LE1=%u LE2=%u",
380 dir, v1 & 0xffffff, v2 & 0xffffff,
381 MBUF_TRAIL32(m, -4) & 0xffffff,
382 MBUF_TRAIL32(m, -3) & 0xffffff);
386 sscop->funcs->verbose(sscop, sscop->aarg,
387 "%s UD pl=%u", dir, (v1 >> 30) & 0x3);
391 sscop->funcs->verbose(sscop, sscop->aarg,
392 "%s MD pl=%u", dir, (v1 >> 30) & 0x3);
396 sscop->funcs->verbose(sscop, sscop->aarg,
397 "%s ERAK n(mr)=%u", dir, v1 & 0xffffff);
405 * Initialize state of variables
408 sscop_init(struct sscop *sscop)
410 sscop->state = SSCOP_IDLE;
414 sscop->clear_buffers = 1;
422 sscop_clear(struct sscop *sscop)
424 TIMER_STOP(sscop, cc);
425 TIMER_STOP(sscop, ka);
426 TIMER_STOP(sscop, nr);
427 TIMER_STOP(sscop, idle);
428 TIMER_STOP(sscop, poll);
436 MSGQ_CLEAR(&sscop->xq);
437 MSGQ_CLEAR(&sscop->uxq);
438 MSGQ_CLEAR(&sscop->mxq);
439 MSGQ_CLEAR(&sscop->xbuf);
440 MSGQ_CLEAR(&sscop->rbuf);
442 SIGQ_CLEAR(&sscop->sigs);
443 SIGQ_CLEAR(&sscop->saved_sigs);
448 * Allocate instance memory, initialize the state of all variables.
451 sscop_create(void *a, const struct sscop_funcs *funcs)
455 MEMZALLOC(sscop, struct sscop *, sizeof(struct sscop));
463 sscop->funcs = funcs;
467 sscop->maxcc = MAXCC;
468 sscop->maxpd = MAXPD;
469 sscop->maxstat = MAXSTAT;
470 sscop->timercc = TIMERCC;
471 sscop->timerka = TIMERKA;
472 sscop->timernr = TIMERNR;
473 sscop->timerpoll = TIMERPOLL;
474 sscop->timeridle = TIMERIDLE;
475 sscop->robustness = 0;
476 sscop->poll_after_rex = 0;
479 TIMER_INIT(sscop, cc);
480 TIMER_INIT(sscop, nr);
481 TIMER_INIT(sscop, ka);
482 TIMER_INIT(sscop, poll);
483 TIMER_INIT(sscop, idle);
485 MSGQ_INIT(&sscop->xq);
486 MSGQ_INIT(&sscop->uxq);
487 MSGQ_INIT(&sscop->mxq);
488 MSGQ_INIT(&sscop->rbuf);
489 MSGQ_INIT(&sscop->xbuf);
491 SIGQ_INIT(&sscop->sigs);
492 SIGQ_INIT(&sscop->saved_sigs);
500 * Free all resources in a sscop instance
503 sscop_destroy(struct sscop *sscop)
511 * Reset the SSCOP instance.
514 sscop_reset(struct sscop *sscop)
521 sscop_getparam(const struct sscop *sscop, struct sscop_param *p)
523 p->timer_cc = sscop->timercc;
524 p->timer_poll = sscop->timerpoll;
525 p->timer_keep_alive = sscop->timerka;
526 p->timer_no_response = sscop->timernr;
527 p->timer_idle = sscop->timeridle;
528 p->maxk = sscop->maxk;
529 p->maxj = sscop->maxj;
530 p->maxcc = sscop->maxcc;
531 p->maxpd = sscop->maxpd;
532 p->maxstat = sscop->maxstat;
535 if(sscop->robustness)
536 p->flags |= SSCOP_ROBUST;
537 if(sscop->poll_after_rex)
538 p->flags |= SSCOP_POLLREX;
542 sscop_setparam(struct sscop *sscop, struct sscop_param *p, u_int *pmask)
546 /* can change only in idle state */
547 if (sscop->state != SSCOP_IDLE)
553 * first check all parameters
555 if ((mask & SSCOP_SET_TCC) && p->timer_cc == 0)
556 *pmask |= SSCOP_SET_TCC;
557 if ((mask & SSCOP_SET_TPOLL) && p->timer_poll == 0)
558 *pmask |= SSCOP_SET_TPOLL;
559 if ((mask & SSCOP_SET_TKA) && p->timer_keep_alive == 0)
560 *pmask |= SSCOP_SET_TKA;
561 if ((mask & SSCOP_SET_TNR) && p->timer_no_response == 0)
562 *pmask |= SSCOP_SET_TNR;
563 if ((mask & SSCOP_SET_TIDLE) && p->timer_idle == 0)
564 *pmask |= SSCOP_SET_TIDLE;
565 if ((mask & SSCOP_SET_MAXK) && p->maxk > MAXMAXK)
566 *pmask |= SSCOP_SET_MAXK;
567 if ((mask & SSCOP_SET_MAXJ) && p->maxj > MAXMAXJ)
568 *pmask |= SSCOP_SET_MAXJ;
569 if ((mask & SSCOP_SET_MAXCC) && p->maxcc > 255)
570 *pmask |= SSCOP_SET_MAXCC;
571 if ((mask & SSCOP_SET_MAXPD) && p->maxpd >= (1 << 24))
572 *pmask |= SSCOP_SET_MAXPD;
573 if ((mask & SSCOP_SET_MAXSTAT) &&
574 ((p->maxstat & 1) == 0 || p->maxstat == 1 || p->maxstat == 2 ||
575 p->maxstat * 4 > MAXMAXK - 8))
576 *pmask |= SSCOP_SET_MAXSTAT;
577 if ((mask & SSCOP_SET_MR) && p->mr >= (1 << 24) - 1)
578 *pmask |= SSCOP_SET_MR;
587 if (mask & SSCOP_SET_TCC)
588 sscop->timercc = p->timer_cc;
590 if (mask & SSCOP_SET_TPOLL)
591 sscop->timerpoll = p->timer_poll;
593 if (mask & SSCOP_SET_TKA)
594 sscop->timerka = p->timer_keep_alive;
596 if (mask & SSCOP_SET_TNR)
597 sscop->timernr = p->timer_no_response;
599 if (mask & SSCOP_SET_TIDLE)
600 sscop->timeridle = p->timer_idle;
602 if (mask & SSCOP_SET_MAXK)
603 sscop->maxk = p->maxk;
604 if (mask & SSCOP_SET_MAXJ)
605 sscop->maxj = p->maxj;
607 if (mask & SSCOP_SET_MAXCC)
608 sscop->maxcc = p->maxcc;
609 if (mask & SSCOP_SET_MAXPD)
610 sscop->maxpd = p->maxpd;
611 if (mask & SSCOP_SET_MAXSTAT)
612 sscop->maxstat = p->maxstat;
614 if (mask & SSCOP_SET_MR)
617 if (mask & SSCOP_SET_ROBUST)
618 sscop->robustness = ((p->flags & SSCOP_ROBUST) != 0);
620 if (mask & SSCOP_SET_POLLREX)
621 sscop->poll_after_rex = ((p->flags & SSCOP_POLLREX) != 0);
627 sscop_getstate(const struct sscop *sscop)
629 return (sscop->state);
633 /************************************************************/
635 * EXTERNAL INPUT SIGNAL MAPPING
639 * Map AA signal to SSCOP internal signal
642 sscop_aasig(struct sscop *sscop, enum sscop_aasig sig,
643 struct SSCOP_MBUF_T *m, u_int arg)
645 struct sscop_msg *msg;
647 if (sig >= sizeof(sscop_sigs)/sizeof(sscop_sigs[0])) {
648 VERBOSE(sscop, SSCOP_DBG_INSIG, (sscop, sscop->aarg,
649 "AA-Signal %u - bad signal", sig));
653 VERBOSE(sscop, SSCOP_DBG_INSIG, (sscop, sscop->aarg,
654 "AA-Signal %s in state %s with%s message",
655 sscop_sigs[sig], states[sscop->state], m ? "" : "out"));
659 FAILURE("sscop: cannot allocate aasig");
666 case SSCOP_ESTABLISH_request:
669 sscop_signal(sscop, SIG_ESTAB_REQ, msg);
672 case SSCOP_ESTABLISH_response:
675 sscop_signal(sscop, SIG_ESTAB_RESP, msg);
678 case SSCOP_RELEASE_request:
680 sscop_signal(sscop, SIG_RELEASE_REQ, msg);
683 case SSCOP_DATA_request:
685 sscop_signal(sscop, SIG_USER_DATA, msg);
688 case SSCOP_UDATA_request:
690 sscop_signal(sscop, SIG_UDATA, msg);
693 case SSCOP_RECOVER_response:
696 sscop_signal(sscop, SIG_RECOVER, NULL);
699 case SSCOP_RESYNC_request:
701 sscop_signal(sscop, SIG_SYNC_REQ, msg);
704 case SSCOP_RESYNC_response:
707 sscop_signal(sscop, SIG_SYNC_RESP, NULL);
710 case SSCOP_RETRIEVE_request:
713 sscop_signal(sscop, SIG_RETRIEVE, msg);
716 case SSCOP_ESTABLISH_indication:
717 case SSCOP_ESTABLISH_confirm:
718 case SSCOP_RELEASE_indication:
719 case SSCOP_RELEASE_confirm:
720 case SSCOP_DATA_indication:
721 case SSCOP_UDATA_indication:
722 case SSCOP_RECOVER_indication:
723 case SSCOP_RESYNC_indication:
724 case SSCOP_RESYNC_confirm:
725 case SSCOP_RETRIEVE_indication:
726 case SSCOP_RETRIEVE_COMPL_indication:
736 * Signal from layer management.
739 sscop_maasig(struct sscop *sscop, enum sscop_maasig sig, struct SSCOP_MBUF_T *m)
741 struct sscop_msg *msg;
743 if (sig >= sizeof(sscop_msigs)/sizeof(sscop_msigs[0])) {
744 VERBOSE(sscop, SSCOP_DBG_INSIG, (sscop, sscop->aarg,
745 "MAA-Signal %u - bad signal", sig));
749 VERBOSE(sscop, SSCOP_DBG_INSIG, (sscop, sscop->aarg,
750 "MAA-Signal %s in state %s with%s message",
751 sscop_msigs[sig], states[sscop->state], m ? "" : "out"));
755 FAILURE("sscop: cannot allocate maasig");
762 case SSCOP_MDATA_request:
764 sscop_signal(sscop, SIG_MDATA, msg);
767 case SSCOP_MDATA_indication:
768 case SSCOP_MERROR_indication:
777 * Map PDU to SSCOP signal.
780 sscop_input(struct sscop *sscop, struct SSCOP_MBUF_T *m)
782 struct sscop_msg *msg;
788 FAILURE("sscop: cannot allocate in pdu msg");
798 if(size % 4 != 0 || size < 4)
801 pdu.sscop_null = MBUF_TRAIL32(m, -1);
803 VERBOSE(sscop, SSCOP_DBG_PDU, (sscop, sscop->aarg,
804 "got %s, size=%u", pdus[pdu.sscop_type], size));
807 #define ENSURE(C,F) if(!(C)) { VERBOSE(sscop, SSCOP_DBG_PDU, F); goto err; }
809 #define ENSURE(C,F) if(!(C)) goto err
813 if (ISVERBOSE(sscop, SSCOP_DBG_PDU))
814 sscop_dump_pdu(sscop, "rx", m);
817 switch(pdu.sscop_type) {
820 ENSURE(0, (sscop, sscop->aarg,
821 "Bad PDU type %u", pdu.sscop_type));
825 ENSURE(size >= 8U, (sscop, sscop->aarg,
826 "PDU_BGN size=%u", size));
827 ENSURE(size >= 8U + pdu.sscop_pl, (sscop, sscop->aarg,
828 "PDU_BGN size=%u pl=%u", size, pdu.sscop_pl));
829 ENSURE(size <= 8U + sscop->maxj, (sscop, sscop->aarg,
830 "PDU_BGN size=%u", size));
831 sscop_signal(sscop, SIG_BGN, msg);
835 ENSURE(size >= 8U, (sscop, sscop->aarg,
836 "PDU_BGAK size=%u", size));
837 ENSURE(size >= 8U + pdu.sscop_pl, (sscop, sscop->aarg,
838 "PDU_BGAK size=%u pl=%u", size, pdu.sscop_pl));
839 ENSURE(size <= 8U + sscop->maxj, (sscop, sscop->aarg,
840 "PDU_BGAK size=%u", size));
841 sscop_signal(sscop, SIG_BGAK, msg);
845 ENSURE(size >= 8U, (sscop, sscop->aarg,
846 "PDU_END size=%u", size));
847 ENSURE(size >= 8U + pdu.sscop_pl, (sscop, sscop->aarg,
848 "PDU_END size=%u pl=%u", size, pdu.sscop_pl));
849 ENSURE(size <= 8U + sscop->maxj, (sscop, sscop->aarg,
850 "PDU_END size=%u", size));
851 sscop_signal(sscop, SIG_END, msg);
855 ENSURE(size == 8U, (sscop, sscop->aarg,
856 "PDU_ENDAK size=%u", size));
857 sscop_signal(sscop, SIG_ENDAK, msg);
861 ENSURE(size >= 8U, (sscop, sscop->aarg,
862 "PDU_BGREJ size=%u", size));
863 ENSURE(size >= 8U + pdu.sscop_pl, (sscop, sscop->aarg,
864 "PDU_BGREJ size=%u pl=%u", size, pdu.sscop_pl));
865 ENSURE(size <= 8U + sscop->maxj, (sscop, sscop->aarg,
866 "PDU_BGREJ size=%u", size));
867 sscop_signal(sscop, SIG_BGREJ, msg);
871 ENSURE(size >= 4U + pdu.sscop_pl, (sscop, sscop->aarg,
872 "PDU_SD size=%u pl=%u", size, pdu.sscop_pl));
873 ENSURE(size <= 4U + sscop->maxk, (sscop, sscop->aarg,
874 "PDU_SD size=%u", size));
875 sscop_signal(sscop, SIG_SD, msg);
879 ENSURE(size >= 4U + pdu.sscop_pl, (sscop, sscop->aarg,
880 "PDU_UD size=%u pl=%u", size, pdu.sscop_pl));
881 ENSURE(size <= 4U + sscop->maxk, (sscop, sscop->aarg,
882 "PDU_UD size=%u", size));
883 sscop_signal(sscop, SIG_UD, msg);
887 ENSURE(size >= 4U + pdu.sscop_pl, (sscop, sscop->aarg,
888 "PDU_MD size=%u pl=%u", size, pdu.sscop_pl));
889 ENSURE(size <= 4U + sscop->maxk, (sscop, sscop->aarg,
890 "PDU_MD size=%u", size));
891 sscop_signal(sscop, SIG_MD, msg);
895 ENSURE(size == 8U, (sscop, sscop->aarg,
896 "PDU_POLL size=%u", size));
897 sscop_signal(sscop, SIG_POLL, msg);
901 ENSURE(size >= 12U, (sscop, sscop->aarg,
902 "PDU_STAT size=%u", size));
903 ENSURE(size <= 12U + 4 * sscop->maxstat, (sscop, sscop->aarg,
904 "PDU_STAT size=%u", size));
905 sscop_signal(sscop, SIG_STAT, msg);
909 ENSURE(size >= 8U, (sscop, sscop->aarg,
910 "PDU_RS size=%u", size));
911 ENSURE(size >= 8U + pdu.sscop_pl, (sscop, sscop->aarg,
912 "PDU_RS size=%u pl=%u", size, pdu.sscop_pl));
913 ENSURE(size <= 8U + sscop->maxj, (sscop, sscop->aarg,
914 "PDU_RS size=%u", size));
915 sscop_signal(sscop, SIG_RS, msg);
919 ENSURE(size == 8U, (sscop, sscop->aarg,
920 "PDU_RSAK size=%u", size));
921 sscop_signal(sscop, SIG_RSAK, msg);
925 ENSURE(size == 8U, (sscop, sscop->aarg,
926 "PDU_ER size=%u", size));
927 sscop_signal(sscop, SIG_ER, msg);
931 ENSURE(size == 8U, (sscop, sscop->aarg,
932 "PDU_ERAK size=%u", size));
933 sscop_signal(sscop, SIG_ERAK, msg);
937 ENSURE(size == 16U, (sscop, sscop->aarg,
938 "PDU_ERAK size=%u", size));
939 sscop_signal(sscop, SIG_USTAT, msg);
946 MAAL_ERROR(sscop, 'U', 0);
950 /************************************************************/
956 * Move the receiver window by N packets
959 sscop_window(struct sscop *sscop, u_int n)
962 return (SEQNO_DIFF(sscop->vr_mr, sscop->vr_r));
966 * Lower layer busy handling
969 sscop_setbusy(struct sscop *sscop, int busy)
971 u_int old = sscop->ll_busy;
975 else if (busy == 0) {
985 sscop_signame(enum sscop_aasig sig)
989 if (sig >= sizeof(sscop_sigs)/sizeof(sscop_sigs[0])) {
990 sprintf(str, "BAD SSCOP_AASIG %u", sig);
993 return (sscop_sigs[sig]);
998 sscop_msigname(enum sscop_maasig sig)
1000 static char str[40];
1002 if (sig >= sizeof(sscop_msigs)/sizeof(sscop_msigs[0])) {
1003 sprintf(str, "BAD SSCOP_MAASIG %u", sig);
1006 return (sscop_msigs[sig]);
1011 sscop_statename(enum sscop_state s)
1013 static char str[40];
1015 if (s >= sizeof(states)/sizeof(states[0])) {
1016 sprintf(str, "BAD SSCOP_STATE %u", s);
1024 /************************************************************/
1030 * p 75: release buffers
1033 m_release_buffers(struct sscop *sscop)
1035 MSGQ_CLEAR(&sscop->xq);
1036 MSGQ_CLEAR(&sscop->xbuf);
1038 MSGQ_CLEAR(&sscop->rbuf);
1042 * P 75: Prepare retrival
1045 m_prepare_retrieval(struct sscop *sscop)
1047 struct sscop_msg *msg;
1049 if (sscop->clear_buffers) {
1050 MSGQ_CLEAR(&sscop->xq);
1051 MSGQ_CLEAR(&sscop->xbuf);
1053 MSGQ_FOREACH(msg, &sscop->xbuf)
1057 MSGQ_CLEAR(&sscop->rbuf);
1061 * P 75: Prepare retrival
1064 m_prepare_recovery(struct sscop *sscop)
1066 struct sscop_msg *msg;
1068 if(sscop->clear_buffers) {
1069 MSGQ_CLEAR(&sscop->xq);
1070 MSGQ_CLEAR(&sscop->xbuf);
1072 MSGQ_FOREACH(msg, &sscop->xbuf)
1079 * P 75: Clear transmitter
1082 m_clear_transmitter(struct sscop *sscop)
1084 if(!sscop->clear_buffers) {
1085 MSGQ_CLEAR(&sscop->xq);
1086 MSGQ_CLEAR(&sscop->xbuf);
1092 * p 75: Deliver data
1093 * Freeing the message is the responibility of the handler function.
1096 m_deliver_data(struct sscop *sscop)
1098 struct sscop_msg *msg;
1101 if ((msg = MSGQ_GET(&sscop->rbuf)) == NULL)
1104 if (sscop->clear_buffers) {
1105 MSGQ_CLEAR(&sscop->rbuf);
1109 sn = msg->seqno + 1;
1110 AAL_DATA(sscop, SSCOP_DATA_indication, msg->m, msg->seqno);
1113 while ((msg = MSGQ_GET(&sscop->rbuf)) != NULL) {
1114 ASSERT(msg->seqno == sn);
1115 if (++sn == SSCOP_MAXSEQNO)
1117 AAL_DATA(sscop, SSCOP_DATA_indication, msg->m, msg->seqno);
1123 * P 75: Initialize state variables
1126 m_initialize_state(struct sscop *sscop)
1141 * p 76: Data retrieval
1144 m_data_retrieval(struct sscop *sscop, u_int rn)
1146 struct sscop_msg *s;
1148 if (rn != SSCOP_RETRIEVE_UNKNOWN) {
1149 if(rn >= SSCOP_RETRIEVE_TOTAL)
1153 while(rn >= sscop->vt_a && rn < sscop->vt_s) {
1154 if(rn == SSCOP_MAXSEQNO) rn = 0;
1155 if((s = QFIND(&sscop->xbuf, rn)) != NULL) {
1156 MSGQ_REMOVE(&sscop->xbuf, s);
1157 AAL_DATA(sscop, SSCOP_RETRIEVE_indication,
1165 while((s = MSGQ_GET(&sscop->xq)) != NULL) {
1166 AAL_DATA(sscop, SSCOP_RETRIEVE_indication, s->m, 0);
1169 AAL_SIG(sscop, SSCOP_RETRIEVE_COMPL_indication);
1173 * P 76: Detect retransmission. PDU type must already be stripped.
1176 m_detect_retransmission(struct sscop *sscop, struct sscop_msg *msg)
1180 bgn.sscop_null = MBUF_TRAIL32(msg->m, -1);
1182 if (sscop->vr_sq == bgn.sscop_bgns)
1185 sscop->vr_sq = bgn.sscop_bgns;
1190 * P 76: Set POLL timer
1193 m_set_poll_timer(struct sscop *sscop)
1195 if(MSGQ_EMPTY(&sscop->xq) && sscop->vt_s == sscop->vt_a)
1196 TIMER_RESTART(sscop, ka);
1198 TIMER_RESTART(sscop, poll);
1202 * P 77: Reset data transfer timers
1205 m_reset_data_xfer_timers(struct sscop *sscop)
1207 TIMER_STOP(sscop, ka);
1208 TIMER_STOP(sscop, nr);
1209 TIMER_STOP(sscop, idle);
1210 TIMER_STOP(sscop, poll);
1214 * P 77: Set data transfer timers
1217 m_set_data_xfer_timers(struct sscop *sscop)
1219 TIMER_RESTART(sscop, poll);
1220 TIMER_RESTART(sscop, nr);
1224 * P 77: Initialize VR(MR)
1227 m_initialize_mr(struct sscop *sscop)
1229 sscop->vr_mr = sscop->mr;
1232 /************************************************************/
1237 c_ready_pduq(struct sscop *sscop)
1239 if (!sscop->ll_busy &&
1241 sscop->vt_s < sscop->vt_ms ||
1242 TIMER_ISACT(sscop, idle)))
1247 /************************************************************/
1256 send_bgn(struct sscop *sscop, struct SSCOP_MBUF_T *uu)
1260 struct SSCOP_MBUF_T *m;
1263 pdu.sscop_type = PDU_BGN;
1264 pdu.sscop_ns = sscop->vr_mr;
1267 bgn.sscop_bgns = sscop->vt_sq;
1270 if ((m = MBUF_DUP(uu)) == NULL) {
1271 FAILURE("sscop: cannot allocate BGN");
1274 pdu.sscop_pl += MBUF_PAD4(m);
1276 if ((m = MBUF_ALLOC(8)) == NULL) {
1277 FAILURE("sscop: cannot allocate BGN");
1282 MBUF_APPEND32(m, bgn.sscop_null);
1283 MBUF_APPEND32(m, pdu.sscop_null);
1292 send_bgrej(struct sscop *sscop, struct SSCOP_MBUF_T *uu)
1296 struct SSCOP_MBUF_T *m;
1299 pdu.sscop_type = PDU_BGREJ;
1303 if((m = MBUF_DUP(uu)) == NULL) {
1304 FAILURE("sscop: cannot allocate BGREJ");
1307 pdu.sscop_pl += MBUF_PAD4(m);
1309 if((m = MBUF_ALLOC(8)) == NULL) {
1310 FAILURE("sscop: cannot allocate BGREJ");
1315 MBUF_APPEND32(m, bgn.sscop_null);
1316 MBUF_APPEND32(m, pdu.sscop_null);
1325 send_bgak(struct sscop *sscop, struct SSCOP_MBUF_T *uu)
1329 struct SSCOP_MBUF_T *m;
1332 pdu.sscop_type = PDU_BGAK;
1333 pdu.sscop_ns = sscop->vr_mr;
1337 if((m = MBUF_DUP(uu)) == NULL) {
1338 FAILURE("sscop: cannot allocate BGAK");
1341 pdu.sscop_pl += MBUF_PAD4(m);
1343 if((m = MBUF_ALLOC(8)) == NULL) {
1344 FAILURE("sscop: cannot allocate BGAK");
1349 MBUF_APPEND32(m, bgn.sscop_null);
1350 MBUF_APPEND32(m, pdu.sscop_null);
1356 * Send SD PDU. The function makes a duplicate of the message.
1359 send_sd(struct sscop *sscop, struct SSCOP_MBUF_T *m, u_int seqno)
1363 if((m = MBUF_DUP(m)) == NULL) {
1364 FAILURE("sscop: cannot allocate SD");
1370 pdu.sscop_type = PDU_SD;
1371 pdu.sscop_ns = seqno;
1373 pdu.sscop_pl += MBUF_PAD4(m);
1375 MBUF_APPEND32(m, pdu.sscop_null);
1381 * Send a UD PDU. The caller must free the sscop msg part.
1384 send_ud(struct sscop *sscop, struct SSCOP_MBUF_T *m)
1389 pdu.sscop_type = PDU_UD;
1391 pdu.sscop_pl += MBUF_PAD4(m);
1393 MBUF_APPEND32(m, pdu.sscop_null);
1399 * Send a MD PDU. The caller must free the sscop msg part.
1402 send_md(struct sscop *sscop, struct SSCOP_MBUF_T *m)
1407 pdu.sscop_type = PDU_MD;
1409 pdu.sscop_pl += MBUF_PAD4(m);
1411 MBUF_APPEND32(m, pdu.sscop_null);
1420 send_end(struct sscop *sscop, int src, struct SSCOP_MBUF_T *uu)
1423 struct SSCOP_MBUF_T *m;
1425 sscop->last_end_src = src;
1429 pdu.sscop_type = PDU_END;
1432 if((m = MBUF_DUP(uu)) == NULL) {
1433 FAILURE("sscop: cannot allocate END");
1436 pdu.sscop_pl += MBUF_PAD4(m);
1438 if((m = MBUF_ALLOC(8)) == NULL) {
1439 FAILURE("sscop: cannot allocate END");
1444 MBUF_APPEND32(m, 0);
1445 MBUF_APPEND32(m, pdu.sscop_null);
1451 * Send USTAT PDU. List must be terminated by -1.
1454 send_ustat(struct sscop *sscop, ...)
1461 struct SSCOP_MBUF_T *m;
1463 va_start(ap, sscop);
1465 while((f = va_arg(ap, int)) >= 0)
1469 if((m = MBUF_ALLOC(n * 4 + 8)) == NULL) {
1470 FAILURE("sscop: cannot allocate USTAT");
1474 va_start(ap, sscop);
1475 while((f = va_arg(ap, int)) >= 0) {
1476 seqno.sscop_null = 0;
1478 MBUF_APPEND32(m, seqno.sscop_null);
1482 seqno.sscop_null = 0;
1483 seqno.sscop_n = sscop->vr_mr;
1484 MBUF_APPEND32(m, seqno.sscop_null);
1487 pdu.sscop_type = PDU_USTAT;
1488 pdu.sscop_ns = sscop->vr_r;
1489 MBUF_APPEND32(m, pdu.sscop_null);
1498 send_er(struct sscop *sscop)
1502 struct SSCOP_MBUF_T *m;
1505 pdu.sscop_type = PDU_ER;
1506 pdu.sscop_ns = sscop->vr_mr;
1509 bgn.sscop_bgns = sscop->vt_sq;
1511 if((m = MBUF_ALLOC(8)) == NULL) {
1512 FAILURE("sscop: cannot allocate ER");
1515 MBUF_APPEND32(m, bgn.sscop_null);
1516 MBUF_APPEND32(m, pdu.sscop_null);
1525 send_poll(struct sscop *sscop)
1529 struct SSCOP_MBUF_T *m;
1531 seqno.sscop_null = 0;
1532 seqno.sscop_n = sscop->vt_ps;
1535 pdu.sscop_ns = sscop->vt_s;
1536 pdu.sscop_type = PDU_POLL;
1538 if((m = MBUF_ALLOC(8)) == NULL) {
1539 FAILURE("sscop: cannot allocate POLL");
1542 MBUF_APPEND32(m, seqno.sscop_null);
1543 MBUF_APPEND32(m, pdu.sscop_null);
1549 * Send STAT PDU. List is already in buffer.
1552 send_stat(struct sscop *sscop, u_int nps, struct SSCOP_MBUF_T *m)
1557 seqno.sscop_null = 0;
1558 seqno.sscop_n = nps;
1559 MBUF_APPEND32(m, seqno.sscop_null);
1561 seqno.sscop_null = 0;
1562 seqno.sscop_n = sscop->vr_mr;
1563 MBUF_APPEND32(m, seqno.sscop_null);
1566 pdu.sscop_type = PDU_STAT;
1567 pdu.sscop_ns = sscop->vr_r;
1568 MBUF_APPEND32(m, pdu.sscop_null);
1577 send_endak(struct sscop *sscop)
1581 struct SSCOP_MBUF_T *m;
1583 seqno.sscop_null = 0;
1585 pdu.sscop_type = PDU_ENDAK;
1587 if((m = MBUF_ALLOC(8)) == NULL) {
1588 FAILURE("sscop: cannot allocate ENDAK");
1591 MBUF_APPEND32(m, seqno.sscop_null);
1592 MBUF_APPEND32(m, pdu.sscop_null);
1601 send_erak(struct sscop *sscop)
1605 struct SSCOP_MBUF_T *m;
1607 seqno.sscop_null = 0;
1609 pdu.sscop_type = PDU_ERAK;
1610 pdu.sscop_ns = sscop->vr_mr;
1612 if((m = MBUF_ALLOC(8)) == NULL) {
1613 FAILURE("sscop: cannot allocate ERAK");
1616 MBUF_APPEND32(m, seqno.sscop_null);
1617 MBUF_APPEND32(m, pdu.sscop_null);
1626 send_rs(struct sscop *sscop, int resend, struct SSCOP_MBUF_T *uu)
1630 struct SSCOP_MBUF_T *m;
1633 pdu.sscop_type = PDU_RS;
1634 pdu.sscop_ns = resend ? sscop->rs_mr : sscop->vr_mr;
1637 bgn.sscop_bgns = resend ? sscop->rs_sq : sscop->vt_sq;
1639 sscop->rs_mr = pdu.sscop_ns;
1640 sscop->rs_sq = bgn.sscop_bgns;
1643 if((m = MBUF_DUP(uu)) == NULL) {
1644 FAILURE("sscop: cannot allocate RS");
1647 pdu.sscop_pl += MBUF_PAD4(m);
1649 if((m = MBUF_ALLOC(8)) == NULL) {
1650 FAILURE("sscop: cannot allocate RS");
1655 MBUF_APPEND32(m, bgn.sscop_null);
1656 MBUF_APPEND32(m, pdu.sscop_null);
1665 send_rsak(struct sscop *sscop)
1669 struct SSCOP_MBUF_T *m;
1671 seqno.sscop_null = 0;
1673 pdu.sscop_type = PDU_RSAK;
1674 pdu.sscop_ns = sscop->vr_mr;
1676 if((m = MBUF_ALLOC(8)) == NULL) {
1677 FAILURE("sscop: cannot allocate RSAK");
1681 MBUF_APPEND32(m, seqno.sscop_null);
1682 MBUF_APPEND32(m, pdu.sscop_null);
1687 /************************************************************/
1689 * P 31; IDLE && AA-ESTABLISH-request
1690 * arg is UU data (opt).
1693 sscop_idle_establish_req(struct sscop *sscop, struct sscop_msg *uu)
1695 u_int br = uu->rexmit;
1699 m_clear_transmitter(sscop);
1701 sscop->clear_buffers = br;
1706 m_initialize_mr(sscop);
1708 send_bgn(sscop, sscop->uu_bgn);
1710 TIMER_RESTART(sscop, cc);
1712 sscop_set_state(sscop, SSCOP_OUT_PEND);
1716 * P 31: IDLE && BGN PDU
1717 * arg is the received PDU (freed).
1720 sscop_idle_bgn(struct sscop *sscop, struct sscop_msg *msg)
1725 pdu.sscop_null = MBUF_STRIP32(msg->m);
1727 if(sscop->robustness) {
1728 bgn.sscop_null = MBUF_STRIP32(msg->m);
1729 sscop->vr_sq = bgn.sscop_bgns;
1731 if(m_detect_retransmission(sscop, msg)) {
1732 send_bgrej(sscop, sscop->uu_bgrej);
1733 SSCOP_MSG_FREE(msg);
1736 (void)MBUF_STRIP32(msg->m);
1739 sscop->vt_ms = pdu.sscop_ns;
1740 sscop_set_state(sscop, SSCOP_IN_PEND);
1742 AAL_UU_SIGNAL(sscop, SSCOP_ESTABLISH_indication, msg, pdu.sscop_pl, 0);
1746 * p 31: IDLE && ENDAK PDU
1747 * p 34: OUT_PEND && ENDAK PDU
1748 * p 34: OUT_PEND && SD PDU
1749 * p 34: OUT_PEND && ERAK PDU
1750 * p 34: OUT_PEND && END PDU
1751 * p 34: OUT_PEND && STAT PDU
1752 * p 34: OUT_PEND && USTAT PDU
1753 * p 34: OUT_PEND && POLL PDU
1754 * p 36: OUT_PEND && RS PDU
1755 * p 36: OUT_PEND && RSAK PDU
1756 * p 40: OUTGOING_DISCONNECT_PENDING && SD PDU
1757 * p 40: OUTGOING_DISCONNECT_PENDING && BGAK PDU
1758 * p 40: OUTGOING_DISCONNECT_PENDING && POLL PDU
1759 * p 40: OUTGOING_DISCONNECT_PENDING && STAT PDU
1760 * p 40: OUTGOING_DISCONNECT_PENDING && USTAT PDU
1761 * p 41: OUTGOING_DISCONNECT_PENDING && ERAK PDU
1762 * p 42: OUTGOING_DISCONNECT_PENDING && ER PDU
1763 * p 42: OUTGOING_DISCONNECT_PENDING && RS PDU
1764 * p 42: OUTGOING_DISCONNECT_PENDING && RSAK PDU
1765 * p 43: OUTGOING_RESYNC && ER PDU
1766 * p 43: OUTGOING_RESYNC && POLL PDU
1767 * p 44: OUTGOING_RESYNC && STAT PDU
1768 * p 44: OUTGOING_RESYNC && USTAT PDU
1769 * p 45: OUTGOING_RESYNC && BGAK PDU
1770 * p 45: OUTGOING_RESYNC && SD PDU
1771 * p 45: OUTGOING_RESYNC && ERAK PDU
1772 * P 60: READY && BGAK PDU
1773 * P 60: READY && ERAK PDU
1774 * arg is pdu (freed).
1777 sscop_ignore_pdu(struct sscop *sscop __unused, struct sscop_msg *msg)
1779 SSCOP_MSG_FREE(msg);
1783 * p 31: IDLE && END PDU
1784 * arg is pdu (freed).
1787 sscop_idle_end(struct sscop *sscop, struct sscop_msg *msg)
1789 SSCOP_MSG_FREE(msg);
1794 * p 31: IDLE && ER PDU
1795 * arg is pdu (freed).
1798 sscop_idle_er(struct sscop *sscop, struct sscop_msg *msg)
1800 SSCOP_MSG_FREE(msg);
1801 MAAL_ERROR(sscop, 'L', 0);
1803 send_end(sscop, 1, NULL);
1807 * p 31: IDLE && BGREJ PDU
1808 * arg is pdu (freed).
1811 sscop_idle_bgrej(struct sscop *sscop, struct sscop_msg *msg)
1813 SSCOP_MSG_FREE(msg);
1814 MAAL_ERROR(sscop, 'D', 0);
1819 * p 32: IDLE && POLL PDU
1820 * arg is pdu (freed).
1823 sscop_idle_poll(struct sscop *sscop, struct sscop_msg *msg)
1825 SSCOP_MSG_FREE(msg);
1826 MAAL_ERROR(sscop, 'G', 0);
1828 send_end(sscop, 1, NULL);
1832 * p 32: IDLE && SD PDU
1833 * arg is pdu (freed).
1836 sscop_idle_sd(struct sscop *sscop, struct sscop_msg *msg)
1838 SSCOP_MSG_FREE(msg);
1839 MAAL_ERROR(sscop, 'A', 0);
1841 send_end(sscop, 1, NULL);
1845 * p 32: IDLE && BGAK PDU
1846 * arg is pdu (freed).
1849 sscop_idle_bgak(struct sscop *sscop, struct sscop_msg *msg)
1851 SSCOP_MSG_FREE(msg);
1852 MAAL_ERROR(sscop, 'C', 0);
1854 send_end(sscop, 1, NULL);
1858 * p 32: IDLE && ERAK PDU
1859 * arg is pdu (freed).
1862 sscop_idle_erak(struct sscop *sscop, struct sscop_msg *msg)
1864 SSCOP_MSG_FREE(msg);
1865 MAAL_ERROR(sscop, 'M', 0);
1867 send_end(sscop, 1, NULL);
1871 * p 32: IDLE && STAT PDU
1872 * arg is pdu (freed).
1875 sscop_idle_stat(struct sscop *sscop, struct sscop_msg *msg)
1877 SSCOP_MSG_FREE(msg);
1878 MAAL_ERROR(sscop, 'H', 0);
1880 send_end(sscop, 1, NULL);
1884 * p 32: IDLE && USTAT PDU
1885 * arg is pdu (freed).
1888 sscop_idle_ustat(struct sscop *sscop, struct sscop_msg *msg)
1890 SSCOP_MSG_FREE(msg);
1891 MAAL_ERROR(sscop, 'I', 0);
1893 send_end(sscop, 1, NULL);
1897 * p 33: IDLE & RS PDU
1898 * arg is pdu (freed).
1901 sscop_idle_rs(struct sscop *sscop, struct sscop_msg *msg)
1903 SSCOP_MSG_FREE(msg);
1904 MAAL_ERROR(sscop, 'J', 0);
1906 send_end(sscop, 1, NULL);
1910 * p 33: IDLE & RSAK PDU
1911 * arg is pdu (freed).
1914 sscop_idle_rsak(struct sscop *sscop, struct sscop_msg *msg)
1916 SSCOP_MSG_FREE(msg);
1917 MAAL_ERROR(sscop, 'K', 0);
1919 send_end(sscop, 1, NULL);
1923 * p 33: IDLE && PDU_Q
1924 * p XX: OUTPEND && PDU_Q
1925 * p 39: IN_PEND && PDU_Q
1926 * p 45: OUT_RESYNC_PEND && PDU_Q
1927 * p 48: IN_RESYNC_PEND && PDU_Q
1931 sscop_flush_pduq(struct sscop *sscop __unused, struct sscop_msg *unused __unused)
1934 MSGQ_CLEAR(&sscop->xq);
1939 * p 34: OUT_PEND && BGAK PDU
1940 * arg is pdu (freed).
1943 sscop_outpend_bgak(struct sscop *sscop, struct sscop_msg *msg)
1947 pdu.sscop_null = MBUF_STRIP32(msg->m);
1948 (void)MBUF_STRIP32(msg->m);
1950 TIMER_STOP(sscop, cc);
1951 sscop->vt_ms = pdu.sscop_ns;
1953 AAL_UU_SIGNAL(sscop, SSCOP_ESTABLISH_confirm, msg, pdu.sscop_pl, 0);
1955 m_initialize_state(sscop);
1956 m_set_data_xfer_timers(sscop);
1958 sscop_set_state(sscop, SSCOP_READY);
1962 * P 34: OUT_PEND && BGREJ PDU
1965 sscop_outpend_bgrej(struct sscop *sscop, struct sscop_msg *msg)
1969 pdu.sscop_null = MBUF_STRIP32(msg->m);
1970 (void)MBUF_STRIP32(msg->m);
1972 TIMER_STOP(sscop, cc);
1974 AAL_UU_SIGNAL(sscop, SSCOP_RELEASE_indication, msg, pdu.sscop_pl, 0);
1976 sscop_set_state(sscop, SSCOP_IDLE);
1980 * P 35: OUT_PEND && TIMER_CC expiry
1984 sscop_outpend_tcc(struct sscop *sscop, struct sscop_msg *unused __unused)
1986 if(sscop->vt_cc >= sscop->maxcc) {
1987 MAAL_ERROR(sscop, 'O', 0);
1989 send_end(sscop, 1, NULL);
1991 AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1);
1993 sscop_set_state(sscop, SSCOP_IDLE);
1996 send_bgn(sscop, sscop->uu_bgn);
1997 TIMER_RESTART(sscop, cc);
2002 * P 35: OUT_PEND && RELEASE_REQ
2006 sscop_outpend_release_req(struct sscop *sscop, struct sscop_msg *uu)
2010 TIMER_STOP(sscop, cc);
2012 send_end(sscop, 0, sscop->uu_end);
2013 TIMER_RESTART(sscop, cc);
2015 sscop_set_state(sscop, SSCOP_OUT_DIS_PEND);
2019 * P 36: OUT_PEND && BGN PDU
2020 * arg is the received PDU (freed).
2023 sscop_outpend_bgn(struct sscop *sscop, struct sscop_msg *msg)
2027 pdu.sscop_null = MBUF_STRIP32(msg->m);
2029 if(m_detect_retransmission(sscop, msg)) {
2030 SSCOP_MSG_FREE(msg);
2033 (void)MBUF_STRIP32(msg->m);
2035 TIMER_STOP(sscop, cc);
2037 sscop->vt_ms = pdu.sscop_ns;
2039 m_initialize_mr(sscop);
2041 send_bgak(sscop, sscop->uu_bgak);
2043 AAL_UU_SIGNAL(sscop, SSCOP_ESTABLISH_confirm, msg, pdu.sscop_pl, 0);
2045 m_initialize_state(sscop);
2047 m_set_data_xfer_timers(sscop);
2049 sscop_set_state(sscop, SSCOP_READY);
2053 * p 37: IN_PEND && AA-ESTABLISH.response
2057 sscop_inpend_establish_resp(struct sscop *sscop, struct sscop_msg *uu)
2059 u_int br = uu->rexmit;
2061 SET_UU(uu_bgak, uu);
2063 m_clear_transmitter(sscop);
2064 sscop->clear_buffers = br;
2065 m_initialize_mr(sscop);
2066 send_bgak(sscop, sscop->uu_bgak);
2067 m_initialize_state(sscop);
2068 m_set_data_xfer_timers(sscop);
2070 sscop_set_state(sscop, SSCOP_READY);
2074 * p 37: IN_PEND && AA-RELEASE.request
2078 sscop_inpend_release_req(struct sscop *sscop, struct sscop_msg *uu)
2080 SET_UU(uu_bgrej, uu);
2082 send_bgrej(sscop, sscop->uu_bgrej);
2084 sscop_set_state(sscop, SSCOP_IDLE);
2088 * p 37: IN_PEND && BGN PDU
2089 * arg is pdu. (freed)
2092 sscop_inpend_bgn(struct sscop *sscop, struct sscop_msg *msg)
2096 pdu.sscop_null = MBUF_STRIP32(msg->m);
2098 if(m_detect_retransmission(sscop, msg)) {
2099 SSCOP_MSG_FREE(msg);
2102 (void)MBUF_STRIP32(msg->m);
2104 sscop->vt_ms = pdu.sscop_ns;
2106 AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 0);
2107 AAL_UU_SIGNAL(sscop, SSCOP_ESTABLISH_indication, msg, pdu.sscop_pl, 0);
2111 * p 37: IN_PEND && ER PDU
2112 * arg is pdu (freed).
2115 sscop_inpend_er(struct sscop *sscop, struct sscop_msg *msg)
2117 MAAL_ERROR(sscop, 'L', 0);
2118 SSCOP_MSG_FREE(msg);
2122 * p 37: IN_PEND && ENDAK PDU
2123 * arg is pdu (freed).
2126 sscop_inpend_endak(struct sscop *sscop, struct sscop_msg *msg)
2128 MAAL_ERROR(sscop, 'F', 0);
2130 AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1);
2132 sscop_set_state(sscop, SSCOP_IDLE);
2134 SSCOP_MSG_FREE(msg);
2138 * p 38: IN_PEND && BGAK PDU
2139 * arg is pdu (freed).
2142 sscop_inpend_bgak(struct sscop *sscop, struct sscop_msg *msg)
2144 MAAL_ERROR(sscop, 'C', 0);
2146 SSCOP_MSG_FREE(msg);
2150 * p 38: IN_PEND && BGREJ PDU
2151 * arg is pdu (freed).
2154 sscop_inpend_bgrej(struct sscop *sscop, struct sscop_msg *msg)
2156 MAAL_ERROR(sscop, 'D', 0);
2158 AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1);
2160 SSCOP_MSG_FREE(msg);
2162 sscop_set_state(sscop, SSCOP_IDLE);
2166 * p 38: IN_PEND && SD PDU
2167 * arg is pdu (freed).
2170 sscop_inpend_sd(struct sscop *sscop, struct sscop_msg *msg)
2172 MAAL_ERROR(sscop, 'A', 0);
2174 SSCOP_MSG_FREE(msg);
2177 send_end(sscop, 1, NULL);
2179 AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1);
2181 sscop_set_state(sscop, SSCOP_IDLE);
2185 * p 38: IN_PEND && USTAT PDU
2186 * arg is pdu (freed).
2189 sscop_inpend_ustat(struct sscop *sscop, struct sscop_msg *msg)
2191 MAAL_ERROR(sscop, 'I', 0);
2193 SSCOP_MSG_FREE(msg);
2196 send_end(sscop, 1, NULL);
2198 AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1);
2200 sscop_set_state(sscop, SSCOP_IDLE);
2204 * p 38: IN_PEND && STAT PDU
2205 * arg is pdu (freed).
2208 sscop_inpend_stat(struct sscop *sscop, struct sscop_msg *msg)
2210 MAAL_ERROR(sscop, 'H', 0);
2212 SSCOP_MSG_FREE(msg);
2215 send_end(sscop, 1, NULL);
2217 AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1);
2219 sscop_set_state(sscop, SSCOP_IDLE);
2223 * p 38: IN_PEND && POLL PDU
2224 * arg is pdu (freed).
2227 sscop_inpend_poll(struct sscop *sscop, struct sscop_msg *msg)
2229 MAAL_ERROR(sscop, 'G', 0);
2231 SSCOP_MSG_FREE(msg);
2234 send_end(sscop, 1, NULL);
2236 AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1);
2238 sscop_set_state(sscop, SSCOP_IDLE);
2242 * p 39: IN_PEND && ERAK PDU
2243 * arg is pdu (freed).
2246 sscop_inpend_erak(struct sscop *sscop, struct sscop_msg *msg)
2248 SSCOP_MSG_FREE(msg);
2249 MAAL_ERROR(sscop, 'M', 0);
2253 * p 39: IN_PEND & RS PDU
2254 * arg is pdu (freed).
2257 sscop_inpend_rs(struct sscop *sscop, struct sscop_msg *msg)
2259 SSCOP_MSG_FREE(msg);
2260 MAAL_ERROR(sscop, 'J', 0);
2264 * p 39: IN_PEND & RSAK PDU
2265 * arg is pdu (freed).
2268 sscop_inpend_rsak(struct sscop *sscop, struct sscop_msg *msg)
2270 SSCOP_MSG_FREE(msg);
2271 MAAL_ERROR(sscop, 'K', 0);
2275 * p 39: IN_PEND && END PDU
2276 * arg is pdu (freed).
2280 sscop_inpend_end(struct sscop *sscop, struct sscop_msg *msg)
2284 pdu.sscop_null = MBUF_STRIP32(msg->m);
2285 (void)MBUF_STRIP32(msg->m);
2289 AAL_UU_SIGNAL(sscop, SSCOP_RELEASE_indication,
2290 msg, pdu.sscop_pl, (u_int)pdu.sscop_s);
2292 sscop_set_state(sscop, SSCOP_IDLE);
2296 * p 40: OUT_DIS_PEND && SSCOP_ESTABLISH_request
2301 sscop_outdis_establish_req(struct sscop *sscop, struct sscop_msg *uu)
2305 TIMER_STOP(sscop, cc);
2306 m_clear_transmitter(sscop);
2307 sscop->clear_buffers = 1;
2310 m_initialize_mr(sscop);
2311 send_bgn(sscop, sscop->uu_bgn);
2312 TIMER_RESTART(sscop, cc);
2314 sscop_set_state(sscop, SSCOP_OUT_PEND);
2318 * p 41: OUT_DIS_PEND && END PDU
2319 * arg is pdu (freed).
2322 sscop_outdis_end(struct sscop *sscop, struct sscop_msg *msg)
2326 pdu.sscop_null = MBUF_STRIP32(msg->m);
2327 (void)MBUF_STRIP32(msg->m);
2329 TIMER_STOP(sscop, cc);
2332 AAL_UU_SIGNAL(sscop, SSCOP_RELEASE_confirm, msg, pdu.sscop_pl, 0);
2334 sscop_set_state(sscop, SSCOP_IDLE);
2338 * p 41: OUT_DIS_PEND && ENDAK PDU
2339 * p 41: OUT_DIS_PEND && BGREJ PDU
2340 * arg is pdu (freed)
2343 sscop_outdis_endak(struct sscop *sscop, struct sscop_msg *msg)
2347 pdu.sscop_null = MBUF_STRIP32(msg->m);
2348 (void)MBUF_STRIP32(msg->m);
2350 TIMER_STOP(sscop, cc);
2352 AAL_UU_SIGNAL(sscop, SSCOP_RELEASE_confirm, msg, pdu.sscop_pl, 0);
2354 sscop_set_state(sscop, SSCOP_IDLE);
2358 * p 41: OUT_DIS_PEND && TIMER CC expiry
2362 sscop_outdis_cc(struct sscop *sscop, struct sscop_msg *unused __unused)
2364 if(sscop->vt_cc >= sscop->maxcc) {
2365 MAAL_ERROR(sscop, 'O', 0);
2366 AAL_SIG(sscop, SSCOP_RELEASE_confirm);
2367 sscop_set_state(sscop, SSCOP_IDLE);
2370 send_end(sscop, sscop->last_end_src, sscop->uu_end);
2371 TIMER_RESTART(sscop, cc);
2376 * p 42: OUT_DIS_PEND && BGN PDU
2377 * arg is pdu (freed).
2380 sscop_outdis_bgn(struct sscop *sscop, struct sscop_msg *msg)
2384 pdu.sscop_null = MBUF_STRIP32(msg->m);
2386 if(m_detect_retransmission(sscop, msg)) {
2388 send_bgak(sscop, NULL);
2389 send_end(sscop, sscop->last_end_src, sscop->uu_end);
2390 SSCOP_MSG_FREE(msg);
2393 (void)MBUF_STRIP32(msg->m);
2395 TIMER_STOP(sscop, cc);
2396 sscop->vt_ms = pdu.sscop_ns;
2397 AAL_SIG(sscop, SSCOP_RELEASE_confirm);
2398 AAL_UU_SIGNAL(sscop, SSCOP_ESTABLISH_indication,
2399 msg, pdu.sscop_pl, 0);
2400 sscop_set_state(sscop, SSCOP_IN_PEND);
2405 * p 43: OUT_RESYNC_PEND && BGN PDU
2406 * arg is pdu (freed).
2409 sscop_outsync_bgn(struct sscop *sscop, struct sscop_msg *msg)
2413 pdu.sscop_null = MBUF_STRIP32(msg->m);
2415 if(m_detect_retransmission(sscop, msg)) {
2416 send_bgak(sscop, sscop->uu_bgak);
2417 send_rs(sscop, 1, sscop->uu_rs);
2418 SSCOP_MSG_FREE(msg);
2420 (void)MBUF_STRIP32(msg->m);
2422 TIMER_STOP(sscop, cc);
2423 sscop->vt_ms = pdu.sscop_ns;
2424 AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 0);
2425 AAL_UU_SIGNAL(sscop, SSCOP_ESTABLISH_indication,
2426 msg, pdu.sscop_pl, 0);
2427 sscop_set_state(sscop, SSCOP_IN_PEND);
2432 * p 43: OUT_RESYNC_PEND && ENDAK PDU
2433 * arg is pdu (freed).
2436 sscop_outsync_endak(struct sscop *sscop, struct sscop_msg *msg)
2438 SSCOP_MSG_FREE(msg);
2439 TIMER_STOP(sscop, cc);
2440 MAAL_ERROR(sscop, 'F', 0);
2441 AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1);
2442 sscop_set_state(sscop, SSCOP_IDLE);
2446 * p 43: OUT_RESYNC_PEND && BGREJ PDU
2447 * arg is pdu (freed).
2450 sscop_outsync_bgrej(struct sscop *sscop, struct sscop_msg *msg)
2452 SSCOP_MSG_FREE(msg);
2453 TIMER_STOP(sscop, cc);
2454 MAAL_ERROR(sscop, 'D', 0);
2455 AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1);
2456 sscop_set_state(sscop, SSCOP_IDLE);
2460 * p 43: OUT_RESYNC_PEND && END PDU
2461 * arg is pdu (freed).
2465 sscop_outsync_end(struct sscop *sscop, struct sscop_msg *msg)
2469 pdu.sscop_null = MBUF_STRIP32(msg->m);
2470 (void)MBUF_STRIP32(msg->m);
2472 TIMER_STOP(sscop, cc);
2474 AAL_UU_SIGNAL(sscop, SSCOP_RELEASE_indication, msg, pdu.sscop_pl,
2475 (u_int)pdu.sscop_s);
2476 sscop_set_state(sscop, SSCOP_IDLE);
2480 * p 44: OUT_RESYNC && TIMER CC expiry
2483 sscop_outsync_cc(struct sscop *sscop, struct sscop_msg *msg __unused)
2485 if(sscop->vt_cc == sscop->maxcc) {
2486 MAAL_ERROR(sscop, 'O', 0);
2488 send_end(sscop, 1, NULL);
2489 AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1);
2490 sscop_set_state(sscop, SSCOP_IDLE);
2493 send_rs(sscop, 1, sscop->uu_rs);
2494 TIMER_RESTART(sscop, cc);
2499 * p 44: OUT_RESYNC && AA-RELEASE.request
2503 sscop_outsync_release_req(struct sscop *sscop, struct sscop_msg *uu)
2507 TIMER_STOP(sscop, cc);
2509 send_end(sscop, 0, sscop->uu_end);
2510 TIMER_RESTART(sscop, cc);
2511 sscop_set_state(sscop, SSCOP_OUT_DIS_PEND);
2515 * p 45: OUT_RESYNC && RS PDU
2516 * arg is pdu (freed).
2519 sscop_outsync_rs(struct sscop *sscop, struct sscop_msg *msg)
2523 pdu.sscop_null = MBUF_STRIP32(msg->m);
2525 if(m_detect_retransmission(sscop, msg)) {
2526 SSCOP_MSG_FREE(msg);
2529 (void)MBUF_STRIP32(msg->m);
2531 TIMER_STOP(sscop, cc);
2532 sscop->vt_ms = pdu.sscop_ns;
2533 m_initialize_mr(sscop);
2535 AAL_UU_SIGNAL(sscop, SSCOP_RESYNC_confirm, msg, pdu.sscop_pl, 0);
2536 m_initialize_state(sscop);
2537 m_set_data_xfer_timers(sscop);
2538 sscop_set_state(sscop, SSCOP_READY);
2542 * p 45: OUT_RESYNC && RSAK PDU
2543 * arg is pdu (freed).
2546 sscop_outsync_rsak(struct sscop *sscop, struct sscop_msg *msg)
2550 pdu.sscop_null = MBUF_STRIP32(msg->m);
2552 SSCOP_MSG_FREE(msg);
2554 TIMER_STOP(sscop, cc);
2555 sscop->vt_ms = pdu.sscop_ns;
2556 AAL_SIG(sscop, SSCOP_RESYNC_confirm);
2557 m_initialize_state(sscop);
2558 m_set_data_xfer_timers(sscop);
2559 sscop_set_state(sscop, SSCOP_READY);
2563 * p 46: IN_RESYNC_PEND && AA-RESYNC.response
2566 sscop_insync_sync_resp(struct sscop *sscop, struct sscop_msg *noarg __unused)
2568 m_initialize_mr(sscop);
2570 m_clear_transmitter(sscop);
2571 m_initialize_state(sscop);
2572 m_set_data_xfer_timers(sscop);
2573 sscop_set_state(sscop, SSCOP_READY);
2577 * p 46: IN_RESYNC_PEND && AA-RELEASE.request
2581 sscop_insync_release_req(struct sscop *sscop, struct sscop_msg *uu)
2586 send_end(sscop, 0, sscop->uu_end);
2587 TIMER_RESTART(sscop, cc);
2588 sscop_set_state(sscop, SSCOP_OUT_DIS_PEND);
2592 * p 46: IN_RESYNC_PEND && ENDAK PDU
2593 * arg is pdu (freed).
2596 sscop_insync_endak(struct sscop *sscop, struct sscop_msg *msg)
2598 SSCOP_MSG_FREE(msg);
2599 MAAL_ERROR(sscop, 'F', 0);
2600 AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1);
2601 sscop_set_state(sscop, SSCOP_IDLE);
2605 * p 46: IN_RESYNC_PEND && BGREJ PDU
2606 * arg is pdu (freed).
2609 sscop_insync_bgrej(struct sscop *sscop, struct sscop_msg *msg)
2611 SSCOP_MSG_FREE(msg);
2612 MAAL_ERROR(sscop, 'D', 0);
2613 AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1);
2614 sscop_set_state(sscop, SSCOP_IDLE);
2618 * p 46: IN_RESYNC_PEND && END PDU
2619 * arg is pdu (freed).
2622 sscop_insync_end(struct sscop *sscop, struct sscop_msg *msg)
2626 pdu.sscop_null = MBUF_STRIP32(msg->m);
2627 (void)MBUF_STRIP32(msg->m);
2630 AAL_UU_SIGNAL(sscop, SSCOP_RELEASE_indication,
2631 msg, pdu.sscop_pl, (u_int)pdu.sscop_s);
2632 sscop_set_state(sscop, SSCOP_IDLE);
2636 * p 47: IN_RESYNC_PEND && ER PDU
2637 * arg is pdu (freed).
2640 sscop_insync_er(struct sscop *sscop, struct sscop_msg *msg)
2642 SSCOP_MSG_FREE(msg);
2643 MAAL_ERROR(sscop, 'L', 0);
2647 * p 47: IN_RESYNC_PEND && BGN PDU
2648 * arg is pdu (freed).
2651 sscop_insync_bgn(struct sscop *sscop, struct sscop_msg *msg)
2655 pdu.sscop_null = MBUF_STRIP32(msg->m);
2657 if(m_detect_retransmission(sscop, msg)) {
2658 MAAL_ERROR(sscop, 'B', 0);
2659 SSCOP_MSG_FREE(msg);
2662 (void)MBUF_STRIP32(msg->m);
2664 sscop->vt_ms = pdu.sscop_ns;
2665 AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 0);
2666 AAL_UU_SIGNAL(sscop, SSCOP_ESTABLISH_indication, msg, pdu.sscop_pl, 0);
2668 sscop_set_state(sscop, SSCOP_IN_PEND);
2672 * p 47: IN_RESYNC_PEND && SD PDU
2673 * arg is pdu (freed).
2676 sscop_insync_sd(struct sscop *sscop, struct sscop_msg *msg)
2678 SSCOP_MSG_FREE(msg);
2679 MAAL_ERROR(sscop, 'A', 0);
2681 send_end(sscop, 1, NULL);
2682 AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1);
2683 sscop_set_state(sscop, SSCOP_IDLE);
2687 * p 47: IN_RESYNC_PEND && POLL PDU
2688 * arg is pdu (freed).
2691 sscop_insync_poll(struct sscop *sscop, struct sscop_msg *msg)
2693 SSCOP_MSG_FREE(msg);
2694 MAAL_ERROR(sscop, 'G', 0);
2696 send_end(sscop, 1, NULL);
2697 AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1);
2698 sscop_set_state(sscop, SSCOP_IDLE);
2702 * p 47: IN_RESYNC_PEND && STAT PDU
2703 * arg is pdu (freed).
2706 sscop_insync_stat(struct sscop *sscop, struct sscop_msg *msg)
2708 SSCOP_MSG_FREE(msg);
2709 MAAL_ERROR(sscop, 'H', 0);
2711 send_end(sscop, 1, NULL);
2712 AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1);
2713 sscop_set_state(sscop, SSCOP_IDLE);
2717 * p 47: IN_RESYNC_PEND && USTAT PDU
2718 * arg is pdu (freed).
2721 sscop_insync_ustat(struct sscop *sscop, struct sscop_msg *msg)
2723 SSCOP_MSG_FREE(msg);
2724 MAAL_ERROR(sscop, 'I', 0);
2726 send_end(sscop, 1, NULL);
2727 AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1);
2728 sscop_set_state(sscop, SSCOP_IDLE);
2732 * p 48: IN_RESYNC_PEND && BGAK PDU
2733 * arg is pdu (freed).
2736 sscop_insync_bgak(struct sscop *sscop, struct sscop_msg *msg)
2738 MAAL_ERROR(sscop, 'C', 0);
2739 SSCOP_MSG_FREE(msg);
2743 * p 48: IN_RESYNC_PEND && ERAK PDU
2744 * arg is pdu (freed).
2747 sscop_insync_erak(struct sscop *sscop, struct sscop_msg *msg)
2749 MAAL_ERROR(sscop, 'M', 0);
2750 SSCOP_MSG_FREE(msg);
2754 * p 48: IN_RESYNC_PEND && RS PDU
2755 * arg is pdu (freed).
2758 sscop_insync_rs(struct sscop *sscop, struct sscop_msg *msg)
2762 pdu.sscop_null = MBUF_STRIP32(msg->m);
2764 if(m_detect_retransmission(sscop, msg)) {
2765 SSCOP_MSG_FREE(msg);
2768 SSCOP_MSG_FREE(msg);
2769 MAAL_ERROR(sscop, 'J', 0);
2773 * p 48: IN_RESYNC_PEND && RSAK PDU
2774 * arg is pdu (freed).
2777 sscop_insync_rsak(struct sscop *sscop, struct sscop_msg *msg)
2779 MAAL_ERROR(sscop, 'K', 0);
2780 SSCOP_MSG_FREE(msg);
2785 * p 49: OUT_REC_PEND && AA-DATA.request
2786 * arg is message (queued).
2789 sscop_outrec_userdata(struct sscop *sscop, struct sscop_msg *msg)
2791 if(!sscop->clear_buffers) {
2792 MSGQ_APPEND(&sscop->xq, msg);
2793 sscop_signal(sscop, SIG_PDU_Q, msg);
2795 SSCOP_MSG_FREE(msg);
2800 * p 49: OUT_REC_PEND && BGAK PDU
2801 * arg is pdu (freed)
2804 sscop_outrec_bgak(struct sscop *sscop, struct sscop_msg *msg)
2806 MAAL_ERROR(sscop, 'C', 0);
2808 SSCOP_MSG_FREE(msg);
2812 * p 49: OUT_REC_PEND && ERAK PDU
2813 * arg is pdu (freed)
2816 sscop_outrec_erak(struct sscop *sscop, struct sscop_msg *msg)
2820 pdu.sscop_null = MBUF_STRIP32(msg->m);
2822 TIMER_STOP(sscop, cc);
2823 sscop->vt_ms = pdu.sscop_ns;
2824 m_deliver_data(sscop);
2826 AAL_SIG(sscop, SSCOP_RECOVER_indication);
2828 sscop_set_state(sscop, SSCOP_REC_PEND);
2830 SSCOP_MSG_FREE(msg);
2834 * p 49: OUT_REC_PEND && END PDU
2835 * arg is pdu (freed)
2838 sscop_outrec_end(struct sscop *sscop, struct sscop_msg *msg)
2842 pdu.sscop_null = MBUF_STRIP32(msg->m);
2843 (void)MBUF_STRIP32(msg->m);
2845 TIMER_STOP(sscop, cc);
2847 AAL_UU_SIGNAL(sscop, SSCOP_RELEASE_indication,
2848 msg, pdu.sscop_pl, (u_int)pdu.sscop_s);
2850 MSGQ_CLEAR(&sscop->rbuf);
2852 sscop_set_state(sscop, SSCOP_IDLE);
2856 * p 49: OUT_REC_PEND && ENDAK PDU
2857 * arg is pdu (freed)
2860 sscop_outrec_endak(struct sscop *sscop, struct sscop_msg *msg)
2862 MAAL_ERROR(sscop, 'F', 0);
2863 TIMER_STOP(sscop, cc);
2864 AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1);
2865 MSGQ_CLEAR(&sscop->rbuf);
2867 sscop_set_state(sscop, SSCOP_IDLE);
2869 SSCOP_MSG_FREE(msg);
2873 * p 49: OUT_REC_PEND && BGREJ PDU
2874 * arg is pdu (freed)
2877 sscop_outrec_bgrej(struct sscop *sscop, struct sscop_msg *msg)
2879 MAAL_ERROR(sscop, 'D', 0);
2880 TIMER_STOP(sscop, cc);
2881 AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1);
2882 MSGQ_CLEAR(&sscop->rbuf);
2884 sscop_set_state(sscop, SSCOP_IDLE);
2886 SSCOP_MSG_FREE(msg);
2890 * p 50: OUT_REC_PEND && TIMER CC expiry
2894 sscop_outrec_cc(struct sscop *sscop, struct sscop_msg *unused __unused)
2896 if(sscop->vt_cc >= sscop->maxcc) {
2897 MAAL_ERROR(sscop, 'O', 0);
2899 send_end(sscop, 1, NULL);
2900 AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1);
2901 MSGQ_CLEAR(&sscop->rbuf);
2902 sscop_set_state(sscop, SSCOP_IDLE);
2906 TIMER_RESTART(sscop, cc);
2911 * p 50: OUT_REC_PEND && SSCOP_RELEASE_request
2915 sscop_outrec_release_req(struct sscop *sscop, struct sscop_msg *uu)
2919 TIMER_STOP(sscop, cc);
2921 send_end(sscop, 0, sscop->uu_end);
2922 MSGQ_CLEAR(&sscop->rbuf);
2923 TIMER_RESTART(sscop, cc);
2925 sscop_set_state(sscop, SSCOP_OUT_DIS_PEND);
2929 * p 51: OUT_REC_PEND && AA-RESYNC.request
2933 sscop_outrec_sync_req(struct sscop *sscop, struct sscop_msg *uu)
2937 TIMER_STOP(sscop, cc);
2940 m_initialize_mr(sscop);
2941 send_rs(sscop, 0, sscop->uu_rs);
2942 m_clear_transmitter(sscop);
2943 MSGQ_CLEAR(&sscop->rbuf);
2944 TIMER_RESTART(sscop, cc);
2948 * p 51: OUT_REC_PEND && BGN PDU
2949 * arg is pdu (freed).
2953 sscop_outrec_bgn(struct sscop *sscop, struct sscop_msg *msg)
2957 pdu.sscop_null = MBUF_STRIP32(msg->m);
2959 if(m_detect_retransmission(sscop, msg)) {
2960 MAAL_ERROR(sscop, 'B', 0);
2961 SSCOP_MSG_FREE(msg);
2963 (void)MBUF_STRIP32(msg->m);
2965 TIMER_STOP(sscop, cc);
2966 sscop->vt_ms = pdu.sscop_ns;
2967 AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 0);
2968 AAL_UU_SIGNAL(sscop, SSCOP_ESTABLISH_indication,
2969 msg, pdu.sscop_pl, 0);
2970 MSGQ_CLEAR(&sscop->rbuf);
2972 sscop_set_state(sscop, SSCOP_IN_PEND);
2977 * p 51: OUT_REC_PEND && ER PDU
2978 * arg is pdu (freed).
2981 sscop_outrec_er(struct sscop *sscop, struct sscop_msg *msg)
2985 pdu.sscop_null = MBUF_STRIP32(msg->m);
2987 if(m_detect_retransmission(sscop, msg)) {
2988 MAAL_ERROR(sscop, 'L', 0);
2990 TIMER_STOP(sscop, cc);
2991 sscop->vt_ms = pdu.sscop_ns;
2992 m_initialize_mr(sscop);
2994 m_deliver_data(sscop);
2996 AAL_SIG(sscop, SSCOP_RECOVER_indication);
2998 sscop_set_state(sscop, SSCOP_REC_PEND);
3001 SSCOP_MSG_FREE(msg);
3005 * p 52: OUT_REC_PEND && SD PDU queued
3009 sscop_outrec_pduq(struct sscop *sscop, struct sscop_msg *msg)
3011 sscop_save_signal(sscop, SIG_PDU_Q, msg);
3015 * p 52: OUT_REC_PEND && RSAK PDU
3016 * arg is pdu (freed).
3019 sscop_outrec_rsak(struct sscop *sscop, struct sscop_msg *msg)
3021 SSCOP_MSG_FREE(msg);
3022 MAAL_ERROR(sscop, 'K', 0);
3026 * p 52: OUT_REC_PEND && RS PDU
3027 * arg is pdu (freed).
3030 sscop_outrec_rs(struct sscop *sscop, struct sscop_msg *msg)
3034 pdu.sscop_null = MBUF_STRIP32(msg->m);
3036 if(m_detect_retransmission(sscop, msg)) {
3037 SSCOP_MSG_FREE(msg);
3038 MAAL_ERROR(sscop, 'J', 0);
3041 (void)MBUF_STRIP32(msg->m);
3043 TIMER_STOP(sscop, cc);
3044 sscop->vt_ms = pdu.sscop_ns;
3045 AAL_UU_SIGNAL(sscop, SSCOP_RESYNC_indication, msg, pdu.sscop_pl, 0);
3046 MSGQ_CLEAR(&sscop->rbuf);
3047 sscop_set_state(sscop, SSCOP_IN_RESYNC_PEND);
3051 * p 53: REC_PEND && BGAK PDU
3052 * arg is pdu (freed)
3055 sscop_rec_bgak(struct sscop *sscop, struct sscop_msg *msg)
3057 MAAL_ERROR(sscop, 'C', 0);
3059 SSCOP_MSG_FREE(msg);
3063 * p 53: REC_PEND && END PDU
3064 * arg is pdu (freed)
3068 sscop_rec_end(struct sscop *sscop, struct sscop_msg *msg)
3072 pdu.sscop_null = MBUF_STRIP32(msg->m);
3073 (void)MBUF_STRIP32(msg->m);
3076 AAL_UU_SIGNAL(sscop, SSCOP_RELEASE_indication,
3077 msg, pdu.sscop_pl, (u_int)pdu.sscop_s);
3079 sscop_set_state(sscop, SSCOP_IDLE);
3083 * p 53: REC_PEND && ENDAK PDU
3084 * arg is pdu (freed)
3087 sscop_rec_endak(struct sscop *sscop, struct sscop_msg *msg)
3089 MAAL_ERROR(sscop, 'F', 0);
3090 AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1);
3091 sscop_set_state(sscop, SSCOP_IDLE);
3092 SSCOP_MSG_FREE(msg);
3096 * p 53: REC_PEND && BGREJ PDU
3097 * arg is pdu (freed)
3100 sscop_rec_bgrej(struct sscop *sscop, struct sscop_msg *msg)
3102 MAAL_ERROR(sscop, 'D', 0);
3103 AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1);
3104 sscop_set_state(sscop, SSCOP_IDLE);
3105 SSCOP_MSG_FREE(msg);
3109 * p 54: REC_PEND && RELEASE
3113 sscop_rec_release_req(struct sscop *sscop, struct sscop_msg *uu)
3118 send_end(sscop, 0, sscop->uu_end);
3119 TIMER_RESTART(sscop, cc);
3121 sscop_set_state(sscop, SSCOP_OUT_DIS_PEND);
3125 * p 54: REC_PEND && RSAK PDU
3126 * arg is pdu (freed).
3129 sscop_rec_rsak(struct sscop *sscop, struct sscop_msg *msg)
3131 MAAL_ERROR(sscop, 'K', 0);
3132 SSCOP_MSG_FREE(msg);
3137 * p 54: REC_PEND && RS PDU
3138 * arg is pdu (freed).
3141 sscop_rec_rs(struct sscop *sscop, struct sscop_msg *msg)
3145 pdu.sscop_null = MBUF_STRIP32(msg->m);
3147 if(m_detect_retransmission(sscop, msg)) {
3148 SSCOP_MSG_FREE(msg);
3149 MAAL_ERROR(sscop, 'J', 0);
3152 (void)MBUF_STRIP32(msg->m);
3154 sscop->vt_ms = pdu.sscop_ns;
3155 AAL_UU_SIGNAL(sscop, SSCOP_RESYNC_indication, msg, pdu.sscop_pl, 0);
3157 sscop_set_state(sscop, SSCOP_IN_RESYNC_PEND);
3161 * p 54: REC_PEND && RECOVER response
3165 sscop_rec_recover(struct sscop *sscop, struct sscop_msg *unused __unused)
3167 if(!sscop->clear_buffers) {
3168 MSGQ_CLEAR(&sscop->xbuf);
3170 m_initialize_state(sscop);
3171 m_set_data_xfer_timers(sscop);
3173 sscop_set_state(sscop, SSCOP_READY);
3177 * p 54: REC_PEND && RESYNC request
3181 sscop_rec_sync_req(struct sscop *sscop, struct sscop_msg *uu)
3185 m_clear_transmitter(sscop);
3188 m_initialize_mr(sscop);
3189 send_rs(sscop, 0, sscop->uu_rs);
3190 TIMER_RESTART(sscop, cc);
3192 sscop_set_state(sscop, SSCOP_OUT_RESYNC_PEND);
3196 * p 55: REC_PEND && SD PDU queued
3200 sscop_rec_pduq(struct sscop *sscop, struct sscop_msg *msg)
3202 sscop_save_signal(sscop, SIG_PDU_Q, msg);
3206 * p 55: REC_PEND && ER PDU
3207 * arg is pdu (freed).
3210 sscop_rec_er(struct sscop *sscop, struct sscop_msg *msg)
3214 pdu.sscop_null = MBUF_STRIP32(msg->m);
3216 if(m_detect_retransmission(sscop, msg)) {
3219 MAAL_ERROR(sscop, 'L', 0);
3221 SSCOP_MSG_FREE(msg);
3225 * p 55: REC_PEND && BGN PDU
3226 * arg is pdu (freed)
3230 sscop_rec_bgn(struct sscop *sscop, struct sscop_msg *msg)
3234 pdu.sscop_null = MBUF_STRIP32(msg->m);
3236 if(m_detect_retransmission(sscop, msg)) {
3237 MAAL_ERROR(sscop, 'B', 0);
3238 SSCOP_MSG_FREE(msg);
3241 (void)MBUF_STRIP32(msg->m);
3243 sscop->vt_ms = pdu.sscop_ns;
3244 AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 0);
3245 AAL_UU_SIGNAL(sscop, SSCOP_ESTABLISH_indication, msg, pdu.sscop_pl, 0);
3247 sscop_set_state(sscop, SSCOP_IN_PEND);
3251 * p 55: REC_PEND && STAT PDU
3252 * arg is pdu (freed)
3255 sscop_rec_stat(struct sscop *sscop, struct sscop_msg *msg)
3257 MAAL_ERROR(sscop, 'H', 0);
3259 send_end(sscop, 1, NULL);
3260 AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1);
3261 sscop_set_state(sscop, SSCOP_IDLE);
3262 SSCOP_MSG_FREE(msg);
3266 * p 55: REC_PEND && USTAT PDU
3267 * arg is pdu (freed)
3270 sscop_rec_ustat(struct sscop *sscop, struct sscop_msg *msg)
3272 MAAL_ERROR(sscop, 'I', 0);
3274 send_end(sscop, 1, NULL);
3275 AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1);
3276 sscop_set_state(sscop, SSCOP_IDLE);
3277 SSCOP_MSG_FREE(msg);
3281 * p 56: IN_REC_PEND && AA-RECOVER.response
3285 sscop_inrec_recover(struct sscop *sscop, struct sscop_msg *unused __unused)
3287 if(!sscop->clear_buffers) {
3288 MSGQ_CLEAR(&sscop->xbuf);
3290 m_initialize_mr(sscop);
3292 m_initialize_state(sscop);
3293 m_set_data_xfer_timers(sscop);
3295 sscop_set_state(sscop, SSCOP_READY);
3299 * p 56: IN_REC_PEND && SD PDU queued
3303 sscop_inrec_pduq(struct sscop *sscop, struct sscop_msg *msg)
3305 sscop_save_signal(sscop, SIG_PDU_Q, msg);
3309 * p 56: IN_REC_PEND && AA-RELEASE.request
3313 sscop_inrec_release_req(struct sscop *sscop, struct sscop_msg *uu)
3318 send_end(sscop, 0, sscop->uu_end);
3319 TIMER_RESTART(sscop, cc);
3321 sscop_set_state(sscop, SSCOP_OUT_DIS_PEND);
3325 * p 56: IN_REC_PEND && END PDU
3326 * arg is pdu (freed).
3330 sscop_inrec_end(struct sscop *sscop, struct sscop_msg *msg)
3334 pdu.sscop_null = MBUF_STRIP32(msg->m);
3335 (void)MBUF_STRIP32(msg->m);
3338 AAL_UU_SIGNAL(sscop, SSCOP_RELEASE_indication,
3339 msg, pdu.sscop_pl, (u_int)pdu.sscop_s);
3341 sscop_set_state(sscop, SSCOP_IDLE);
3345 * p 56: IN_REC_PEND && RESYNC_REQ
3348 sscop_inrec_sync_req(struct sscop *sscop, struct sscop_msg *uu)
3352 m_clear_transmitter(sscop);
3355 m_initialize_mr(sscop);
3356 send_rs(sscop, 0, sscop->uu_rs);
3357 TIMER_RESTART(sscop, cc);
3359 sscop_set_state(sscop, SSCOP_OUT_RESYNC_PEND);
3364 * p 57: IN_REC_PEND && ENDAK PDU
3365 * arg is pdu (freed)
3368 sscop_inrec_endak(struct sscop *sscop, struct sscop_msg *msg)
3370 MAAL_ERROR(sscop, 'F', 0);
3371 AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1);
3372 SSCOP_MSG_FREE(msg);
3373 sscop_set_state(sscop, SSCOP_IDLE);
3377 * p 57: IN_REC_PEND && BGREJ PDU
3378 * arg is pdu (freed)
3381 sscop_inrec_bgrej(struct sscop *sscop, struct sscop_msg *msg)
3383 MAAL_ERROR(sscop, 'D', 0);
3384 AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1);
3385 SSCOP_MSG_FREE(msg);
3386 sscop_set_state(sscop, SSCOP_IDLE);
3390 * p 57: IN_REC_PEND && USTAT PDU
3391 * arg is pdu (freed)
3394 sscop_inrec_ustat(struct sscop *sscop, struct sscop_msg *msg)
3396 MAAL_ERROR(sscop, 'I', 0);
3398 send_end(sscop, 1, NULL);
3399 AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1);
3400 SSCOP_MSG_FREE(msg);
3401 sscop_set_state(sscop, SSCOP_IDLE);
3405 * p 57: IN_REC_PEND && STAT PDU
3406 * arg is pdu (freed)
3409 sscop_inrec_stat(struct sscop *sscop, struct sscop_msg *msg)
3411 MAAL_ERROR(sscop, 'H', 0);
3413 send_end(sscop, 1, NULL);
3414 AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1);
3415 SSCOP_MSG_FREE(msg);
3416 sscop_set_state(sscop, SSCOP_IDLE);
3420 * p 57: IN_REC_PEND && POLL PDU
3421 * arg is pdu (freed)
3424 sscop_inrec_poll(struct sscop *sscop, struct sscop_msg *msg)
3426 MAAL_ERROR(sscop, 'G', 0);
3428 send_end(sscop, 1, NULL);
3429 AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1);
3430 SSCOP_MSG_FREE(msg);
3431 sscop_set_state(sscop, SSCOP_IDLE);
3435 * p 57: IN_REC_PEND && SD PDU
3436 * arg is pdu (freed)
3439 sscop_inrec_sd(struct sscop *sscop, struct sscop_msg *msg)
3441 MAAL_ERROR(sscop, 'A', 0);
3443 send_end(sscop, 1, NULL);
3444 AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1);
3445 SSCOP_MSG_FREE(msg);
3446 sscop_set_state(sscop, SSCOP_IDLE);
3450 * p 58: IN_REC_PEND && RSAK PDU
3451 * arg is pdu (freed).
3454 sscop_inrec_rsak(struct sscop *sscop, struct sscop_msg *msg)
3456 SSCOP_MSG_FREE(msg);
3457 MAAL_ERROR(sscop, 'K', 0);
3461 * p 58: IN_REC_PEND && RS PDU
3462 * arg is pdu (freed).
3465 sscop_inrec_rs(struct sscop *sscop, struct sscop_msg *msg)
3469 pdu.sscop_null = MBUF_STRIP32(msg->m);
3471 if(m_detect_retransmission(sscop, msg)) {
3472 SSCOP_MSG_FREE(msg);
3473 MAAL_ERROR(sscop, 'J', 0);
3476 (void)MBUF_STRIP32(msg->m);
3478 sscop->vt_ms = pdu.sscop_ns;
3479 AAL_UU_SIGNAL(sscop, SSCOP_RESYNC_indication, msg, pdu.sscop_pl, 0);
3481 sscop_set_state(sscop, SSCOP_IN_RESYNC_PEND);
3485 * p 59: IN_REC_PEND && ER PDU
3486 * arg is pdu (freed)
3489 sscop_inrec_er(struct sscop *sscop, struct sscop_msg *msg)
3493 pdu.sscop_null = MBUF_STRIP32(msg->m);
3495 if(!m_detect_retransmission(sscop, msg)) {
3496 MAAL_ERROR(sscop, 'L', 0);
3499 SSCOP_MSG_FREE(msg);
3503 * p 59: IN_REC_PEND && BGN PDU
3504 * arg is pdu (freed).
3508 sscop_inrec_bgn(struct sscop *sscop, struct sscop_msg *msg)
3512 pdu.sscop_null = MBUF_STRIP32(msg->m);
3514 if(m_detect_retransmission(sscop, msg)) {
3515 MAAL_ERROR(sscop, 'B', 0);
3516 SSCOP_MSG_FREE(msg);
3519 (void)MBUF_STRIP32(msg->m);
3521 sscop->vt_ms = pdu.sscop_ns;
3522 AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 0);
3523 AAL_UU_SIGNAL(sscop, SSCOP_ESTABLISH_indication, msg, pdu.sscop_pl, 0);
3525 sscop_set_state(sscop, SSCOP_IN_PEND);
3529 * p 59: IN_REC_PEND && BGAK PDU
3530 * arg is pdu (freed)
3534 sscop_inrec_bgak(struct sscop *sscop, struct sscop_msg *msg)
3536 MAAL_ERROR(sscop, 'C', 0);
3537 SSCOP_MSG_FREE(msg);
3541 * p 59: IN_REC_PEND && ERAK PDU
3542 * arg is pdu (freed)
3546 sscop_inrec_erak(struct sscop *sscop, struct sscop_msg *msg)
3548 MAAL_ERROR(sscop, 'M', 0);
3549 SSCOP_MSG_FREE(msg);
3553 * p 60: READY && RESYNC request
3557 sscop_ready_sync_req(struct sscop *sscop, struct sscop_msg *uu)
3561 m_reset_data_xfer_timers(sscop);
3564 m_initialize_mr(sscop);
3565 send_rs(sscop, 0, sscop->uu_rs);
3566 m_release_buffers(sscop);
3567 TIMER_RESTART(sscop, cc);
3569 sscop_set_state(sscop, SSCOP_OUT_RESYNC_PEND);
3574 * p 60: READY && AA-RELEASE.request
3578 sscop_ready_release_req(struct sscop *sscop, struct sscop_msg *uu)
3582 m_reset_data_xfer_timers(sscop);
3584 send_end(sscop, 0, sscop->uu_end);
3585 m_prepare_retrieval(sscop);
3586 TIMER_RESTART(sscop, cc);
3588 sscop_set_state(sscop, SSCOP_OUT_DIS_PEND);
3592 * p 61: READY && ER PDU
3593 * arg is pdu (freed).
3596 sscop_ready_er(struct sscop *sscop, struct sscop_msg *msg)
3600 pdu.sscop_null = MBUF_STRIP32(msg->m);
3602 if(m_detect_retransmission(sscop, msg)) {
3603 TIMER_RESTART(sscop, nr);
3606 m_reset_data_xfer_timers(sscop);
3607 sscop->vt_ms = pdu.sscop_ns;
3608 m_prepare_recovery(sscop);
3609 m_deliver_data(sscop);
3611 AAL_SIG(sscop, SSCOP_RECOVER_indication);
3613 sscop_set_state(sscop, SSCOP_IN_REC_PEND);
3616 SSCOP_MSG_FREE(msg);
3620 * p 61: READY && BGN PDU
3621 * arg is pdu (freed)
3624 sscop_ready_bgn(struct sscop *sscop, struct sscop_msg *msg)
3628 pdu.sscop_null = MBUF_STRIP32(msg->m);
3630 if(m_detect_retransmission(sscop, msg)) {
3631 TIMER_RESTART(sscop, nr);
3632 send_bgak(sscop, sscop->uu_bgak);
3633 SSCOP_MSG_FREE(msg);
3636 (void)MBUF_STRIP32(msg->m);
3638 m_reset_data_xfer_timers(sscop);
3639 sscop->vt_ms = pdu.sscop_ns;
3641 AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 0);
3642 AAL_UU_SIGNAL(sscop, SSCOP_ESTABLISH_indication, msg, pdu.sscop_pl, 0);
3644 m_prepare_retrieval(sscop);
3646 sscop_set_state(sscop, SSCOP_IN_PEND);
3650 * p 62: READY && ENDAK PDU
3651 * arg is pdu (freed)
3654 sscop_ready_endak(struct sscop *sscop, struct sscop_msg *msg)
3656 m_reset_data_xfer_timers(sscop);
3657 MAAL_ERROR(sscop, 'F', 0);
3658 AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1);
3659 m_prepare_retrieval(sscop);
3660 SSCOP_MSG_FREE(msg);
3661 sscop_set_state(sscop, SSCOP_IDLE);
3665 * p 62: READY && BGREJ PDU
3666 * arg is pdu (freed)
3669 sscop_ready_bgrej(struct sscop *sscop, struct sscop_msg *msg)
3671 m_reset_data_xfer_timers(sscop);
3672 MAAL_ERROR(sscop, 'D', 0);
3673 AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1);
3674 m_prepare_retrieval(sscop);
3675 SSCOP_MSG_FREE(msg);
3676 sscop_set_state(sscop, SSCOP_IDLE);
3680 * p 62: READY && RS PDU
3681 * arg is pdu (freed)
3684 sscop_ready_rs(struct sscop *sscop, struct sscop_msg *msg)
3688 pdu.sscop_null = MBUF_STRIP32(msg->m);
3690 if(m_detect_retransmission(sscop, msg)) {
3691 SSCOP_MSG_FREE(msg);
3692 TIMER_RESTART(sscop, nr);
3696 (void)MBUF_STRIP32(msg->m);
3698 m_reset_data_xfer_timers(sscop);
3699 sscop->vt_ms = pdu.sscop_ns;
3700 AAL_UU_SIGNAL(sscop, SSCOP_RESYNC_indication, msg, pdu.sscop_pl, 0);
3701 m_prepare_retrieval(sscop);
3703 sscop_set_state(sscop, SSCOP_IN_RESYNC_PEND);
3707 * p 62: READY && END PDU
3708 * arg is pdu (freed)
3711 sscop_ready_end(struct sscop *sscop, struct sscop_msg *msg)
3715 pdu.sscop_null = MBUF_STRIP32(msg->m);
3716 (void)MBUF_STRIP32(msg->m);
3718 m_reset_data_xfer_timers(sscop);
3720 AAL_UU_SIGNAL(sscop, SSCOP_RELEASE_indication,
3721 msg, pdu.sscop_pl, (u_int)pdu.sscop_s);
3722 m_prepare_retrieval(sscop);
3724 sscop_set_state(sscop, SSCOP_IDLE);
3728 * p 63: READY && POLL expiry
3731 sscop_ready_tpoll(struct sscop *sscop, struct sscop_msg *unused __unused)
3736 m_set_poll_timer(sscop);
3740 * p 63: READY && KEEP_ALIVE expiry
3743 sscop_ready_tka(struct sscop *sscop, struct sscop_msg *unused __unused)
3748 m_set_poll_timer(sscop);
3752 * p 63: READY && IDLE expiry
3755 sscop_ready_tidle(struct sscop *sscop, struct sscop_msg *unused __unused)
3757 TIMER_RESTART(sscop, nr);
3761 m_set_poll_timer(sscop);
3765 * p 63: READY && NO_RESPONSE expiry
3769 sscop_ready_nr(struct sscop *sscop, struct sscop_msg *unused __unused)
3771 m_reset_data_xfer_timers(sscop);
3772 MAAL_ERROR(sscop, 'P', 0);
3774 send_end(sscop, 1, NULL);
3775 AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1);
3776 m_prepare_retrieval(sscop);
3777 sscop_set_state(sscop, SSCOP_IDLE);
3781 * p 63: READY && AA-DATA.request
3782 * arg is message (queued).
3785 sscop_ready_userdata(struct sscop *sscop, struct sscop_msg *msg)
3787 MSGQ_APPEND(&sscop->xq, msg);
3789 sscop_signal(sscop, SIG_PDU_Q, msg);
3793 * p 64: READY && SD PDU queued up
3797 sscop_ready_pduq(struct sscop *sscop, struct sscop_msg *unused __unused)
3799 struct sscop_msg *msg;
3801 if(sscop->rxq != 0) {
3802 TAILQ_FOREACH(msg, &sscop->xbuf, link)
3805 ASSERT(msg != NULL);
3808 send_sd(sscop, msg->m, msg->seqno);
3809 msg->poll_seqno = sscop->vt_ps;
3810 if(sscop->poll_after_rex && sscop->rxq == 0)
3811 goto poll; /* -> A */
3813 goto maybe_poll; /* -> B */
3816 if(MSGQ_EMPTY(&sscop->xq))
3819 if(sscop->vt_s >= sscop->vt_ms) {
3820 /* Send windows closed */
3821 TIMER_STOP(sscop, idle);
3822 TIMER_RESTART(sscop, nr);
3823 goto poll; /* -> A */
3826 msg = MSGQ_GET(&sscop->xq);
3827 msg->seqno = sscop->vt_s;
3828 send_sd(sscop, msg->m, msg->seqno);
3829 msg->poll_seqno = sscop->vt_ps;
3831 MSGQ_APPEND(&sscop->xbuf, msg);
3832 goto maybe_poll; /* -> B */
3836 * p 65: Poll handling
3838 maybe_poll: /* label B */
3840 if(TIMER_ISACT(sscop, poll)) {
3841 if(sscop->vt_pd < sscop->maxpd)
3844 if(TIMER_ISACT(sscop, idle)) {
3845 TIMER_STOP(sscop, idle);
3846 TIMER_RESTART(sscop, nr);
3848 TIMER_STOP(sscop, ka);
3850 if(sscop->vt_pd < sscop->maxpd) {
3851 TIMER_RESTART(sscop, poll);
3859 TIMER_RESTART(sscop, poll);
3863 * p 67: common recovery start
3866 sscop_recover(struct sscop *sscop)
3871 m_initialize_mr(sscop);
3873 m_prepare_recovery(sscop);
3875 TIMER_RESTART(sscop, cc);
3877 sscop_set_state(sscop, SSCOP_OUT_REC_PEND);
3881 * p 66: READY && SD PDU
3882 * arg is received message.
3885 sscop_ready_sd(struct sscop *sscop, struct sscop_msg *msg)
3890 pdu.sscop_null = MBUF_STRIP32(msg->m);
3891 msg->seqno = pdu.sscop_ns;
3894 MBUF_UNPAD(msg->m, pdu.sscop_pl);
3896 if(msg->seqno >= sscop->vr_mr) {
3897 /* message outside window */
3898 if(sscop->vr_h < sscop->vr_mr) {
3899 send_ustat(sscop, sscop->vr_h, sscop->vr_mr, -1);
3900 sscop->vr_h = sscop->vr_mr;
3902 SSCOP_MSG_FREE(msg);
3906 if(msg->seqno == sscop->vr_r) {
3907 if(msg->seqno == sscop->vr_h) {
3908 sscop->vr_r = msg->seqno + 1;
3909 sscop->vr_h = msg->seqno + 1;
3911 AAL_DATA(sscop, SSCOP_DATA_indication,
3912 msg->m, msg->seqno);
3914 SSCOP_MSG_FREE(msg);
3919 AAL_DATA(sscop, SSCOP_DATA_indication,
3920 msg->m, msg->seqno);
3922 SSCOP_MSG_FREE(msg);
3925 if((msg = MSGQ_PEEK(&sscop->rbuf)) == NULL)
3928 ASSERT(sn >= sscop->vr_r);
3929 if(sn != sscop->vr_r)
3931 msg = MSGQ_GET(&sscop->rbuf);
3936 /* Messages were lost */
3938 /* XXX Flow control */
3939 if(msg->seqno == sscop->vr_h) {
3940 QINSERT(&sscop->rbuf, msg);
3944 if(sscop->vr_h < msg->seqno) {
3945 QINSERT(&sscop->rbuf, msg);
3946 send_ustat(sscop, sscop->vr_h, msg->seqno, -1);
3947 sscop->vr_h = msg->seqno + 1;
3951 if(QFIND(&sscop->rbuf, msg->seqno) == NULL) {
3952 QINSERT(&sscop->rbuf, msg);
3956 /* error: start recovery */
3957 SSCOP_MSG_FREE(msg);
3958 m_reset_data_xfer_timers(sscop);
3959 MAAL_ERROR(sscop, 'Q', 0);
3960 sscop_recover(sscop);
3964 * p 67: READY && POLL PDU
3967 sscop_ready_poll(struct sscop *sscop, struct sscop_msg *msg)
3972 struct SSCOP_MBUF_T *m;
3974 pdu.sscop_null = MBUF_STRIP32(msg->m);
3975 seqno.sscop_null = MBUF_STRIP32(msg->m);
3977 if((u_int)pdu.sscop_ns < sscop->vr_h) {
3978 SSCOP_MSG_FREE(msg);
3979 m_reset_data_xfer_timers(sscop);
3980 MAAL_ERROR(sscop, 'Q', 0);
3981 sscop_recover(sscop);
3984 nps = seqno.sscop_n;
3986 if((u_int)pdu.sscop_ns > sscop->vr_mr)
3987 sscop->vr_h = sscop->vr_mr;
3989 sscop->vr_h = pdu.sscop_ns;
3991 SSCOP_MSG_FREE(msg);
3993 /* build stat pdu */
3994 if((m = MBUF_ALLOC(sscop->maxstat * 4 + 12)) == NULL) {
3995 FAILURE("sscop: cannot allocate STAT");
4000 while(sn != sscop->vr_h) {
4001 /* loop through burst we already have */
4003 if(sn >= sscop->vr_h) {
4004 seqno.sscop_null = 0;
4006 MBUF_APPEND32(m, seqno.sscop_null);
4009 if(QFIND(&sscop->rbuf, sn) == NULL)
4014 /* start of a hole */
4015 seqno.sscop_null = 0;
4017 MBUF_APPEND32(m, seqno.sscop_null);
4018 if(MBUF_LEN(m)/4 >= sscop->maxstat) {
4019 send_stat(sscop, nps, m);
4020 if((m = MBUF_ALLOC(sscop->maxstat * 4 + 12)) == NULL) {
4021 FAILURE("sscop: cannot allocate STAT");
4024 seqno.sscop_null = 0;
4026 MBUF_APPEND32(m, seqno.sscop_null);
4030 } while(sn < sscop->vr_h && !QFIND(&sscop->rbuf, sn));
4031 seqno.sscop_null = 0;
4033 MBUF_APPEND32(m, seqno.sscop_null);
4036 send_stat(sscop, nps, m);
4040 * p 69: READY && USTAT PDU
4041 * arg is msg (freed)
4044 sscop_ready_ustat(struct sscop *sscop, struct sscop_msg *msg)
4047 union seqno nmr, sq1, sq2;
4050 pdu.sscop_null = MBUF_STRIP32(msg->m);
4051 nmr.sscop_null = MBUF_STRIP32(msg->m);
4052 sq2.sscop_null = MBUF_STRIP32(msg->m);
4053 sq1.sscop_null = MBUF_STRIP32(msg->m);
4055 SSCOP_MSG_FREE(msg);
4057 cnt = sq1.sscop_n - sq2.sscop_n;
4059 if((u_int)pdu.sscop_ns < sscop->vt_a || (u_int)pdu.sscop_ns >= sscop->vt_s) {
4060 VERBERR(sscop, SSCOP_DBG_ERR, (sscop, sscop->aarg,
4061 "USTAT: N(R) outside VT(A)...VT(S)-1: N(R)=%u VT(A)=%u "
4062 "VT(S)=%u", (u_int)pdu.sscop_ns, sscop->vt_a, sscop->vt_s));
4066 /* Acknowledge all messages between VT(A) and N(R)-1. N(R) is the new
4067 * next in sequence-SD-number of the receiver and means, it has all
4068 * messages below N(R). Remove all message below N(R) from the
4069 * transmission buffer. It may already be removed because of an
4070 * earlier selective ACK in a STAT message.
4072 while((msg = MSGQ_PEEK(&sscop->xbuf)) != NULL && msg->seqno < (u_int)pdu.sscop_ns) {
4073 ASSERT(msg->seqno >= sscop->vt_a);
4074 MSGQ_REMOVE(&sscop->xbuf, msg);
4075 SSCOP_MSG_FREE(msg);
4078 /* Update the in-sequence acknowledge and the send window */
4079 sscop->vt_a = pdu.sscop_ns;
4080 sscop->vt_ms = nmr.sscop_n;
4082 /* check, that the range of requested re-transmissions is between
4083 * the in-sequence-ack and the highest up-to-now transmitted SD
4085 if(sq1.sscop_n >= sq2.sscop_n
4086 || (u_int)sq1.sscop_n < sscop->vt_a
4087 || (u_int)sq2.sscop_n >= sscop->vt_s) {
4088 VERBERR(sscop, SSCOP_DBG_ERR, (sscop, sscop->aarg,
4089 "USTAT: seq1 or seq2 outside VT(A)...VT(S)-1 or seq1>=seq2:"
4090 " seq1=%u seq2=%u VT(A)=%u VT(S)=%u",
4091 sq1.sscop_n, sq2.sscop_n, sscop->vt_a, sscop->vt_s));
4096 * Retransmit all messages from seq1 to seq2-1
4100 * The message may not be in the transmit buffer if it was
4101 * already acked by a STAT. This means, the receiver is
4104 if((msg = QFIND(&sscop->xbuf, sq1.sscop_n)) == NULL) {
4105 VERBERR(sscop, SSCOP_DBG_ERR, (sscop, sscop->aarg,
4106 "USTAT: message %u not found in xmit buffer",
4112 * If it is not yet in the re-transmission queue, put it there
4117 sscop_signal(sscop, SIG_PDU_Q, msg);
4120 } while(sq1.sscop_n != sq2.sscop_n);
4123 * report the re-transmission to the management
4125 MAAL_ERROR(sscop, 'V', cnt);
4129 m_reset_data_xfer_timers(sscop);
4130 MAAL_ERROR(sscop, 'T', 0);
4131 sscop_recover(sscop);
4135 * p 70: READY && STAT PDU
4136 * arg is msg (freed).
4139 sscop_ready_stat(struct sscop *sscop, struct sscop_msg *msg)
4142 union seqno nps, nmr;
4143 u_int len, seq1, seq2, cnt;
4144 struct sscop_msg *m;
4146 pdu.sscop_null = MBUF_STRIP32(msg->m);
4147 nmr.sscop_null = MBUF_STRIP32(msg->m);
4148 nps.sscop_null = MBUF_STRIP32(msg->m);
4150 len = MBUF_LEN(msg->m) / 4;
4152 if((u_int)nps.sscop_n < sscop->vt_pa
4153 || (u_int)nps.sscop_n > sscop->vt_ps) {
4154 SSCOP_MSG_FREE(msg);
4155 m_reset_data_xfer_timers(sscop);
4156 MAAL_ERROR(sscop, 'R', 0);
4157 sscop_recover(sscop);
4161 if((u_int)pdu.sscop_ns < sscop->vt_a
4162 || (u_int)pdu.sscop_ns > sscop->vt_s) {
4164 * The in-sequence acknowledge, i.e. the receivers's next
4165 * expected in-sequence msg is outside the window between
4166 * the transmitters in-sequence ack and highest seqno -
4167 * the receiver seems to be confused.
4169 VERBERR(sscop, SSCOP_DBG_ERR, (sscop, sscop->aarg,
4170 "STAT: N(R) outside VT(A)...VT(S)-1: N(R)=%u VT(A)=%u "
4171 "VT(S)=%u", (u_int)pdu.sscop_ns, sscop->vt_a, sscop->vt_s));
4173 SSCOP_MSG_FREE(msg);
4174 m_reset_data_xfer_timers(sscop);
4175 MAAL_ERROR(sscop, 'S', 0);
4176 sscop_recover(sscop);
4180 /* Acknowledge all messages between VT(A) and N(R)-1. N(R) is the new
4181 * next in sequence-SD-number of the receiver and means, it has all
4182 * messages below N(R). Remove all message below N(R) from the
4183 * transmission buffer. It may already be removed because of an
4184 * earlier selective ACK in a STAT message.
4186 while((m = MSGQ_PEEK(&sscop->xbuf)) != NULL
4187 && m->seqno < (u_int)pdu.sscop_ns) {
4188 ASSERT(m->seqno >= sscop->vt_a);
4189 MSGQ_REMOVE(&sscop->xbuf, m);
4194 * Update in-sequence ack, poll-ack and send window.
4196 sscop->vt_a = pdu.sscop_ns;
4197 sscop->vt_pa = nps.sscop_n;
4198 sscop->vt_ms = nmr.sscop_n;
4202 seq1 = MBUF_GET32(msg->m);
4204 if(seq1 >= sscop->vt_s) {
4205 VERBERR(sscop, SSCOP_DBG_ERR, (sscop, sscop->aarg,
4206 "STAT: seq1 >= VT(S): seq1=%u VT(S)=%u",
4207 seq1, sscop->vt_s));
4212 seq2 = MBUF_GET32(msg->m);
4214 if(seq1 >= seq2 || seq2 > sscop->vt_s) {
4215 VERBERR(sscop, SSCOP_DBG_ERR, (sscop,
4216 sscop->aarg, "STAT: seq1 >= seq2 or "
4217 "seq2 > VT(S): seq1=%u seq2=%u VT(S)=%u",
4218 seq1, seq2, sscop->vt_s));
4224 * The receiver requests the re-transmission
4225 * of some message, but has acknowledged it
4226 * already in an earlier STAT (it isn't in the
4227 * transmitt buffer anymore).
4229 if((m = QFIND(&sscop->xbuf, seq1)) == NULL) {
4230 VERBERR(sscop, SSCOP_DBG_ERR,
4231 (sscop, sscop->aarg, "STAT: message"
4232 " %u not found in xmit buffer",
4236 if(m->poll_seqno < (u_int)nps.sscop_n
4237 && (u_int)nps.sscop_n <= sscop->vt_ps)
4242 sscop_signal(sscop, SIG_PDU_Q, msg);
4244 } while(++seq1 < seq2);
4249 seq2 = MBUF_GET32(msg->m);
4252 if(seq1 >= seq2 || seq2 > sscop->vt_s) {
4253 VERBERR(sscop, SSCOP_DBG_ERR, (sscop,
4254 sscop->aarg, "STAT: seq1 >= seq2 or "
4255 "seq2 > VT(S): seq1=%u seq2=%u VT(S)=%u",
4256 seq1, seq2, sscop->vt_s));
4260 /* OK now the sucessful transmitted messages. Note, that
4261 * some messages may already be out of the buffer because
4262 * of earlier STATS */
4264 if(sscop->clear_buffers) {
4265 if((m = QFIND(&sscop->xbuf, seq1)) != NULL) {
4266 MSGQ_REMOVE(&sscop->xbuf, m);
4270 } while(++seq1 != seq2);
4275 MAAL_ERROR(sscop, 'V', cnt);
4277 SSCOP_MSG_FREE(msg);
4280 if(sscop->vt_s >= sscop->vt_ms) {
4282 * The receiver has closed the window: report to management
4286 MAAL_ERROR(sscop, 'W', 0);
4288 } else if(!sscop->credit) {
4290 * The window was forcefully closed above, but
4291 * now re-opened. Report to management.
4294 MAAL_ERROR(sscop, 'X', 0);
4297 if(TIMER_ISACT(sscop, poll)) {
4298 TIMER_RESTART(sscop, nr);
4299 } else if(!TIMER_ISACT(sscop, idle)) {
4300 TIMER_STOP(sscop, ka);
4301 TIMER_STOP(sscop, nr);
4302 TIMER_RESTART(sscop, idle);
4307 * P. 73: any state & UDATA_REQUEST
4308 * arg is pdu (queued)
4311 sscop_udata_req(struct sscop *sscop, struct sscop_msg *msg)
4313 MSGQ_APPEND(&sscop->uxq, msg);
4314 sscop_signal(sscop, SIG_UPDU_Q, msg);
4318 * P. 73: any state & MDATA_REQUEST
4319 * arg is pdu (queued)
4322 sscop_mdata_req(struct sscop *sscop, struct sscop_msg *msg)
4324 MSGQ_APPEND(&sscop->mxq, msg);
4325 sscop_signal(sscop, SIG_MPDU_Q, msg);
4329 * P. 74: any state & UDATA queued
4333 sscop_upduq(struct sscop *sscop, struct sscop_msg *unused __unused)
4335 struct sscop_msg *msg;
4339 while((msg = MSGQ_GET(&sscop->uxq)) != NULL) {
4340 send_ud(sscop, msg->m);
4342 SSCOP_MSG_FREE(msg);
4347 * P. 74: any state & MDATA queued
4351 sscop_mpduq(struct sscop *sscop, struct sscop_msg *unused __unused)
4353 struct sscop_msg *msg;
4357 while((msg = MSGQ_GET(&sscop->mxq)) != NULL) {
4358 send_md(sscop, msg->m);
4360 SSCOP_MSG_FREE(msg);
4369 sscop_md(struct sscop *sscop, struct sscop_msg *msg)
4373 pdu.sscop_null = MBUF_STRIP32(msg->m);
4375 MBUF_UNPAD(msg->m, pdu.sscop_pl);
4377 MAAL_DATA(sscop, msg->m);
4379 SSCOP_MSG_FREE(msg);
4387 sscop_ud(struct sscop *sscop, struct sscop_msg *msg)
4391 pdu.sscop_null = MBUF_STRIP32(msg->m);
4393 MBUF_UNPAD(msg->m, pdu.sscop_pl);
4395 AAL_DATA(sscop, SSCOP_UDATA_indication, msg->m, 0);
4397 SSCOP_MSG_FREE(msg);
4402 * p 33: IDLE & RETRIEVE
4403 * p 39: IN_PEND & RETRIEVE
4404 * p 42: OUT_DIS_PEND & RETRIEVE
4405 * p 48: IN_RESYNC_PEND & RETRIEVE
4406 * p 53: REC_PEND & RETRIEVE
4407 * p 58: IN_REC_PEND & RETRIEVE
4410 sscop_retrieve(struct sscop *sscop, struct sscop_msg *msg)
4412 m_data_retrieval(sscop, msg->rexmit);
4413 SSCOP_MSG_FREE(msg);
4416 /************************************************************/
4418 * GENERAL EVENT HANDLING
4422 * State/event matrix.
4424 * Entries marked with Z are not specified in Q.2110, but are added for
4425 * the sake of stability.
4428 void (*func)(struct sscop *, struct sscop_msg *);
4429 int (*cond)(struct sscop *);
4430 } state_matrix[SSCOP_NSTATES][SIG_NUM] = {
4432 /* SIG_BGN */ { sscop_idle_bgn, NULL },
4433 /* SIG_BGAK */ { sscop_idle_bgak, NULL },
4434 /* SIG_END */ { sscop_idle_end, NULL },
4435 /* SIG_ENDAK */ { sscop_ignore_pdu, NULL },
4436 /* SIG_RS */ { sscop_idle_rs, NULL },
4437 /* SIG_RSAK */ { sscop_idle_rsak, NULL },
4438 /* SIG_BGREJ */ { sscop_idle_bgrej, NULL },
4439 /* SIG_SD */ { sscop_idle_sd, NULL },
4440 /* SIG_ER */ { sscop_idle_er, NULL },
4441 /* SIG_POLL */ { sscop_idle_poll, NULL },
4442 /* SIG_STAT */ { sscop_idle_stat, NULL },
4443 /* SIG_USTAT */ { sscop_idle_ustat, NULL },
4444 /* SIG_UD */ { sscop_ud, NULL },
4445 /* SIG_MD */ { sscop_md, NULL },
4446 /* SIG_ERAK */ { sscop_idle_erak, NULL },
4447 /* SIG_T_CC */ { NULL, NULL },
4448 /* SIG_T_POLL */ { NULL, NULL },
4449 /* SIG_T_KA */ { NULL, NULL },
4450 /* SIG_T_NR */ { NULL, NULL },
4451 /* SIG_T_IDLE */ { NULL, NULL },
4452 /* SIG_PDU_Q */ { sscop_flush_pduq, NULL },
4453 /* SIG_USER_DATA */ { NULL, NULL },
4454 /* SIG_ESTAB_REQ */ { sscop_idle_establish_req, NULL },
4455 /* SIG_ESTAB_RESP */ { NULL, NULL },
4456 /* SIG_RELEASE_REQ */ { NULL, NULL },
4457 /* SIG_RECOVER */ { NULL, NULL },
4458 /* SIG_SYNC_REQ */ { NULL, NULL },
4459 /* SIG_SYNC_RESP */ { NULL, NULL },
4460 /* SIG_UDATA */ { sscop_udata_req, NULL },
4461 /* SIG_MDATA */ { sscop_mdata_req, NULL },
4462 /* SIG_UPDU_Q */ { sscop_upduq, NULL },
4463 /* SIG_MPDU_Q */ { sscop_mpduq, NULL },
4464 /* SIG_RETRIEVE */ { sscop_retrieve, NULL },
4466 /* SSCOP_OUT_PEND */ {
4467 /* SIG_BGN */ { sscop_outpend_bgn, NULL },
4468 /* SIG_BGAK */ { sscop_outpend_bgak, NULL },
4469 /* SIG_END */ { sscop_ignore_pdu, NULL },
4470 /* SIG_ENDAK */ { sscop_ignore_pdu, NULL },
4471 /* SIG_RS */ { sscop_ignore_pdu, NULL },
4472 /* SIG_RSAK */ { sscop_ignore_pdu, NULL },
4473 /* SIG_BGREJ */ { sscop_outpend_bgrej, NULL },
4474 /* SIG_SD */ { sscop_ignore_pdu, NULL },
4475 /* SIG_ER */ { sscop_ignore_pdu, NULL },
4476 /* SIG_POLL */ { sscop_ignore_pdu, NULL },
4477 /* SIG_STAT */ { sscop_ignore_pdu, NULL },
4478 /* SIG_USTAT */ { sscop_ignore_pdu, NULL },
4479 /* SIG_UD */ { sscop_ud, NULL },
4480 /* SIG_MD */ { sscop_md, NULL },
4481 /* SIG_ERAK */ { sscop_ignore_pdu, NULL },
4482 /* SIG_T_CC */ { sscop_outpend_tcc, NULL },
4483 /* SIG_T_POLL */ { NULL, NULL },
4484 /* SIG_T_KA */ { NULL, NULL },
4485 /* SIG_T_NR */ { NULL, NULL },
4486 /* SIG_T_IDLE */ { NULL, NULL },
4487 /* SIG_PDU_Q */ { sscop_flush_pduq, NULL },
4488 /* SIG_USER_DATA */ { NULL, NULL },
4489 /* SIG_ESTAB_REQ */ { NULL, NULL },
4490 /* SIG_ESTAB_RESP */ { NULL, NULL },
4491 /* SIG_RELEASE_REQ */ { sscop_outpend_release_req, NULL },
4492 /* SIG_RECOVER */ { NULL, NULL },
4493 /* SIG_SYNC_REQ */ { NULL, NULL },
4494 /* SIG_SYNC_RESP */ { NULL, NULL },
4495 /* SIG_UDATA */ { sscop_udata_req, NULL },
4496 /* SIG_MDATA */ { sscop_mdata_req, NULL },
4497 /* SIG_UPDU_Q */ { sscop_upduq, NULL },
4498 /* SIG_MPDU_Q */ { sscop_mpduq, NULL },
4499 /* SIG_RETRIEVE */ { NULL, NULL },
4501 /* SSCOP_IN_PEND */ {
4502 /* SIG_BGN */ { sscop_inpend_bgn, NULL },
4503 /* SIG_BGAK */ { sscop_inpend_bgak, NULL },
4504 /* SIG_END */ { sscop_inpend_end, NULL },
4505 /* SIG_ENDAK */ { sscop_inpend_endak, NULL },
4506 /* SIG_RS */ { sscop_inpend_rs, NULL },
4507 /* SIG_RSAK */ { sscop_inpend_rsak, NULL },
4508 /* SIG_BGREJ */ { sscop_inpend_bgrej, NULL },
4509 /* SIG_SD */ { sscop_inpend_sd, NULL },
4510 /* SIG_ER */ { sscop_inpend_er, NULL },
4511 /* SIG_POLL */ { sscop_inpend_poll, NULL },
4512 /* SIG_STAT */ { sscop_inpend_stat, NULL },
4513 /* SIG_USTAT */ { sscop_inpend_ustat, NULL },
4514 /* SIG_UD */ { sscop_ud, NULL },
4515 /* SIG_MD */ { sscop_md, NULL },
4516 /* SIG_ERAK */ { sscop_inpend_erak, NULL },
4517 /* SIG_T_CC */ { NULL, NULL },
4518 /* SIG_T_POLL */ { NULL, NULL },
4519 /* SIG_T_KA */ { NULL, NULL },
4520 /* SIG_T_NR */ { NULL, NULL },
4521 /* SIG_T_IDLE */ { NULL, NULL },
4522 /* SIG_PDU_Q */ { sscop_flush_pduq, NULL },
4523 /* SIG_USER_DATA */ { NULL, NULL },
4524 /* SIG_ESTAB_REQ */ { NULL, NULL },
4525 /* SIG_ESTAB_RESP */ { sscop_inpend_establish_resp, NULL },
4526 /* SIG_RELEASE_REQ */ { sscop_inpend_release_req, NULL },
4527 /* SIG_RECOVER */ { NULL, NULL },
4528 /* SIG_SYNC_REQ */ { NULL, NULL },
4529 /* SIG_SYNC_RESP */ { NULL, NULL },
4530 /* SIG_UDATA */ { sscop_udata_req, NULL },
4531 /* SIG_MDATA */ { sscop_mdata_req, NULL },
4532 /* SIG_UPDU_Q */ { sscop_upduq, NULL },
4533 /* SIG_MPDU_Q */ { sscop_mpduq, NULL },
4534 /* SIG_RETRIEVE */ { sscop_retrieve, NULL },
4536 /* SSCOP_OUT_DIS_PEND */ {
4537 /* SIG_BGN */ { sscop_outdis_bgn, NULL },
4538 /* SIG_BGAK */ { sscop_ignore_pdu, NULL },
4539 /* SIG_END */ { sscop_outdis_end, NULL },
4540 /* SIG_ENDAK */ { sscop_outdis_endak, NULL },
4541 /* SIG_RS */ { sscop_ignore_pdu, NULL },
4542 /* SIG_RSAK */ { sscop_ignore_pdu, NULL },
4543 /* SIG_BGREJ */ { sscop_outdis_endak, NULL },
4544 /* SIG_SD */ { sscop_ignore_pdu, NULL },
4545 /* SIG_ER */ { sscop_ignore_pdu, NULL },
4546 /* SIG_POLL */ { sscop_ignore_pdu, NULL },
4547 /* SIG_STAT */ { sscop_ignore_pdu, NULL },
4548 /* SIG_USTAT */ { sscop_ignore_pdu, NULL },
4549 /* SIG_UD */ { sscop_ud, NULL },
4550 /* SIG_MD */ { sscop_md, NULL },
4551 /* SIG_ERAK */ { sscop_ignore_pdu, NULL },
4552 /* SIG_T_CC */ { sscop_outdis_cc, NULL },
4553 /* SIG_T_POLL */ { NULL, NULL },
4554 /* SIG_T_KA */ { NULL, NULL },
4555 /* SIG_T_NR */ { NULL, NULL },
4556 /* SIG_T_IDLE */ { NULL, NULL },
4557 /* SIG_PDU_Q */ { sscop_flush_pduq, NULL },
4558 /* SIG_USER_DATA */ { NULL, NULL },
4559 /* SIG_ESTAB_REQ */ { sscop_outdis_establish_req, NULL },
4560 /* SIG_ESTAB_RESP */ { NULL, NULL },
4561 /* SIG_RELEASE_REQ */ { NULL, NULL },
4562 /* SIG_RECOVER */ { NULL, NULL },
4563 /* SIG_SYNC_REQ */ { NULL, NULL },
4564 /* SIG_SYNC_RESP */ { NULL, NULL },
4565 /* SIG_UDATA */ { sscop_udata_req, NULL },
4566 /* SIG_MDATA */ { sscop_mdata_req, NULL },
4567 /* SIG_UPDU_Q */ { sscop_upduq, NULL },
4568 /* SIG_MPDU_Q */ { sscop_mpduq, NULL },
4569 /* SIG_RETRIEVE */ { sscop_retrieve, NULL },
4571 /* SSCOP_OUT_RESYNC_PEND */ {
4572 /* SIG_BGN */ { sscop_outsync_bgn, NULL },
4573 /* SIG_BGAK */ { sscop_ignore_pdu, NULL },
4574 /* SIG_END */ { sscop_outsync_end, NULL },
4575 /* SIG_ENDAK */ { sscop_outsync_endak, NULL },
4576 /* SIG_RS */ { sscop_outsync_rs, NULL },
4577 /* SIG_RSAK */ { sscop_outsync_rsak, NULL },
4578 /* SIG_BGREJ */ { sscop_outsync_bgrej, NULL },
4579 /* SIG_SD */ { sscop_ignore_pdu, NULL },
4580 /* SIG_ER */ { sscop_ignore_pdu, NULL },
4581 /* SIG_POLL */ { sscop_ignore_pdu, NULL },
4582 /* SIG_STAT */ { sscop_ignore_pdu, NULL },
4583 /* SIG_USTAT */ { sscop_ignore_pdu, NULL },
4584 /* SIG_UD */ { sscop_ud, NULL },
4585 /* SIG_MD */ { sscop_md, NULL },
4586 /* SIG_ERAK */ { sscop_ignore_pdu, NULL },
4587 /* SIG_T_CC */ { sscop_outsync_cc, NULL },
4588 /* SIG_T_POLL */ { NULL, NULL },
4589 /* SIG_T_KA */ { NULL, NULL },
4590 /* SIG_T_NR */ { NULL, NULL },
4591 /* SIG_T_IDLE */ { NULL, NULL },
4592 /* SIG_PDU_Q */ { sscop_flush_pduq, NULL },
4593 /* SIG_USER_DATA */ { NULL, NULL },
4594 /* SIG_ESTAB_REQ */ { NULL, NULL },
4595 /* SIG_ESTAB_RESP */ { NULL, NULL },
4596 /* SIG_RELEASE_REQ */ { sscop_outsync_release_req, NULL },
4597 /* SIG_RECOVER */ { NULL, NULL },
4598 /* SIG_SYNC_REQ */ { NULL, NULL },
4599 /* SIG_SYNC_RESP */ { NULL, NULL },
4600 /* SIG_UDATA */ { sscop_udata_req, NULL },
4601 /* SIG_MDATA */ { sscop_mdata_req, NULL },
4602 /* SIG_UPDU_Q */ { sscop_upduq, NULL },
4603 /* SIG_MPDU_Q */ { sscop_mpduq, NULL },
4604 /* SIG_RETRIEVE */ { NULL, NULL },
4606 /* SSCOP_IN_RESYNC_PEND */ {
4607 /* SIG_BGN */ { sscop_insync_bgn, NULL },
4608 /* SIG_BGAK */ { sscop_insync_bgak, NULL },
4609 /* SIG_END */ { sscop_insync_end, NULL },
4610 /* SIG_ENDAK */ { sscop_insync_endak, NULL },
4611 /* SIG_RS */ { sscop_insync_rs, NULL },
4612 /* SIG_RSAK */ { sscop_insync_rsak, NULL },
4613 /* SIG_BGREJ */ { sscop_insync_bgrej, NULL },
4614 /* SIG_SD */ { sscop_insync_sd, NULL },
4615 /* SIG_ER */ { sscop_insync_er, NULL },
4616 /* SIG_POLL */ { sscop_insync_poll, NULL },
4617 /* SIG_STAT */ { sscop_insync_stat, NULL },
4618 /* SIG_USTAT */ { sscop_insync_ustat, NULL },
4619 /* SIG_UD */ { sscop_ud, NULL },
4620 /* SIG_MD */ { sscop_md, NULL },
4621 /* SIG_ERAK */ { sscop_insync_erak, NULL },
4622 /* SIG_T_CC */ { NULL, NULL },
4623 /* SIG_T_POLL */ { NULL, NULL },
4624 /* SIG_T_KA */ { NULL, NULL },
4625 /* SIG_T_NR */ { NULL, NULL },
4626 /* SIG_T_IDLE */ { NULL, NULL },
4627 /* SIG_PDU_Q */ { sscop_flush_pduq, NULL },
4628 /* SIG_USER_DATA */ { NULL, NULL },
4629 /* SIG_ESTAB_REQ */ { NULL, NULL },
4630 /* SIG_ESTAB_RESP */ { NULL, NULL },
4631 /* SIG_RELEASE_REQ */ { sscop_insync_release_req, NULL },
4632 /* SIG_RECOVER */ { NULL, NULL },
4633 /* SIG_SYNC_REQ */ { NULL, NULL },
4634 /* SIG_SYNC_RESP */ { sscop_insync_sync_resp, NULL },
4635 /* SIG_UDATA */ { sscop_udata_req, NULL },
4636 /* SIG_MDATA */ { sscop_mdata_req, NULL },
4637 /* SIG_UPDU_Q */ { sscop_upduq, NULL },
4638 /* SIG_MPDU_Q */ { sscop_mpduq, NULL },
4639 /* SIG_RETRIEVE */ { sscop_retrieve, NULL },
4641 /* SSCOP_OUT_REC_PEND */ {
4642 /* SIG_BGN */ { sscop_outrec_bgn, NULL },
4643 /* SIG_BGAK */ { sscop_outrec_bgak, NULL },
4644 /* SIG_END */ { sscop_outrec_end, NULL },
4645 /* SIG_ENDAK */ { sscop_outrec_endak, NULL },
4646 /* SIG_RS */ { sscop_outrec_rs, NULL },
4647 /* SIG_RSAK */ { sscop_outrec_rsak, NULL },
4648 /* SIG_BGREJ */ { sscop_outrec_bgrej, NULL },
4649 /* SIG_SD */ { sscop_ignore_pdu, NULL },
4650 /* SIG_ER */ { sscop_outrec_er, NULL },
4651 /* SIG_POLL */ { sscop_ignore_pdu, NULL },
4652 /* SIG_STAT */ { sscop_ignore_pdu, NULL },
4653 /* SIG_USTAT */ { sscop_ignore_pdu, NULL },
4654 /* SIG_UD */ { sscop_ud, NULL },
4655 /* SIG_MD */ { sscop_md, NULL },
4656 /* SIG_ERAK */ { sscop_outrec_erak, NULL },
4657 /* SIG_T_CC */ { sscop_outrec_cc, NULL },
4658 /* SIG_T_POLL */ { NULL, NULL },
4659 /* SIG_T_KA */ { NULL, NULL },
4660 /* SIG_T_NR */ { NULL, NULL },
4661 /* SIG_T_IDLE */ { NULL, NULL },
4662 /* SIG_PDU_Q */ { sscop_outrec_pduq, NULL },
4663 /* SIG_USER_DATA */ { sscop_outrec_userdata, NULL },
4664 /* SIG_ESTAB_REQ */ { NULL, NULL },
4665 /* SIG_ESTAB_RESP */ { NULL, NULL },
4666 /* SIG_RELEASE_REQ */ { sscop_outrec_release_req, NULL },
4667 /* SIG_RECOVER */ { NULL, NULL },
4668 /* SIG_SYNC_REQ */ { sscop_outrec_sync_req, NULL },
4669 /* SIG_SYNC_RESP */ { NULL, NULL },
4670 /* SIG_UDATA */ { sscop_udata_req, NULL },
4671 /* SIG_MDATA */ { sscop_mdata_req, NULL },
4672 /* SIG_UPDU_Q */ { sscop_upduq, NULL },
4673 /* SIG_MPDU_Q */ { sscop_mpduq, NULL },
4674 /* SIG_RETRIEVE */ { NULL, NULL },
4676 /* SSCOP_REC_PEND */ {
4677 /* SIG_BGN */ { sscop_rec_bgn, NULL },
4678 /* SIG_BGAK */ { sscop_rec_bgak, NULL },
4679 /* SIG_END */ { sscop_rec_end, NULL },
4680 /* SIG_ENDAK */ { sscop_rec_endak, NULL },
4681 /* SIG_RS */ { sscop_rec_rs, NULL },
4682 /* SIG_RSAK */ { sscop_rec_rsak, NULL },
4683 /* SIG_BGREJ */ { sscop_rec_bgrej, NULL },
4684 /* SIG_SD */ { sscop_ignore_pdu, NULL },
4685 /* SIG_ER */ { sscop_rec_er, NULL },
4686 /* SIG_POLL */ { sscop_ignore_pdu, NULL },
4687 /* SIG_STAT */ { sscop_rec_stat, NULL },
4688 /* SIG_USTAT */ { sscop_rec_ustat, NULL },
4689 /* SIG_UD */ { sscop_ud, NULL },
4690 /* SIG_MD */ { sscop_md, NULL },
4691 /* SIG_ERAK */ { sscop_ignore_pdu, NULL },
4692 /* SIG_T_CC */ { NULL, NULL },
4693 /* SIG_T_POLL */ { NULL, NULL },
4694 /* SIG_T_KA */ { NULL, NULL },
4695 /* SIG_T_NR */ { NULL, NULL },
4696 /* SIG_T_IDLE */ { NULL, NULL },
4697 /* SIG_PDU_Q */ { sscop_rec_pduq, NULL },
4698 /* SIG_USER_DATA */ { NULL, NULL },
4699 /* SIG_ESTAB_REQ */ { NULL, NULL },
4700 /* SIG_ESTAB_RESP */ { NULL, NULL },
4701 /* SIG_RELEASE_REQ */ { sscop_rec_release_req, NULL },
4702 /* SIG_RECOVER */ { sscop_rec_recover, NULL },
4703 /* SIG_SYNC_REQ */ { sscop_rec_sync_req, NULL },
4704 /* SIG_SYNC_RESP */ { NULL, NULL },
4705 /* SIG_UDATA */ { sscop_udata_req, NULL },
4706 /* SIG_MDATA */ { sscop_mdata_req, NULL },
4707 /* SIG_UPDU_Q */ { sscop_upduq, NULL },
4708 /* SIG_MPDU_Q */ { sscop_mpduq, NULL },
4709 /* SIG_RETRIEVE */ { sscop_retrieve, NULL },
4711 /* SSCOP_IN_REC_PEND */ {
4712 /* SIG_BGN */ { sscop_inrec_bgn, NULL },
4713 /* SIG_BGAK */ { sscop_inrec_bgak, NULL },
4714 /* SIG_END */ { sscop_inrec_end, NULL },
4715 /* SIG_ENDAK */ { sscop_inrec_endak, NULL },
4716 /* SIG_RS */ { sscop_inrec_rs, NULL },
4717 /* SIG_RSAK */ { sscop_inrec_rsak, NULL },
4718 /* SIG_BGREJ */ { sscop_inrec_bgrej, NULL },
4719 /* SIG_SD */ { sscop_inrec_sd, NULL },
4720 /* SIG_ER */ { sscop_inrec_er, NULL },
4721 /* SIG_POLL */ { sscop_inrec_poll, NULL },
4722 /* SIG_STAT */ { sscop_inrec_stat, NULL },
4723 /* SIG_USTAT */ { sscop_inrec_ustat, NULL },
4724 /* SIG_UD */ { sscop_ud, NULL },
4725 /* SIG_MD */ { sscop_md, NULL },
4726 /* SIG_ERAK */ { sscop_inrec_erak, NULL },
4727 /* SIG_T_CC */ { NULL, NULL },
4728 /* SIG_T_POLL */ { NULL, NULL },
4729 /* SIG_T_KA */ { NULL, NULL },
4730 /* SIG_T_NR */ { NULL, NULL },
4731 /* SIG_T_IDLE */ { NULL, NULL },
4732 /* SIG_PDU_Q */ { sscop_inrec_pduq, NULL },
4733 /* SIG_USER_DATA */ { NULL, NULL },
4734 /* SIG_ESTAB_REQ */ { NULL, NULL },
4735 /* SIG_ESTAB_RESP */ { NULL, NULL },
4736 /* SIG_RELEASE_REQ */ { sscop_inrec_release_req, NULL },
4737 /* SIG_RECOVER */ { sscop_inrec_recover, NULL },
4738 /* SIG_SYNC_REQ */ { sscop_inrec_sync_req, NULL },
4739 /* SIG_SYNC_RESP */ { NULL, NULL },
4740 /* SIG_UDATA */ { sscop_udata_req, NULL },
4741 /* SIG_MDATA */ { sscop_mdata_req, NULL },
4742 /* SIG_UPDU_Q */ { sscop_upduq, NULL },
4743 /* SIG_MPDU_Q */ { sscop_mpduq, NULL },
4744 /* SIG_RETRIEVE */ { sscop_retrieve, NULL },
4747 /* SIG_BGN */ { sscop_ready_bgn, NULL },
4748 /* SIG_BGAK */ { sscop_ignore_pdu, NULL },
4749 /* SIG_END */ { sscop_ready_end, NULL },
4750 /* SIG_ENDAK */ { sscop_ready_endak, NULL },
4751 /* SIG_RS */ { sscop_ready_rs, NULL },
4752 /* SIG_RSAK */ { sscop_ignore_pdu, NULL },
4753 /* SIG_BGREJ */ { sscop_ready_bgrej, NULL },
4754 /* SIG_SD */ { sscop_ready_sd, NULL },
4755 /* SIG_ER */ { sscop_ready_er, NULL },
4756 /* SIG_POLL */ { sscop_ready_poll, NULL },
4757 /* SIG_STAT */ { sscop_ready_stat, NULL },
4758 /* SIG_USTAT */ { sscop_ready_ustat, NULL },
4759 /* SIG_UD */ { sscop_ud, NULL },
4760 /* SIG_MD */ { sscop_md, NULL },
4761 /* SIG_ERAK */ { sscop_ignore_pdu, NULL },
4762 /* SIG_T_CC */ { NULL, NULL },
4763 /* SIG_T_POLL */ { sscop_ready_tpoll, NULL },
4764 /* SIG_T_KA */ { sscop_ready_tka, NULL },
4765 /* SIG_T_NR */ { sscop_ready_nr, NULL },
4766 /* SIG_T_IDLE */ { sscop_ready_tidle, NULL },
4767 /* SIG_PDU_Q */ { sscop_ready_pduq, c_ready_pduq },
4768 /* SIG_USER_DATA */ { sscop_ready_userdata, NULL },
4769 /* SIG_ESTAB_REQ */ { NULL, NULL },
4770 /* SIG_ESTAB_RESP */ { NULL, NULL },
4771 /* SIG_RELEASE_REQ */ { sscop_ready_release_req, NULL },
4772 /* SIG_RECOVER */ { NULL, NULL },
4773 /* SIG_SYNC_REQ */ { sscop_ready_sync_req, NULL },
4774 /* SIG_SYNC_RESP */ { NULL, NULL },
4775 /* SIG_UDATA */ { sscop_udata_req, NULL },
4776 /* SIG_MDATA */ { sscop_mdata_req, NULL },
4777 /* SIG_UPDU_Q */ { sscop_upduq, NULL },
4778 /* SIG_MPDU_Q */ { sscop_mpduq, NULL },
4779 /* SIG_RETRIEVE */ { NULL, NULL },
4784 * Try to execute a signal. It is executed if
4785 * - it is illegal (in this case it is effectively ignored)
4786 * - it has no condition
4787 * - its condition is true
4788 * If it has a condition and that is false, the function does nothing and
4790 * If the signal gets executed, the signal function is responsible to release
4791 * the message (if any).
4794 sig_exec(struct sscop *sscop, u_int sig, struct sscop_msg *msg)
4796 void (*func)(struct sscop *, struct sscop_msg *);
4797 int (*cond)(struct sscop *);
4799 func = state_matrix[sscop->state][sig].func;
4800 cond = state_matrix[sscop->state][sig].cond;
4803 VERBOSE(sscop, SSCOP_DBG_BUG, (sscop, sscop->aarg,
4804 "no handler for %s in state %s - ignored",
4805 events[sig], states[sscop->state]));
4806 SSCOP_MSG_FREE(msg);
4809 if(cond == NULL || (*cond)(sscop)) {
4810 VERBOSE(sscop, SSCOP_DBG_EXEC, (sscop, sscop->aarg,
4811 "executing %s in %s", events[sig],
4812 states[sscop->state]));
4813 (*func)(sscop, msg);
4816 VERBOSE(sscop, SSCOP_DBG_EXEC, (sscop, sscop->aarg,
4817 "delaying %s in %s", events[sig],
4818 states[sscop->state]));
4824 * Deliver a signal to the given sscop
4825 * If it is delivered from inside a signal handler - queue it. If not,
4826 * execute it. After execution loop through the queue and execute all
4827 * pending signals. Signals, that cannot be executed because of entry
4828 * conditions are skipped.
4831 sscop_signal(struct sscop *sscop, u_int sig, struct sscop_msg *msg)
4833 struct sscop_sig *s;
4835 VERBOSE(sscop, SSCOP_DBG_INSIG, (sscop, sscop->aarg,
4836 "got signal %s in state %s%s", events[sig],
4837 states[sscop->state], sscop->in_sig ? " -- queuing" : ""));
4841 FAILURE("sscop: cannot allocate signal");
4842 SSCOP_MSG_FREE(msg);
4847 SIGQ_APPEND(&sscop->sigs, s);
4854 * Loop through the signal queue until we can't execute any signals.
4857 handle_sigs(struct sscop *sscop)
4859 struct sscop_sig *s;
4860 sscop_sigq_head_t dsigs, q;
4866 * Copy the current signal queue to the local one and empty
4867 * the signal queue. Then loop through the signals. After one
4868 * pass we have a list of delayed signals because of entry
4869 * conditions and a new list of signals. Merge them. Repeat until
4870 * the signal queue is either empty or contains only delayed signals.
4878 * Copy signal list and make sscop list empty
4880 SIGQ_MOVE(&sscop->sigs, &q);
4883 * Loop through the list
4885 while((s = SIGQ_GET(&q)) != NULL) {
4886 if(sig_exec(sscop, s->sig, s->msg)) {
4890 SIGQ_APPEND(&dsigs, s);
4895 * Merge lists by inserting delayed signals in front of
4896 * the signal list. preserving the order.
4898 SIGQ_PREPEND(&dsigs, &sscop->sigs);
4904 * Save a signal that should be executed only if state changes.
4907 sscop_save_signal(struct sscop *sscop, u_int sig, struct sscop_msg *msg)
4909 struct sscop_sig *s;
4913 FAILURE("sscop: cannot allocate signal");
4914 SSCOP_MSG_FREE(msg);
4919 SIGQ_APPEND(&sscop->saved_sigs, s);
4923 * Set a new state. If signals are waiting for a state change - append them to
4924 * the signal queue, so they get executed.
4927 sscop_set_state(struct sscop *sscop, u_int nstate)
4929 VERBOSE(sscop, SSCOP_DBG_STATE, (sscop, sscop->aarg,
4930 "changing state from %s to %s",
4931 states[sscop->state], states[nstate]));
4933 sscop->state = nstate;
4934 SIGQ_MOVE(&sscop->saved_sigs, &sscop->sigs);
4938 sscop_setdebug(struct sscop *sscop, u_int n)
4944 sscop_getdebug(const struct sscop *sscop)
4946 return (sscop->debug);