1121326Sharti/* 2121326Sharti * Copyright (c) 1996-2003 3121326Sharti * Fraunhofer Institute for Open Communication Systems (FhG Fokus). 4121326Sharti * All rights reserved. 5121326Sharti * 6121326Sharti * Redistribution and use in source and binary forms, with or without 7121326Sharti * modification, are permitted provided that the following conditions 8121326Sharti * are met: 9121326Sharti * 1. Redistributions of source code must retain the above copyright 10121326Sharti * notice, this list of conditions and the following disclaimer. 11121326Sharti * 2. Redistributions in binary form must reproduce the above copyright 12121326Sharti * notice, this list of conditions and the following disclaimer in the 13121326Sharti * documentation and/or other materials provided with the distribution. 14121326Sharti * 15121326Sharti * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16121326Sharti * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17121326Sharti * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18121326Sharti * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19121326Sharti * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20121326Sharti * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21121326Sharti * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22121326Sharti * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23121326Sharti * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24121326Sharti * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25121326Sharti * SUCH DAMAGE. 26121326Sharti * 27121326Sharti * Author: Hartmut Brandt <harti@freebsd.org> 28121326Sharti * 29131826Sharti * $Begemot: libunimsg/netnatm/saal/saal_sscop.c,v 1.11 2004/07/08 08:22:13 brandt Exp $ 30121326Sharti * 31121326Sharti * Core SSCOP code (ITU-T Q.2110) 32121326Sharti */ 33121326Sharti 34121326Sharti#include <netnatm/saal/sscop.h> 35121326Sharti#include <netnatm/saal/sscoppriv.h> 36121326Sharti 37121326Sharti#ifndef FAILURE 38121326Sharti#define FAILURE(S) 39121326Sharti#endif 40121326Sharti 41121326Sharti#define MKSTR(S) #S 42121326Sharti 43121326Shartistatic const char *const sscop_sigs[] = { 44121326Sharti MKSTR(SSCOP_ESTABLISH_request), 45121326Sharti MKSTR(SSCOP_ESTABLISH_indication), 46121326Sharti MKSTR(SSCOP_ESTABLISH_response), 47121326Sharti MKSTR(SSCOP_ESTABLISH_confirm), 48121326Sharti MKSTR(SSCOP_RELEASE_request), 49121326Sharti MKSTR(SSCOP_RELEASE_indication), 50121326Sharti MKSTR(SSCOP_RELEASE_confirm), 51121326Sharti MKSTR(SSCOP_DATA_request), 52121326Sharti MKSTR(SSCOP_DATA_indication), 53121326Sharti MKSTR(SSCOP_UDATA_request), 54121326Sharti MKSTR(SSCOP_UDATA_indication), 55121326Sharti MKSTR(SSCOP_RECOVER_indication), 56121326Sharti MKSTR(SSCOP_RECOVER_response), 57121326Sharti MKSTR(SSCOP_RESYNC_request), 58121326Sharti MKSTR(SSCOP_RESYNC_indication), 59121326Sharti MKSTR(SSCOP_RESYNC_response), 60121326Sharti MKSTR(SSCOP_RESYNC_confirm), 61121326Sharti MKSTR(SSCOP_RETRIEVE_request), 62121326Sharti MKSTR(SSCOP_RETRIEVE_indication), 63121326Sharti MKSTR(SSCOP_RETRIEVE_COMPL_indication), 64121326Sharti}; 65121326Sharti 66121326Shartistatic const char *const sscop_msigs[] = { 67121326Sharti MKSTR(SSCOP_MDATA_request), 68121326Sharti MKSTR(SSCOP_MDATA_indication), 69121326Sharti MKSTR(SSCOP_MERROR_indication), 70121326Sharti}; 71121326Sharti 72121326Shartistatic const char *const states[] = { 73121326Sharti MKSTR(SSCOP_IDLE), 74121326Sharti MKSTR(SSCOP_OUT_PEND), 75121326Sharti MKSTR(SSCOP_IN_PEND), 76121326Sharti MKSTR(SSCOP_OUT_DIS_PEND), 77121326Sharti MKSTR(SSCOP_OUT_RESYNC_PEND), 78121326Sharti MKSTR(SSCOP_IN_RESYNC_PEND), 79121326Sharti MKSTR(SSCOP_OUT_REC_PEND), 80121326Sharti MKSTR(SSCOP_REC_PEND), 81121326Sharti MKSTR(SSCOP_IN_REC_PEND), 82121326Sharti MKSTR(SSCOP_READY), 83121326Sharti}; 84121326Sharti 85121326Sharti#ifdef SSCOP_DEBUG 86121326Shartistatic const char *const events[] = { 87121326Sharti MKSTR(SIG_BGN), 88121326Sharti MKSTR(SIG_BGAK), 89121326Sharti MKSTR(SIG_END), 90121326Sharti MKSTR(SIG_ENDAK), 91121326Sharti MKSTR(SIG_RS), 92121326Sharti MKSTR(SIG_RSAK), 93121326Sharti MKSTR(SIG_BGREJ), 94121326Sharti MKSTR(SIG_SD), 95121326Sharti MKSTR(SIG_ER), 96121326Sharti MKSTR(SIG_POLL), 97121326Sharti MKSTR(SIG_STAT), 98121326Sharti MKSTR(SIG_USTAT), 99121326Sharti MKSTR(SIG_UD), 100121326Sharti MKSTR(SIG_MD), 101121326Sharti MKSTR(SIG_ERAK), 102121326Sharti 103121326Sharti MKSTR(SIG_T_CC), 104121326Sharti MKSTR(SIG_T_POLL), 105121326Sharti MKSTR(SIG_T_KA), 106121326Sharti MKSTR(SIG_T_NR), 107121326Sharti MKSTR(SIG_T_IDLE), 108121326Sharti 109121326Sharti MKSTR(SIG_PDU_Q), 110121326Sharti MKSTR(SIG_USER_DATA), 111121326Sharti MKSTR(SIG_ESTAB_REQ), 112121326Sharti MKSTR(SIG_ESTAB_RESP), 113121326Sharti MKSTR(SIG_RELEASE_REQ), 114121326Sharti MKSTR(SIG_RECOVER), 115121326Sharti MKSTR(SIG_SYNC_REQ), 116121326Sharti MKSTR(SIG_SYNC_RESP), 117121326Sharti MKSTR(SIG_UDATA), 118121326Sharti MKSTR(SIG_MDATA), 119121326Sharti MKSTR(SIG_UPDU_Q), 120121326Sharti MKSTR(SIG_MPDU_Q), 121121326Sharti MKSTR(SIG_RETRIEVE), 122121326Sharti}; 123121326Sharti 124121326Shartistatic const char *const pdus[] = { 125121326Sharti "illegale PDU type 0", /* no PDU type 0 */ 126121326Sharti MKSTR(PDU_BGN), 127121326Sharti MKSTR(PDU_BGAK), 128121326Sharti MKSTR(PDU_END), 129121326Sharti MKSTR(PDU_ENDAK), 130121326Sharti MKSTR(PDU_RS), 131121326Sharti MKSTR(PDU_RSAK), 132121326Sharti MKSTR(PDU_BGREJ), 133121326Sharti MKSTR(PDU_SD), 134121326Sharti MKSTR(PDU_ER), 135121326Sharti MKSTR(PDU_POLL), 136121326Sharti MKSTR(PDU_STAT), 137121326Sharti MKSTR(PDU_USTAT), 138121326Sharti MKSTR(PDU_UD), 139121326Sharti MKSTR(PDU_MD), 140121326Sharti MKSTR(PDU_ERAK), 141121326Sharti}; 142121326Sharti#endif 143121326Sharti 144121326ShartiMEMINIT(); 145121326Sharti 146121326Shartistatic void sscop_signal(struct sscop *, u_int, struct sscop_msg *); 147121326Shartistatic void sscop_save_signal(struct sscop *, u_int, struct sscop_msg *); 148121326Shartistatic void handle_sigs(struct sscop *); 149121326Shartistatic void sscop_set_state(struct sscop *, u_int); 150121326Sharti 151121326Sharti/************************************************************/ 152121326Sharti 153121326Sharti 154121326Sharti/************************************************************/ 155121326Sharti/* 156121326Sharti * Queue macros 157121326Sharti */ 158121326Sharti#define SSCOP_MSG_FREE(MSG) \ 159121326Sharti do { \ 160121326Sharti if(MSG) { \ 161121326Sharti MBUF_FREE((MSG)->m); \ 162121326Sharti MSG_FREE((MSG)); \ 163121326Sharti } \ 164121326Sharti } while(0) 165121326Sharti 166121326Sharti 167121326Sharti#define QFIND(Q,RN) \ 168121326Sharti ({ \ 169121326Sharti struct sscop_msg *_msg = NULL, *_m; \ 170121326Sharti MSGQ_FOREACH(_m, (Q)) { \ 171121326Sharti if(_m->seqno == (RN)) { \ 172121326Sharti _msg = _m; \ 173121326Sharti break; \ 174121326Sharti } \ 175121326Sharti } \ 176121326Sharti _msg; \ 177121326Sharti }) 178121326Sharti 179121326Sharti#define QINSERT(Q,M) \ 180121326Sharti do { \ 181121326Sharti struct sscop_msg *_msg = NULL, *_m; \ 182121326Sharti MSGQ_FOREACH(_m, (Q)) { \ 183121326Sharti if (_m->seqno > (M)->seqno) { \ 184121326Sharti _msg = _m; \ 185121326Sharti break; \ 186121326Sharti } \ 187121326Sharti } \ 188121326Sharti if (_msg != NULL) \ 189121326Sharti MSGQ_INSERT_BEFORE(_msg, (M)); \ 190121326Sharti else \ 191121326Sharti MSGQ_APPEND((Q), (M)); \ 192121326Sharti } while (0) 193121326Sharti 194121326Sharti 195121326Sharti/* 196121326Sharti * Send an error indication to the management plane. 197121326Sharti */ 198121326Sharti#define MAAL_ERROR(S,E,C) \ 199121326Sharti do { \ 200121326Sharti VERBOSE(S, SSCOP_DBG_USIG, ((S), (S)->aarg, \ 201121326Sharti "MAA-Signal %s in state %s", \ 202121326Sharti sscop_msigs[SSCOP_MERROR_indication], states[(S)->state])); \ 203121326Sharti (S)->funcs->send_manage((S), (S)->aarg, \ 204121326Sharti SSCOP_MERROR_indication, NULL, (E), (C)); \ 205121326Sharti } while(0) 206121326Sharti 207121326Sharti#define MAAL_DATA(S,M) \ 208121326Sharti do { \ 209121326Sharti VERBOSE(S, SSCOP_DBG_USIG, ((S), (S)->aarg, \ 210121326Sharti "MAA-Signal %s in state %s", \ 211121326Sharti sscop_msigs[SSCOP_MDATA_indication], states[(S)->state])); \ 212121326Sharti (S)->funcs->send_manage((S), (S)->aarg, \ 213121326Sharti SSCOP_MDATA_indication, (M), 0, 0); \ 214121326Sharti } while(0) 215121326Sharti 216121326Sharti#define AAL_DATA(S,D,M,N) \ 217121326Sharti do { \ 218121326Sharti VERBOSE(S, SSCOP_DBG_USIG, ((S), (S)->aarg, \ 219121326Sharti "AA-Signal %s in state %s", \ 220121326Sharti sscop_sigs[D], states[(S)->state])); \ 221121326Sharti (S)->funcs->send_upper((S), (S)->aarg, (D), (M), (N)); \ 222121326Sharti } while(0) 223121326Sharti 224121326Sharti#define AAL_SIG(S,D) \ 225121326Sharti do { \ 226121326Sharti VERBOSE(S, SSCOP_DBG_USIG, ((S), (S)->aarg, \ 227121326Sharti "AA-Signal %s in state %s", \ 228121326Sharti sscop_sigs[D], states[(S)->state])); \ 229121326Sharti (S)->funcs->send_upper((S), (S)->aarg, (D), NULL, 0); \ 230121326Sharti } while(0) 231121326Sharti 232121326Sharti#ifdef SSCOP_DEBUG 233121326Sharti#define AAL_SEND(S,M) do { \ 234121326Sharti if (ISVERBOSE(S, SSCOP_DBG_PDU)) \ 235121326Sharti sscop_dump_pdu(S, "tx", (M)); \ 236121326Sharti (S)->funcs->send_lower((S), (S)->aarg, (M)); \ 237121326Sharti } while(0) 238121326Sharti#else 239121326Sharti#define AAL_SEND(S,M) (S)->funcs->send_lower((S), (S)->aarg, (M)) 240121326Sharti#endif 241121326Sharti 242121326Sharti 243121326Sharti/* 244121326Sharti * Free a save user-to-user data buffer and set the pointer to zero 245121326Sharti * to signal, that it is free. 246121326Sharti */ 247121326Sharti#define FREE_UU(F) \ 248121326Sharti do { \ 249121326Sharti if(sscop->F) { \ 250121326Sharti MBUF_FREE(sscop->F); \ 251121326Sharti sscop->F = NULL; \ 252121326Sharti } \ 253121326Sharti } while(0) 254121326Sharti 255121326Sharti#define SET_UU(F,U) \ 256121326Sharti do { \ 257121326Sharti FREE_UU(F); \ 258121326Sharti sscop->F = U->m; \ 259121326Sharti U->m = NULL; \ 260121326Sharti SSCOP_MSG_FREE(U); \ 261121326Sharti } while(0) 262121326Sharti 263121326Sharti#define AAL_UU_SIGNAL(S, SIG, M, PL, SN) \ 264121326Sharti do { \ 265121326Sharti if(MBUF_LEN((M)->m) > 0) { \ 266121326Sharti MBUF_UNPAD((M)->m,(PL)); \ 267121326Sharti AAL_DATA((S), (SIG), (M)->m, (SN)); \ 268121326Sharti (M)->m = NULL; \ 269121326Sharti } else { \ 270121326Sharti AAL_DATA((S), (SIG), NULL, (SN)); \ 271121326Sharti } \ 272121326Sharti SSCOP_MSG_FREE((M)); \ 273121326Sharti } while(0) 274121326Sharti 275121326Sharti 276121326Sharti 277121326ShartiTIMER_FUNC(cc, CC) 278121326ShartiTIMER_FUNC(nr, NR) 279121326ShartiTIMER_FUNC(ka, KA) 280121326ShartiTIMER_FUNC(poll, POLL) 281121326ShartiTIMER_FUNC(idle, IDLE) 282121326Sharti 283121326Sharti/************************************************************/ 284121326Sharti/* 285121326Sharti * INSTANCE AND TYPE HANDLING. 286121326Sharti */ 287121326Sharti#ifdef SSCOP_DEBUG 288121326Shartistatic void 289121326Shartisscop_dump_pdu(struct sscop *sscop, const char *dir, 290121326Sharti const struct SSCOP_MBUF_T *m) 291121326Sharti{ 292121326Sharti u_int32_t v1, v2, v3, v4; 293121326Sharti u_int size = MBUF_LEN(m); 294121326Sharti u_int n, i; 295121326Sharti 296121326Sharti if (size < 8) 297121326Sharti return; 298121326Sharti 299121326Sharti v1 = MBUF_TRAIL32(m, -1); 300121326Sharti v2 = MBUF_TRAIL32(m, -2); 301121326Sharti 302121326Sharti switch ((v1 >> 24) & 0xf) { 303121326Sharti 304121326Sharti case 0: 305121326Sharti return; 306121326Sharti 307121326Sharti case PDU_BGN: 308121326Sharti sscop->funcs->verbose(sscop, sscop->aarg, 309121326Sharti "%s BGN n(mr)=%u n(sq)=%u pl=%u", 310121326Sharti dir, v1 & 0xffffff, v2 & 0xff, (v1 >> 30) & 0x3); 311121326Sharti return; 312121326Sharti 313121326Sharti case PDU_BGAK: 314121326Sharti sscop->funcs->verbose(sscop, sscop->aarg, 315121326Sharti "%s BGAK n(mr)=%u pl=%u", 316121326Sharti dir, v1 & 0xffffff, (v1 >> 30) & 0x3); 317121326Sharti return; 318121326Sharti 319121326Sharti case PDU_END: 320121326Sharti sscop->funcs->verbose(sscop, sscop->aarg, 321121326Sharti "%s END r=%u s=%u pl=%u", 322121326Sharti dir, (v1 >> 29) & 1, (v1 >> 28) & 1, (v1 >> 30) & 0x3); 323121326Sharti return; 324121326Sharti 325121326Sharti case PDU_ENDAK: 326121326Sharti sscop->funcs->verbose(sscop, sscop->aarg, "%s ENDAK", dir); 327121326Sharti return; 328121326Sharti 329121326Sharti case PDU_RS: 330121326Sharti sscop->funcs->verbose(sscop, sscop->aarg, 331121326Sharti "%s RS n(mr)=%u n(sq)=%u pl=%u", 332121326Sharti dir, v1 & 0xffffff, v2 & 0xff, (v1 >> 30) & 0x3); 333121326Sharti return; 334121326Sharti 335121326Sharti case PDU_RSAK: 336121326Sharti sscop->funcs->verbose(sscop, sscop->aarg, "%s RSAK n(mr)=%u", 337121326Sharti dir, v1 & 0xffffff); 338121326Sharti return; 339121326Sharti 340121326Sharti case PDU_BGREJ: 341121326Sharti sscop->funcs->verbose(sscop, sscop->aarg, "%s BGREJ pl=%u", 342121326Sharti dir, (v1 >> 30) & 0x3); 343121326Sharti return; 344121326Sharti 345121326Sharti case PDU_SD: 346121326Sharti sscop->funcs->verbose(sscop, sscop->aarg, "%s SD n(s)=%u pl=%u", 347121326Sharti dir, v1 & 0xffffff, (v1 >> 30) & 0x3); 348121326Sharti return; 349121326Sharti 350121326Sharti case PDU_ER: 351121326Sharti sscop->funcs->verbose(sscop, sscop->aarg, "%s ER n(mr)=%u n(sq)=%u", 352121326Sharti dir, v1 & 0xffffff, v2 & 0xff); 353121326Sharti return; 354121326Sharti 355121326Sharti case PDU_POLL: 356121326Sharti sscop->funcs->verbose(sscop, sscop->aarg, "%s POLL n(s)=%u n(ps)=%u", 357121326Sharti dir, v1 & 0xffffff, v2 & 0xffffff); 358121326Sharti return; 359121326Sharti 360121326Sharti case PDU_STAT: 361121326Sharti if (size < 12) 362121326Sharti return; 363121326Sharti v3 = MBUF_TRAIL32(m, -3); 364121326Sharti sscop->funcs->verbose(sscop, sscop->aarg, 365121326Sharti "%s STAT n(r)=%u n(mr)=%u n(ps)=%u", 366121326Sharti dir, v1 & 0xffffff, v2 & 0xffffff, v3 & 0xffffff); 367121326Sharti n = (size - 12) / 4; 368121326Sharti for (i = 0; i < (size - 12) / 4; i++, n--) { 369121326Sharti v4 = MBUF_TRAIL32(m, -4 - (int)i); 370121326Sharti sscop->funcs->verbose(sscop, sscop->aarg, 371121326Sharti " LE(%u)=%u", n, v4 & 0xffffff); 372121326Sharti } 373121326Sharti return; 374121326Sharti 375121326Sharti case PDU_USTAT: 376121326Sharti if (size < 16) 377121326Sharti return; 378121326Sharti sscop->funcs->verbose(sscop, sscop->aarg, 379121326Sharti "%s STAT n(r)=%u n(mr)=%u LE1=%u LE2=%u", 380121326Sharti dir, v1 & 0xffffff, v2 & 0xffffff, 381121326Sharti MBUF_TRAIL32(m, -4) & 0xffffff, 382121326Sharti MBUF_TRAIL32(m, -3) & 0xffffff); 383121326Sharti return; 384121326Sharti 385121326Sharti case PDU_UD: 386121326Sharti sscop->funcs->verbose(sscop, sscop->aarg, 387121326Sharti "%s UD pl=%u", dir, (v1 >> 30) & 0x3); 388121326Sharti return; 389121326Sharti 390121326Sharti case PDU_MD: 391121326Sharti sscop->funcs->verbose(sscop, sscop->aarg, 392121326Sharti "%s MD pl=%u", dir, (v1 >> 30) & 0x3); 393121326Sharti return; 394121326Sharti 395121326Sharti case PDU_ERAK: 396121326Sharti sscop->funcs->verbose(sscop, sscop->aarg, 397121326Sharti "%s ERAK n(mr)=%u", dir, v1 & 0xffffff); 398121326Sharti return; 399121326Sharti } 400121326Sharti} 401121326Sharti#endif 402121326Sharti 403121326Sharti 404121326Sharti/* 405121326Sharti * Initialize state of variables 406121326Sharti */ 407121326Shartistatic void 408121326Shartisscop_init(struct sscop *sscop) 409121326Sharti{ 410121326Sharti sscop->state = SSCOP_IDLE; 411121326Sharti 412121326Sharti sscop->vt_sq = 0; 413121326Sharti sscop->vr_sq = 0; 414121326Sharti sscop->clear_buffers = 1; 415121326Sharti 416121326Sharti sscop->ll_busy = 0; 417121326Sharti 418121326Sharti sscop->rxq = 0; 419121326Sharti} 420121326Sharti 421121326Shartistatic void 422121326Shartisscop_clear(struct sscop *sscop) 423121326Sharti{ 424121326Sharti TIMER_STOP(sscop, cc); 425121326Sharti TIMER_STOP(sscop, ka); 426121326Sharti TIMER_STOP(sscop, nr); 427121326Sharti TIMER_STOP(sscop, idle); 428121326Sharti TIMER_STOP(sscop, poll); 429121326Sharti 430121326Sharti FREE_UU(uu_bgn); 431121326Sharti FREE_UU(uu_bgak); 432121326Sharti FREE_UU(uu_bgrej); 433121326Sharti FREE_UU(uu_end); 434121326Sharti FREE_UU(uu_rs); 435121326Sharti 436121326Sharti MSGQ_CLEAR(&sscop->xq); 437121326Sharti MSGQ_CLEAR(&sscop->uxq); 438121326Sharti MSGQ_CLEAR(&sscop->mxq); 439121326Sharti MSGQ_CLEAR(&sscop->xbuf); 440121326Sharti MSGQ_CLEAR(&sscop->rbuf); 441121326Sharti 442121326Sharti SIGQ_CLEAR(&sscop->sigs); 443121326Sharti SIGQ_CLEAR(&sscop->saved_sigs); 444121326Sharti} 445121326Sharti 446121326Sharti 447121326Sharti/* 448121326Sharti * Allocate instance memory, initialize the state of all variables. 449121326Sharti */ 450121326Shartistruct sscop * 451121326Shartisscop_create(void *a, const struct sscop_funcs *funcs) 452121326Sharti{ 453121326Sharti struct sscop *sscop; 454121326Sharti 455121326Sharti MEMZALLOC(sscop, struct sscop *, sizeof(struct sscop)); 456121326Sharti if (sscop == NULL) 457121326Sharti return (NULL); 458121326Sharti 459121326Sharti if (a == NULL) 460121326Sharti sscop->aarg = sscop; 461121326Sharti else 462121326Sharti sscop->aarg = a; 463121326Sharti sscop->funcs = funcs; 464121326Sharti 465121326Sharti sscop->maxk = MAXK; 466121326Sharti sscop->maxj = MAXJ; 467121326Sharti sscop->maxcc = MAXCC; 468121326Sharti sscop->maxpd = MAXPD; 469121326Sharti sscop->maxstat = MAXSTAT; 470121326Sharti sscop->timercc = TIMERCC; 471121326Sharti sscop->timerka = TIMERKA; 472121326Sharti sscop->timernr = TIMERNR; 473121326Sharti sscop->timerpoll = TIMERPOLL; 474121326Sharti sscop->timeridle = TIMERIDLE; 475121326Sharti sscop->robustness = 0; 476121326Sharti sscop->poll_after_rex = 0; 477121326Sharti sscop->mr = MAXMR; 478121326Sharti 479121326Sharti TIMER_INIT(sscop, cc); 480121326Sharti TIMER_INIT(sscop, nr); 481121326Sharti TIMER_INIT(sscop, ka); 482121326Sharti TIMER_INIT(sscop, poll); 483121326Sharti TIMER_INIT(sscop, idle); 484121326Sharti 485121326Sharti MSGQ_INIT(&sscop->xq); 486121326Sharti MSGQ_INIT(&sscop->uxq); 487121326Sharti MSGQ_INIT(&sscop->mxq); 488121326Sharti MSGQ_INIT(&sscop->rbuf); 489121326Sharti MSGQ_INIT(&sscop->xbuf); 490121326Sharti 491121326Sharti SIGQ_INIT(&sscop->sigs); 492121326Sharti SIGQ_INIT(&sscop->saved_sigs); 493121326Sharti 494121326Sharti sscop_init(sscop); 495121326Sharti 496121326Sharti return (sscop); 497121326Sharti} 498121326Sharti 499121326Sharti/* 500121326Sharti * Free all resources in a sscop instance 501121326Sharti */ 502121326Shartivoid 503121326Shartisscop_destroy(struct sscop *sscop) 504121326Sharti{ 505121326Sharti sscop_reset(sscop); 506121326Sharti 507121326Sharti MEMFREE(sscop); 508121326Sharti} 509121326Sharti 510121326Sharti/* 511121326Sharti * Reset the SSCOP instance. 512121326Sharti */ 513121326Shartivoid 514121326Shartisscop_reset(struct sscop *sscop) 515121326Sharti{ 516121326Sharti sscop_clear(sscop); 517121326Sharti sscop_init(sscop); 518121326Sharti} 519121326Sharti 520121326Shartivoid 521121326Shartisscop_getparam(const struct sscop *sscop, struct sscop_param *p) 522121326Sharti{ 523121326Sharti p->timer_cc = sscop->timercc; 524121326Sharti p->timer_poll = sscop->timerpoll; 525121326Sharti p->timer_keep_alive = sscop->timerka; 526121326Sharti p->timer_no_response = sscop->timernr; 527121326Sharti p->timer_idle = sscop->timeridle; 528121326Sharti p->maxk = sscop->maxk; 529121326Sharti p->maxj = sscop->maxj; 530121326Sharti p->maxcc = sscop->maxcc; 531121326Sharti p->maxpd = sscop->maxpd; 532121326Sharti p->maxstat = sscop->maxstat; 533121326Sharti p->mr = sscop->mr; 534121326Sharti p->flags = 0; 535121326Sharti if(sscop->robustness) 536121326Sharti p->flags |= SSCOP_ROBUST; 537121326Sharti if(sscop->poll_after_rex) 538121326Sharti p->flags |= SSCOP_POLLREX; 539121326Sharti} 540121326Sharti 541121326Shartiint 542121326Shartisscop_setparam(struct sscop *sscop, struct sscop_param *p, u_int *pmask) 543121326Sharti{ 544121326Sharti u_int mask = *pmask; 545121326Sharti 546121326Sharti /* can change only in idle state */ 547121326Sharti if (sscop->state != SSCOP_IDLE) 548121326Sharti return (EISCONN); 549121326Sharti 550121326Sharti *pmask = 0; 551121326Sharti 552121326Sharti /* 553121326Sharti * first check all parameters 554121326Sharti */ 555121326Sharti if ((mask & SSCOP_SET_TCC) && p->timer_cc == 0) 556121326Sharti *pmask |= SSCOP_SET_TCC; 557121326Sharti if ((mask & SSCOP_SET_TPOLL) && p->timer_poll == 0) 558121326Sharti *pmask |= SSCOP_SET_TPOLL; 559121326Sharti if ((mask & SSCOP_SET_TKA) && p->timer_keep_alive == 0) 560121326Sharti *pmask |= SSCOP_SET_TKA; 561121326Sharti if ((mask & SSCOP_SET_TNR) && p->timer_no_response == 0) 562121326Sharti *pmask |= SSCOP_SET_TNR; 563121326Sharti if ((mask & SSCOP_SET_TIDLE) && p->timer_idle == 0) 564121326Sharti *pmask |= SSCOP_SET_TIDLE; 565121326Sharti if ((mask & SSCOP_SET_MAXK) && p->maxk > MAXMAXK) 566121326Sharti *pmask |= SSCOP_SET_MAXK; 567121326Sharti if ((mask & SSCOP_SET_MAXJ) && p->maxj > MAXMAXJ) 568121326Sharti *pmask |= SSCOP_SET_MAXJ; 569121326Sharti if ((mask & SSCOP_SET_MAXCC) && p->maxcc > 255) 570121326Sharti *pmask |= SSCOP_SET_MAXCC; 571121326Sharti if ((mask & SSCOP_SET_MAXPD) && p->maxpd >= (1 << 24)) 572121326Sharti *pmask |= SSCOP_SET_MAXPD; 573121326Sharti if ((mask & SSCOP_SET_MAXSTAT) && 574121326Sharti ((p->maxstat & 1) == 0 || p->maxstat == 1 || p->maxstat == 2 || 575121326Sharti p->maxstat * 4 > MAXMAXK - 8)) 576121326Sharti *pmask |= SSCOP_SET_MAXSTAT; 577121326Sharti if ((mask & SSCOP_SET_MR) && p->mr >= (1 << 24) - 1) 578121326Sharti *pmask |= SSCOP_SET_MR; 579121326Sharti 580121326Sharti if (*pmask) 581121326Sharti return (EINVAL); 582121326Sharti 583121326Sharti 584121326Sharti /* 585121326Sharti * now set it 586121326Sharti */ 587121326Sharti if (mask & SSCOP_SET_TCC) 588121326Sharti sscop->timercc = p->timer_cc; 589121326Sharti 590121326Sharti if (mask & SSCOP_SET_TPOLL) 591121326Sharti sscop->timerpoll = p->timer_poll; 592121326Sharti 593121326Sharti if (mask & SSCOP_SET_TKA) 594121326Sharti sscop->timerka = p->timer_keep_alive; 595121326Sharti 596121326Sharti if (mask & SSCOP_SET_TNR) 597121326Sharti sscop->timernr = p->timer_no_response; 598121326Sharti 599121326Sharti if (mask & SSCOP_SET_TIDLE) 600121326Sharti sscop->timeridle = p->timer_idle; 601121326Sharti 602121326Sharti if (mask & SSCOP_SET_MAXK) 603121326Sharti sscop->maxk = p->maxk; 604121326Sharti if (mask & SSCOP_SET_MAXJ) 605121326Sharti sscop->maxj = p->maxj; 606121326Sharti 607121326Sharti if (mask & SSCOP_SET_MAXCC) 608121326Sharti sscop->maxcc = p->maxcc; 609121326Sharti if (mask & SSCOP_SET_MAXPD) 610121326Sharti sscop->maxpd = p->maxpd; 611121326Sharti if (mask & SSCOP_SET_MAXSTAT) 612121326Sharti sscop->maxstat = p->maxstat; 613121326Sharti 614121326Sharti if (mask & SSCOP_SET_MR) 615121326Sharti sscop->mr = p->mr; 616121326Sharti 617121326Sharti if (mask & SSCOP_SET_ROBUST) 618121326Sharti sscop->robustness = ((p->flags & SSCOP_ROBUST) != 0); 619121326Sharti 620121326Sharti if (mask & SSCOP_SET_POLLREX) 621121326Sharti sscop->poll_after_rex = ((p->flags & SSCOP_POLLREX) != 0); 622121326Sharti 623121326Sharti return (0); 624121326Sharti} 625121326Sharti 626121326Shartienum sscop_state 627121326Shartisscop_getstate(const struct sscop *sscop) 628121326Sharti{ 629121326Sharti return (sscop->state); 630121326Sharti} 631121326Sharti 632121326Sharti 633121326Sharti/************************************************************/ 634121326Sharti/* 635121326Sharti * EXTERNAL INPUT SIGNAL MAPPING 636121326Sharti */ 637121326Sharti 638121326Sharti/* 639121326Sharti * Map AA signal to SSCOP internal signal 640121326Sharti */ 641121326Shartiint 642121326Shartisscop_aasig(struct sscop *sscop, enum sscop_aasig sig, 643121326Sharti struct SSCOP_MBUF_T *m, u_int arg) 644121326Sharti{ 645121326Sharti struct sscop_msg *msg; 646121326Sharti 647121326Sharti if (sig >= sizeof(sscop_sigs)/sizeof(sscop_sigs[0])) { 648121326Sharti VERBOSE(sscop, SSCOP_DBG_INSIG, (sscop, sscop->aarg, 649121326Sharti "AA-Signal %u - bad signal", sig)); 650121326Sharti MBUF_FREE(m); 651121326Sharti return (EINVAL); 652121326Sharti } 653121326Sharti VERBOSE(sscop, SSCOP_DBG_INSIG, (sscop, sscop->aarg, 654121326Sharti "AA-Signal %s in state %s with%s message", 655121326Sharti sscop_sigs[sig], states[sscop->state], m ? "" : "out")); 656121326Sharti 657121326Sharti MSG_ALLOC(msg); 658121326Sharti if (msg == NULL) { 659121326Sharti FAILURE("sscop: cannot allocate aasig"); 660121326Sharti MBUF_FREE(m); 661121326Sharti return (ENOMEM); 662121326Sharti } 663121326Sharti 664121326Sharti switch(sig) { 665121326Sharti 666121326Sharti case SSCOP_ESTABLISH_request: 667121326Sharti msg->m = m; 668121326Sharti msg->rexmit = arg; 669121326Sharti sscop_signal(sscop, SIG_ESTAB_REQ, msg); 670121326Sharti break; 671121326Sharti 672121326Sharti case SSCOP_ESTABLISH_response: 673121326Sharti msg->m = m; 674121326Sharti msg->rexmit = arg; 675121326Sharti sscop_signal(sscop, SIG_ESTAB_RESP, msg); 676121326Sharti break; 677121326Sharti 678121326Sharti case SSCOP_RELEASE_request: 679121326Sharti msg->m = m; 680121326Sharti sscop_signal(sscop, SIG_RELEASE_REQ, msg); 681121326Sharti break; 682121326Sharti 683121326Sharti case SSCOP_DATA_request: 684121326Sharti msg->m = m; 685121326Sharti sscop_signal(sscop, SIG_USER_DATA, msg); 686121326Sharti break; 687121326Sharti 688121326Sharti case SSCOP_UDATA_request: 689121326Sharti msg->m = m; 690121326Sharti sscop_signal(sscop, SIG_UDATA, msg); 691121326Sharti break; 692121326Sharti 693121326Sharti case SSCOP_RECOVER_response: 694121326Sharti MBUF_FREE(m); 695121326Sharti MSG_FREE(msg); 696121326Sharti sscop_signal(sscop, SIG_RECOVER, NULL); 697121326Sharti break; 698121326Sharti 699121326Sharti case SSCOP_RESYNC_request: 700121326Sharti msg->m = m; 701121326Sharti sscop_signal(sscop, SIG_SYNC_REQ, msg); 702121326Sharti break; 703121326Sharti 704121326Sharti case SSCOP_RESYNC_response: 705121326Sharti MBUF_FREE(m); 706121326Sharti MSG_FREE(msg); 707121326Sharti sscop_signal(sscop, SIG_SYNC_RESP, NULL); 708121326Sharti break; 709121326Sharti 710121326Sharti case SSCOP_RETRIEVE_request: 711121326Sharti MBUF_FREE(m); 712121326Sharti msg->rexmit = arg; 713121326Sharti sscop_signal(sscop, SIG_RETRIEVE, msg); 714121326Sharti break; 715121326Sharti 716121326Sharti case SSCOP_ESTABLISH_indication: 717121326Sharti case SSCOP_ESTABLISH_confirm: 718121326Sharti case SSCOP_RELEASE_indication: 719121326Sharti case SSCOP_RELEASE_confirm: 720121326Sharti case SSCOP_DATA_indication: 721121326Sharti case SSCOP_UDATA_indication: 722121326Sharti case SSCOP_RECOVER_indication: 723121326Sharti case SSCOP_RESYNC_indication: 724121326Sharti case SSCOP_RESYNC_confirm: 725121326Sharti case SSCOP_RETRIEVE_indication: 726121326Sharti case SSCOP_RETRIEVE_COMPL_indication: 727121326Sharti MBUF_FREE(m); 728121326Sharti MSG_FREE(msg); 729121326Sharti return EINVAL; 730121326Sharti } 731121326Sharti 732121326Sharti return 0; 733121326Sharti} 734121326Sharti 735121326Sharti/* 736121326Sharti * Signal from layer management. 737121326Sharti */ 738121326Shartiint 739121326Shartisscop_maasig(struct sscop *sscop, enum sscop_maasig sig, struct SSCOP_MBUF_T *m) 740121326Sharti{ 741121326Sharti struct sscop_msg *msg; 742121326Sharti 743121326Sharti if (sig >= sizeof(sscop_msigs)/sizeof(sscop_msigs[0])) { 744121326Sharti VERBOSE(sscop, SSCOP_DBG_INSIG, (sscop, sscop->aarg, 745121326Sharti "MAA-Signal %u - bad signal", sig)); 746121326Sharti MBUF_FREE(m); 747121326Sharti return (EINVAL); 748121326Sharti } 749121326Sharti VERBOSE(sscop, SSCOP_DBG_INSIG, (sscop, sscop->aarg, 750121326Sharti "MAA-Signal %s in state %s with%s message", 751121326Sharti sscop_msigs[sig], states[sscop->state], m ? "" : "out")); 752121326Sharti 753121326Sharti MSG_ALLOC(msg); 754121326Sharti if (msg == NULL) { 755121326Sharti FAILURE("sscop: cannot allocate maasig"); 756121326Sharti MBUF_FREE(m); 757121326Sharti return (ENOMEM); 758121326Sharti } 759121326Sharti 760121326Sharti switch (sig) { 761121326Sharti 762121326Sharti case SSCOP_MDATA_request: 763121326Sharti msg->m = m; 764121326Sharti sscop_signal(sscop, SIG_MDATA, msg); 765121326Sharti break; 766121326Sharti 767121326Sharti case SSCOP_MDATA_indication: 768121326Sharti case SSCOP_MERROR_indication: 769121326Sharti MBUF_FREE(m); 770121326Sharti MSG_FREE(msg); 771121326Sharti return (EINVAL); 772121326Sharti } 773121326Sharti return (0); 774121326Sharti} 775121326Sharti 776121326Sharti/* 777121326Sharti * Map PDU to SSCOP signal. 778121326Sharti */ 779121326Shartivoid 780121326Shartisscop_input(struct sscop *sscop, struct SSCOP_MBUF_T *m) 781121326Sharti{ 782121326Sharti struct sscop_msg *msg; 783121326Sharti union pdu pdu; 784121326Sharti u_int size; 785121326Sharti 786121326Sharti MSG_ALLOC(msg); 787121326Sharti if(msg == NULL) { 788121326Sharti FAILURE("sscop: cannot allocate in pdu msg"); 789121326Sharti MBUF_FREE(m); 790121326Sharti return; 791121326Sharti } 792121326Sharti 793121326Sharti msg->m = m; 794121326Sharti msg->rexmit = 0; 795121326Sharti 796121326Sharti size = MBUF_LEN(m); 797121326Sharti 798121326Sharti if(size % 4 != 0 || size < 4) 799121326Sharti goto err; 800121326Sharti 801121326Sharti pdu.sscop_null = MBUF_TRAIL32(m, -1); 802121326Sharti 803121326Sharti VERBOSE(sscop, SSCOP_DBG_PDU, (sscop, sscop->aarg, 804121326Sharti "got %s, size=%u", pdus[pdu.sscop_type], size)); 805121326Sharti 806121326Sharti#ifdef SSCOP_DEBUG 807121326Sharti#define ENSURE(C,F) if(!(C)) { VERBOSE(sscop, SSCOP_DBG_PDU, F); goto err; } 808121326Sharti#else 809121326Sharti#define ENSURE(C,F) if(!(C)) goto err 810121326Sharti#endif 811121326Sharti 812121326Sharti#ifdef SSCOP_DEBUG 813121326Sharti if (ISVERBOSE(sscop, SSCOP_DBG_PDU)) 814121326Sharti sscop_dump_pdu(sscop, "rx", m); 815121326Sharti#endif 816121326Sharti 817121326Sharti switch(pdu.sscop_type) { 818121326Sharti 819121326Sharti default: 820121326Sharti ENSURE(0, (sscop, sscop->aarg, 821121326Sharti "Bad PDU type %u", pdu.sscop_type)); 822121326Sharti break; 823121326Sharti 824121326Sharti case PDU_BGN: 825121326Sharti ENSURE(size >= 8U, (sscop, sscop->aarg, 826121326Sharti "PDU_BGN size=%u", size)); 827121326Sharti ENSURE(size >= 8U + pdu.sscop_pl, (sscop, sscop->aarg, 828121326Sharti "PDU_BGN size=%u pl=%u", size, pdu.sscop_pl)); 829121326Sharti ENSURE(size <= 8U + sscop->maxj, (sscop, sscop->aarg, 830121326Sharti "PDU_BGN size=%u", size)); 831121326Sharti sscop_signal(sscop, SIG_BGN, msg); 832121326Sharti break; 833121326Sharti 834121326Sharti case PDU_BGAK: 835121326Sharti ENSURE(size >= 8U, (sscop, sscop->aarg, 836121326Sharti "PDU_BGAK size=%u", size)); 837121326Sharti ENSURE(size >= 8U + pdu.sscop_pl, (sscop, sscop->aarg, 838121326Sharti "PDU_BGAK size=%u pl=%u", size, pdu.sscop_pl)); 839121326Sharti ENSURE(size <= 8U + sscop->maxj, (sscop, sscop->aarg, 840121326Sharti "PDU_BGAK size=%u", size)); 841121326Sharti sscop_signal(sscop, SIG_BGAK, msg); 842121326Sharti break; 843121326Sharti 844121326Sharti case PDU_END: 845121326Sharti ENSURE(size >= 8U, (sscop, sscop->aarg, 846121326Sharti "PDU_END size=%u", size)); 847121326Sharti ENSURE(size >= 8U + pdu.sscop_pl, (sscop, sscop->aarg, 848121326Sharti "PDU_END size=%u pl=%u", size, pdu.sscop_pl)); 849121326Sharti ENSURE(size <= 8U + sscop->maxj, (sscop, sscop->aarg, 850121326Sharti "PDU_END size=%u", size)); 851121326Sharti sscop_signal(sscop, SIG_END, msg); 852121326Sharti break; 853121326Sharti 854121326Sharti case PDU_ENDAK: 855121326Sharti ENSURE(size == 8U, (sscop, sscop->aarg, 856121326Sharti "PDU_ENDAK size=%u", size)); 857121326Sharti sscop_signal(sscop, SIG_ENDAK, msg); 858121326Sharti break; 859121326Sharti 860121326Sharti case PDU_BGREJ: 861121326Sharti ENSURE(size >= 8U, (sscop, sscop->aarg, 862121326Sharti "PDU_BGREJ size=%u", size)); 863121326Sharti ENSURE(size >= 8U + pdu.sscop_pl, (sscop, sscop->aarg, 864121326Sharti "PDU_BGREJ size=%u pl=%u", size, pdu.sscop_pl)); 865121326Sharti ENSURE(size <= 8U + sscop->maxj, (sscop, sscop->aarg, 866121326Sharti "PDU_BGREJ size=%u", size)); 867121326Sharti sscop_signal(sscop, SIG_BGREJ, msg); 868121326Sharti break; 869121326Sharti 870121326Sharti case PDU_SD: 871121326Sharti ENSURE(size >= 4U + pdu.sscop_pl, (sscop, sscop->aarg, 872121326Sharti "PDU_SD size=%u pl=%u", size, pdu.sscop_pl)); 873121326Sharti ENSURE(size <= 4U + sscop->maxk, (sscop, sscop->aarg, 874121326Sharti "PDU_SD size=%u", size)); 875121326Sharti sscop_signal(sscop, SIG_SD, msg); 876121326Sharti break; 877121326Sharti 878121326Sharti case PDU_UD: 879121326Sharti ENSURE(size >= 4U + pdu.sscop_pl, (sscop, sscop->aarg, 880121326Sharti "PDU_UD size=%u pl=%u", size, pdu.sscop_pl)); 881121326Sharti ENSURE(size <= 4U + sscop->maxk, (sscop, sscop->aarg, 882121326Sharti "PDU_UD size=%u", size)); 883121326Sharti sscop_signal(sscop, SIG_UD, msg); 884121326Sharti break; 885121326Sharti 886121326Sharti case PDU_MD: 887121326Sharti ENSURE(size >= 4U + pdu.sscop_pl, (sscop, sscop->aarg, 888121326Sharti "PDU_MD size=%u pl=%u", size, pdu.sscop_pl)); 889121326Sharti ENSURE(size <= 4U + sscop->maxk, (sscop, sscop->aarg, 890121326Sharti "PDU_MD size=%u", size)); 891121326Sharti sscop_signal(sscop, SIG_MD, msg); 892121326Sharti break; 893121326Sharti 894121326Sharti case PDU_POLL: 895121326Sharti ENSURE(size == 8U, (sscop, sscop->aarg, 896121326Sharti "PDU_POLL size=%u", size)); 897121326Sharti sscop_signal(sscop, SIG_POLL, msg); 898121326Sharti break; 899121326Sharti 900121326Sharti case PDU_STAT: 901121326Sharti ENSURE(size >= 12U, (sscop, sscop->aarg, 902121326Sharti "PDU_STAT size=%u", size)); 903121326Sharti ENSURE(size <= 12U + 4 * sscop->maxstat, (sscop, sscop->aarg, 904121326Sharti "PDU_STAT size=%u", size)); 905121326Sharti sscop_signal(sscop, SIG_STAT, msg); 906121326Sharti break; 907121326Sharti 908121326Sharti case PDU_RS: 909121326Sharti ENSURE(size >= 8U, (sscop, sscop->aarg, 910121326Sharti "PDU_RS size=%u", size)); 911121326Sharti ENSURE(size >= 8U + pdu.sscop_pl, (sscop, sscop->aarg, 912121326Sharti "PDU_RS size=%u pl=%u", size, pdu.sscop_pl)); 913121326Sharti ENSURE(size <= 8U + sscop->maxj, (sscop, sscop->aarg, 914121326Sharti "PDU_RS size=%u", size)); 915121326Sharti sscop_signal(sscop, SIG_RS, msg); 916121326Sharti break; 917121326Sharti 918121326Sharti case PDU_RSAK: 919121326Sharti ENSURE(size == 8U, (sscop, sscop->aarg, 920121326Sharti "PDU_RSAK size=%u", size)); 921121326Sharti sscop_signal(sscop, SIG_RSAK, msg); 922121326Sharti break; 923121326Sharti 924121326Sharti case PDU_ER: 925121326Sharti ENSURE(size == 8U, (sscop, sscop->aarg, 926121326Sharti "PDU_ER size=%u", size)); 927121326Sharti sscop_signal(sscop, SIG_ER, msg); 928121326Sharti break; 929121326Sharti 930121326Sharti case PDU_ERAK: 931121326Sharti ENSURE(size == 8U, (sscop, sscop->aarg, 932121326Sharti "PDU_ERAK size=%u", size)); 933121326Sharti sscop_signal(sscop, SIG_ERAK, msg); 934121326Sharti break; 935121326Sharti 936121326Sharti case PDU_USTAT: 937121326Sharti ENSURE(size == 16U, (sscop, sscop->aarg, 938121326Sharti "PDU_ERAK size=%u", size)); 939121326Sharti sscop_signal(sscop, SIG_USTAT, msg); 940121326Sharti break; 941121326Sharti } 942121326Sharti#undef ENSURE 943121326Sharti return; 944121326Sharti 945121326Sharti err: 946121326Sharti MAAL_ERROR(sscop, 'U', 0); 947121326Sharti SSCOP_MSG_FREE(msg); 948121326Sharti} 949121326Sharti 950121326Sharti/************************************************************/ 951121326Sharti/* 952121326Sharti * UTILITIES 953121326Sharti */ 954121326Sharti 955121326Sharti/* 956121326Sharti * Move the receiver window by N packets 957121326Sharti */ 958121326Shartiu_int 959121326Shartisscop_window(struct sscop *sscop, u_int n) 960121326Sharti{ 961121326Sharti sscop->vr_mr += n; 962121326Sharti return (SEQNO_DIFF(sscop->vr_mr, sscop->vr_r)); 963121326Sharti} 964121326Sharti 965121326Sharti/* 966121326Sharti * Lower layer busy handling 967121326Sharti */ 968121326Shartiu_int 969121326Shartisscop_setbusy(struct sscop *sscop, int busy) 970121326Sharti{ 971121326Sharti u_int old = sscop->ll_busy; 972121326Sharti 973121326Sharti if (busy > 0) 974121326Sharti sscop->ll_busy = 1; 975121326Sharti else if (busy == 0) { 976121326Sharti sscop->ll_busy = 0; 977121326Sharti if(old) 978121326Sharti handle_sigs(sscop); 979121326Sharti } 980121326Sharti 981121326Sharti return (old); 982121326Sharti} 983121326Sharti 984121326Sharticonst char * 985121326Shartisscop_signame(enum sscop_aasig sig) 986121326Sharti{ 987121326Sharti static char str[40]; 988121326Sharti 989121326Sharti if (sig >= sizeof(sscop_sigs)/sizeof(sscop_sigs[0])) { 990121326Sharti sprintf(str, "BAD SSCOP_AASIG %u", sig); 991121326Sharti return (str); 992121326Sharti } else { 993121326Sharti return (sscop_sigs[sig]); 994121326Sharti } 995121326Sharti} 996121326Sharti 997121326Sharticonst char * 998121326Shartisscop_msigname(enum sscop_maasig sig) 999121326Sharti{ 1000121326Sharti static char str[40]; 1001121326Sharti 1002121326Sharti if (sig >= sizeof(sscop_msigs)/sizeof(sscop_msigs[0])) { 1003121326Sharti sprintf(str, "BAD SSCOP_MAASIG %u", sig); 1004121326Sharti return (str); 1005121326Sharti } else { 1006121326Sharti return (sscop_msigs[sig]); 1007121326Sharti } 1008121326Sharti} 1009121326Sharti 1010121326Sharticonst char * 1011121326Shartisscop_statename(enum sscop_state s) 1012121326Sharti{ 1013121326Sharti static char str[40]; 1014121326Sharti 1015121326Sharti if (s >= sizeof(states)/sizeof(states[0])) { 1016121326Sharti sprintf(str, "BAD SSCOP_STATE %u", s); 1017121326Sharti return (str); 1018121326Sharti } else { 1019121326Sharti return (states[s]); 1020121326Sharti } 1021121326Sharti} 1022121326Sharti 1023121326Sharti 1024121326Sharti/************************************************************/ 1025121326Sharti/* 1026121326Sharti * MACROS 1027121326Sharti */ 1028121326Sharti 1029121326Sharti/* 1030121326Sharti * p 75: release buffers 1031121326Sharti */ 1032121326Shartistatic void 1033121326Shartim_release_buffers(struct sscop *sscop) 1034121326Sharti{ 1035121326Sharti MSGQ_CLEAR(&sscop->xq); 1036121326Sharti MSGQ_CLEAR(&sscop->xbuf); 1037121326Sharti sscop->rxq = 0; 1038121326Sharti MSGQ_CLEAR(&sscop->rbuf); 1039121326Sharti} 1040121326Sharti 1041121326Sharti/* 1042121326Sharti * P 75: Prepare retrival 1043121326Sharti */ 1044121326Shartistatic void 1045121326Shartim_prepare_retrieval(struct sscop *sscop) 1046121326Sharti{ 1047121326Sharti struct sscop_msg *msg; 1048121326Sharti 1049121326Sharti if (sscop->clear_buffers) { 1050121326Sharti MSGQ_CLEAR(&sscop->xq); 1051121326Sharti MSGQ_CLEAR(&sscop->xbuf); 1052121326Sharti } 1053121326Sharti MSGQ_FOREACH(msg, &sscop->xbuf) 1054121326Sharti msg->rexmit = 0; 1055121326Sharti sscop->rxq = 0; 1056121326Sharti 1057121326Sharti MSGQ_CLEAR(&sscop->rbuf); 1058121326Sharti} 1059121326Sharti 1060121326Sharti/* 1061121326Sharti * P 75: Prepare retrival 1062121326Sharti */ 1063121326Shartistatic void 1064121326Shartim_prepare_recovery(struct sscop *sscop) 1065121326Sharti{ 1066121326Sharti struct sscop_msg *msg; 1067121326Sharti 1068121326Sharti if(sscop->clear_buffers) { 1069121326Sharti MSGQ_CLEAR(&sscop->xq); 1070121326Sharti MSGQ_CLEAR(&sscop->xbuf); 1071121326Sharti } 1072121326Sharti MSGQ_FOREACH(msg, &sscop->xbuf) 1073121326Sharti msg->rexmit = 0; 1074121326Sharti sscop->rxq = 0; 1075121326Sharti} 1076121326Sharti 1077121326Sharti 1078121326Sharti/* 1079121326Sharti * P 75: Clear transmitter 1080121326Sharti */ 1081121326Shartistatic void 1082121326Shartim_clear_transmitter(struct sscop *sscop) 1083121326Sharti{ 1084121326Sharti if(!sscop->clear_buffers) { 1085121326Sharti MSGQ_CLEAR(&sscop->xq); 1086121326Sharti MSGQ_CLEAR(&sscop->xbuf); 1087121326Sharti } 1088121326Sharti} 1089121326Sharti 1090121326Sharti 1091121326Sharti/* 1092121326Sharti * p 75: Deliver data 1093121326Sharti * Freeing the message is the responibility of the handler function. 1094121326Sharti */ 1095121326Shartistatic void 1096121326Shartim_deliver_data(struct sscop *sscop) 1097121326Sharti{ 1098121326Sharti struct sscop_msg *msg; 1099121326Sharti u_int sn; 1100121326Sharti 1101121326Sharti if ((msg = MSGQ_GET(&sscop->rbuf)) == NULL) 1102121326Sharti return; 1103121326Sharti 1104121326Sharti if (sscop->clear_buffers) { 1105121326Sharti MSGQ_CLEAR(&sscop->rbuf); 1106121326Sharti return; 1107121326Sharti } 1108121326Sharti 1109121326Sharti sn = msg->seqno + 1; 1110121326Sharti AAL_DATA(sscop, SSCOP_DATA_indication, msg->m, msg->seqno); 1111121326Sharti MSG_FREE(msg); 1112121326Sharti 1113121326Sharti while ((msg = MSGQ_GET(&sscop->rbuf)) != NULL) { 1114121326Sharti ASSERT(msg->seqno == sn); 1115121326Sharti if (++sn == SSCOP_MAXSEQNO) 1116121326Sharti sn = 0; 1117121326Sharti AAL_DATA(sscop, SSCOP_DATA_indication, msg->m, msg->seqno); 1118121326Sharti MSG_FREE(msg); 1119121326Sharti } 1120121326Sharti} 1121121326Sharti 1122121326Sharti/* 1123121326Sharti * P 75: Initialize state variables 1124121326Sharti */ 1125121326Shartistatic void 1126121326Shartim_initialize_state(struct sscop *sscop) 1127121326Sharti{ 1128121326Sharti sscop->vt_s = 0; 1129121326Sharti sscop->vt_ps = 0; 1130121326Sharti sscop->vt_a = 0; 1131121326Sharti 1132121326Sharti sscop->vt_pa = 1; 1133121326Sharti sscop->vt_pd = 0; 1134121326Sharti sscop->credit = 1; 1135121326Sharti 1136121326Sharti sscop->vr_r = 0; 1137121326Sharti sscop->vr_h = 0; 1138121326Sharti} 1139121326Sharti 1140121326Sharti/* 1141121326Sharti * p 76: Data retrieval 1142121326Sharti */ 1143121326Shartistatic void 1144121326Shartim_data_retrieval(struct sscop *sscop, u_int rn) 1145121326Sharti{ 1146121326Sharti struct sscop_msg *s; 1147121326Sharti 1148121326Sharti if (rn != SSCOP_RETRIEVE_UNKNOWN) { 1149121326Sharti if(rn >= SSCOP_RETRIEVE_TOTAL) 1150121326Sharti rn = sscop->vt_a; 1151121326Sharti else 1152121326Sharti rn++; 1153121326Sharti while(rn >= sscop->vt_a && rn < sscop->vt_s) { 1154121326Sharti if(rn == SSCOP_MAXSEQNO) rn = 0; 1155121326Sharti if((s = QFIND(&sscop->xbuf, rn)) != NULL) { 1156121326Sharti MSGQ_REMOVE(&sscop->xbuf, s); 1157121326Sharti AAL_DATA(sscop, SSCOP_RETRIEVE_indication, 1158121326Sharti s->m, 0); 1159121326Sharti MSG_FREE(s); 1160121326Sharti } 1161121326Sharti rn++; 1162121326Sharti } 1163121326Sharti } 1164121326Sharti 1165121326Sharti while((s = MSGQ_GET(&sscop->xq)) != NULL) { 1166121326Sharti AAL_DATA(sscop, SSCOP_RETRIEVE_indication, s->m, 0); 1167121326Sharti MSG_FREE(s); 1168121326Sharti } 1169121326Sharti AAL_SIG(sscop, SSCOP_RETRIEVE_COMPL_indication); 1170121326Sharti} 1171121326Sharti 1172121326Sharti/* 1173121326Sharti * P 76: Detect retransmission. PDU type must already be stripped. 1174121326Sharti */ 1175121326Shartistatic int 1176121326Shartim_detect_retransmission(struct sscop *sscop, struct sscop_msg *msg) 1177121326Sharti{ 1178121326Sharti union bgn bgn; 1179121326Sharti 1180121326Sharti bgn.sscop_null = MBUF_TRAIL32(msg->m, -1); 1181121326Sharti 1182121326Sharti if (sscop->vr_sq == bgn.sscop_bgns) 1183121326Sharti return (1); 1184121326Sharti 1185121326Sharti sscop->vr_sq = bgn.sscop_bgns; 1186121326Sharti return (0); 1187121326Sharti} 1188121326Sharti 1189121326Sharti/* 1190121326Sharti * P 76: Set POLL timer 1191121326Sharti */ 1192121326Shartistatic void 1193121326Shartim_set_poll_timer(struct sscop *sscop) 1194121326Sharti{ 1195121326Sharti if(MSGQ_EMPTY(&sscop->xq) && sscop->vt_s == sscop->vt_a) 1196121326Sharti TIMER_RESTART(sscop, ka); 1197121326Sharti else 1198121326Sharti TIMER_RESTART(sscop, poll); 1199121326Sharti} 1200121326Sharti 1201121326Sharti/* 1202121326Sharti * P 77: Reset data transfer timers 1203121326Sharti */ 1204121326Shartistatic void 1205121326Shartim_reset_data_xfer_timers(struct sscop *sscop) 1206121326Sharti{ 1207121326Sharti TIMER_STOP(sscop, ka); 1208121326Sharti TIMER_STOP(sscop, nr); 1209121326Sharti TIMER_STOP(sscop, idle); 1210121326Sharti TIMER_STOP(sscop, poll); 1211121326Sharti} 1212121326Sharti 1213121326Sharti/* 1214121326Sharti * P 77: Set data transfer timers 1215121326Sharti */ 1216121326Shartistatic void 1217121326Shartim_set_data_xfer_timers(struct sscop *sscop) 1218121326Sharti{ 1219121326Sharti TIMER_RESTART(sscop, poll); 1220121326Sharti TIMER_RESTART(sscop, nr); 1221121326Sharti} 1222121326Sharti 1223121326Sharti/* 1224121326Sharti * P 77: Initialize VR(MR) 1225121326Sharti */ 1226121326Shartistatic void 1227121326Shartim_initialize_mr(struct sscop *sscop) 1228121326Sharti{ 1229121326Sharti sscop->vr_mr = sscop->mr; 1230121326Sharti} 1231121326Sharti 1232121326Sharti/************************************************************/ 1233121326Sharti/* 1234121326Sharti * CONDITIONS 1235121326Sharti */ 1236121326Shartistatic int 1237121326Shartic_ready_pduq(struct sscop *sscop) 1238121326Sharti{ 1239121326Sharti if (!sscop->ll_busy && 1240121326Sharti (sscop->rxq != 0 || 1241121326Sharti sscop->vt_s < sscop->vt_ms || 1242121326Sharti TIMER_ISACT(sscop, idle))) 1243121326Sharti return (1); 1244121326Sharti return (0); 1245121326Sharti} 1246121326Sharti 1247121326Sharti/************************************************************/ 1248121326Sharti/* 1249121326Sharti * SEND PDUS 1250121326Sharti */ 1251121326Sharti 1252121326Sharti/* 1253121326Sharti * Send BG PDU. 1254121326Sharti */ 1255121326Shartistatic void 1256121326Shartisend_bgn(struct sscop *sscop, struct SSCOP_MBUF_T *uu) 1257121326Sharti{ 1258121326Sharti union pdu pdu; 1259121326Sharti union bgn bgn; 1260121326Sharti struct SSCOP_MBUF_T *m; 1261121326Sharti 1262121326Sharti pdu.sscop_null = 0; 1263121326Sharti pdu.sscop_type = PDU_BGN; 1264121326Sharti pdu.sscop_ns = sscop->vr_mr; 1265121326Sharti 1266121326Sharti bgn.sscop_null = 0; 1267121326Sharti bgn.sscop_bgns = sscop->vt_sq; 1268121326Sharti 1269121326Sharti if(uu) { 1270121326Sharti if ((m = MBUF_DUP(uu)) == NULL) { 1271121326Sharti FAILURE("sscop: cannot allocate BGN"); 1272121326Sharti return; 1273121326Sharti } 1274121326Sharti pdu.sscop_pl += MBUF_PAD4(m); 1275121326Sharti } else { 1276121326Sharti if ((m = MBUF_ALLOC(8)) == NULL) { 1277121326Sharti FAILURE("sscop: cannot allocate BGN"); 1278121326Sharti return; 1279121326Sharti } 1280121326Sharti } 1281121326Sharti 1282121326Sharti MBUF_APPEND32(m, bgn.sscop_null); 1283121326Sharti MBUF_APPEND32(m, pdu.sscop_null); 1284121326Sharti 1285121326Sharti AAL_SEND(sscop, m); 1286121326Sharti} 1287121326Sharti 1288121326Sharti/* 1289121326Sharti * Send BGREJ PDU. 1290121326Sharti */ 1291121326Shartistatic void 1292121326Shartisend_bgrej(struct sscop *sscop, struct SSCOP_MBUF_T *uu) 1293121326Sharti{ 1294121326Sharti union pdu pdu; 1295121326Sharti union bgn bgn; 1296121326Sharti struct SSCOP_MBUF_T *m; 1297121326Sharti 1298121326Sharti pdu.sscop_null = 0; 1299121326Sharti pdu.sscop_type = PDU_BGREJ; 1300121326Sharti bgn.sscop_null = 0; 1301121326Sharti 1302121326Sharti if(uu) { 1303121326Sharti if((m = MBUF_DUP(uu)) == NULL) { 1304121326Sharti FAILURE("sscop: cannot allocate BGREJ"); 1305121326Sharti return; 1306121326Sharti } 1307121326Sharti pdu.sscop_pl += MBUF_PAD4(m); 1308121326Sharti } else { 1309121326Sharti if((m = MBUF_ALLOC(8)) == NULL) { 1310121326Sharti FAILURE("sscop: cannot allocate BGREJ"); 1311121326Sharti return; 1312121326Sharti } 1313121326Sharti } 1314121326Sharti 1315121326Sharti MBUF_APPEND32(m, bgn.sscop_null); 1316121326Sharti MBUF_APPEND32(m, pdu.sscop_null); 1317121326Sharti 1318121326Sharti AAL_SEND(sscop, m); 1319121326Sharti} 1320121326Sharti 1321121326Sharti/* 1322121326Sharti * Send BGAK PDU. 1323121326Sharti */ 1324121326Shartistatic void 1325121326Shartisend_bgak(struct sscop *sscop, struct SSCOP_MBUF_T *uu) 1326121326Sharti{ 1327121326Sharti union pdu pdu; 1328121326Sharti union bgn bgn; 1329121326Sharti struct SSCOP_MBUF_T *m; 1330121326Sharti 1331121326Sharti pdu.sscop_null = 0; 1332121326Sharti pdu.sscop_type = PDU_BGAK; 1333121326Sharti pdu.sscop_ns = sscop->vr_mr; 1334121326Sharti bgn.sscop_null = 0; 1335121326Sharti 1336121326Sharti if(uu) { 1337121326Sharti if((m = MBUF_DUP(uu)) == NULL) { 1338121326Sharti FAILURE("sscop: cannot allocate BGAK"); 1339121326Sharti return; 1340121326Sharti } 1341121326Sharti pdu.sscop_pl += MBUF_PAD4(m); 1342121326Sharti } else { 1343121326Sharti if((m = MBUF_ALLOC(8)) == NULL) { 1344121326Sharti FAILURE("sscop: cannot allocate BGAK"); 1345121326Sharti return; 1346121326Sharti } 1347121326Sharti } 1348121326Sharti 1349121326Sharti MBUF_APPEND32(m, bgn.sscop_null); 1350121326Sharti MBUF_APPEND32(m, pdu.sscop_null); 1351121326Sharti 1352121326Sharti AAL_SEND(sscop, m); 1353121326Sharti} 1354121326Sharti 1355121326Sharti/* 1356121326Sharti * Send SD PDU. The function makes a duplicate of the message. 1357121326Sharti */ 1358121326Shartistatic void 1359121326Shartisend_sd(struct sscop *sscop, struct SSCOP_MBUF_T *m, u_int seqno) 1360121326Sharti{ 1361121326Sharti union pdu pdu; 1362121326Sharti 1363121326Sharti if((m = MBUF_DUP(m)) == NULL) { 1364121326Sharti FAILURE("sscop: cannot allocate SD"); 1365121326Sharti return; 1366121326Sharti } 1367121326Sharti 1368121326Sharti pdu.sscop_null = 0; 1369121326Sharti pdu.sscop_pl = 0; 1370121326Sharti pdu.sscop_type = PDU_SD; 1371121326Sharti pdu.sscop_ns = seqno; 1372121326Sharti 1373121326Sharti pdu.sscop_pl += MBUF_PAD4(m); 1374121326Sharti 1375121326Sharti MBUF_APPEND32(m, pdu.sscop_null); 1376121326Sharti 1377121326Sharti AAL_SEND(sscop, m); 1378121326Sharti} 1379121326Sharti 1380121326Sharti/* 1381121326Sharti * Send a UD PDU. The caller must free the sscop msg part. 1382121326Sharti */ 1383121326Shartistatic void 1384121326Shartisend_ud(struct sscop *sscop, struct SSCOP_MBUF_T *m) 1385121326Sharti{ 1386121326Sharti union pdu pdu; 1387121326Sharti 1388121326Sharti pdu.sscop_null = 0; 1389121326Sharti pdu.sscop_type = PDU_UD; 1390121326Sharti 1391121326Sharti pdu.sscop_pl += MBUF_PAD4(m); 1392121326Sharti 1393121326Sharti MBUF_APPEND32(m, pdu.sscop_null); 1394121326Sharti 1395121326Sharti AAL_SEND(sscop, m); 1396121326Sharti} 1397121326Sharti 1398121326Sharti/* 1399121326Sharti * Send a MD PDU. The caller must free the sscop msg part. 1400121326Sharti */ 1401121326Shartistatic void 1402121326Shartisend_md(struct sscop *sscop, struct SSCOP_MBUF_T *m) 1403121326Sharti{ 1404121326Sharti union pdu pdu; 1405121326Sharti 1406121326Sharti pdu.sscop_null = 0; 1407121326Sharti pdu.sscop_type = PDU_MD; 1408121326Sharti 1409121326Sharti pdu.sscop_pl += MBUF_PAD4(m); 1410121326Sharti 1411121326Sharti MBUF_APPEND32(m, pdu.sscop_null); 1412121326Sharti 1413121326Sharti AAL_SEND(sscop, m); 1414121326Sharti} 1415121326Sharti 1416121326Sharti/* 1417121326Sharti * Send END PDU. 1418121326Sharti */ 1419121326Shartistatic void 1420121326Shartisend_end(struct sscop *sscop, int src, struct SSCOP_MBUF_T *uu) 1421121326Sharti{ 1422121326Sharti union pdu pdu; 1423121326Sharti struct SSCOP_MBUF_T *m; 1424121326Sharti 1425121326Sharti sscop->last_end_src = src; 1426121326Sharti 1427121326Sharti pdu.sscop_null = 0; 1428121326Sharti pdu.sscop_s = src; 1429121326Sharti pdu.sscop_type = PDU_END; 1430121326Sharti 1431121326Sharti if(uu) { 1432121326Sharti if((m = MBUF_DUP(uu)) == NULL) { 1433121326Sharti FAILURE("sscop: cannot allocate END"); 1434121326Sharti return; 1435121326Sharti } 1436121326Sharti pdu.sscop_pl += MBUF_PAD4(m); 1437121326Sharti } else { 1438121326Sharti if((m = MBUF_ALLOC(8)) == NULL) { 1439121326Sharti FAILURE("sscop: cannot allocate END"); 1440121326Sharti return; 1441121326Sharti } 1442121326Sharti } 1443121326Sharti 1444121326Sharti MBUF_APPEND32(m, 0); 1445121326Sharti MBUF_APPEND32(m, pdu.sscop_null); 1446121326Sharti 1447121326Sharti AAL_SEND(sscop, m); 1448121326Sharti} 1449121326Sharti 1450121326Sharti/* 1451121326Sharti * Send USTAT PDU. List must be terminated by -1. 1452121326Sharti */ 1453121326Shartistatic void 1454121326Shartisend_ustat(struct sscop *sscop, ...) 1455121326Sharti{ 1456121326Sharti va_list ap; 1457121326Sharti int f; 1458121326Sharti u_int n; 1459121326Sharti union pdu pdu; 1460121326Sharti union seqno seqno; 1461121326Sharti struct SSCOP_MBUF_T *m; 1462121326Sharti 1463121326Sharti va_start(ap, sscop); 1464121326Sharti n = 0; 1465121326Sharti while((f = va_arg(ap, int)) >= 0) 1466121326Sharti n++; 1467121326Sharti va_end(ap); 1468121326Sharti 1469121326Sharti if((m = MBUF_ALLOC(n * 4 + 8)) == NULL) { 1470121326Sharti FAILURE("sscop: cannot allocate USTAT"); 1471121326Sharti return; 1472121326Sharti } 1473121326Sharti 1474121326Sharti va_start(ap, sscop); 1475121326Sharti while((f = va_arg(ap, int)) >= 0) { 1476121326Sharti seqno.sscop_null = 0; 1477121326Sharti seqno.sscop_n = f; 1478121326Sharti MBUF_APPEND32(m, seqno.sscop_null); 1479121326Sharti } 1480121326Sharti va_end(ap); 1481121326Sharti 1482121326Sharti seqno.sscop_null = 0; 1483121326Sharti seqno.sscop_n = sscop->vr_mr; 1484121326Sharti MBUF_APPEND32(m, seqno.sscop_null); 1485121326Sharti 1486121326Sharti pdu.sscop_null = 0; 1487121326Sharti pdu.sscop_type = PDU_USTAT; 1488121326Sharti pdu.sscop_ns = sscop->vr_r; 1489121326Sharti MBUF_APPEND32(m, pdu.sscop_null); 1490121326Sharti 1491121326Sharti AAL_SEND(sscop, m); 1492121326Sharti} 1493121326Sharti 1494121326Sharti/* 1495121326Sharti * Send ER PDU. 1496121326Sharti */ 1497121326Shartistatic void 1498121326Shartisend_er(struct sscop *sscop) 1499121326Sharti{ 1500121326Sharti union pdu pdu; 1501121326Sharti union bgn bgn; 1502121326Sharti struct SSCOP_MBUF_T *m; 1503121326Sharti 1504121326Sharti pdu.sscop_null = 0; 1505121326Sharti pdu.sscop_type = PDU_ER; 1506121326Sharti pdu.sscop_ns = sscop->vr_mr; 1507121326Sharti 1508121326Sharti bgn.sscop_null = 0; 1509121326Sharti bgn.sscop_bgns = sscop->vt_sq; 1510121326Sharti 1511121326Sharti if((m = MBUF_ALLOC(8)) == NULL) { 1512121326Sharti FAILURE("sscop: cannot allocate ER"); 1513121326Sharti return; 1514121326Sharti } 1515121326Sharti MBUF_APPEND32(m, bgn.sscop_null); 1516121326Sharti MBUF_APPEND32(m, pdu.sscop_null); 1517121326Sharti 1518121326Sharti AAL_SEND(sscop, m); 1519121326Sharti} 1520121326Sharti 1521121326Sharti/* 1522121326Sharti * Send POLL PDU. 1523121326Sharti */ 1524121326Shartistatic void 1525121326Shartisend_poll(struct sscop *sscop) 1526121326Sharti{ 1527121326Sharti union pdu pdu; 1528121326Sharti union seqno seqno; 1529121326Sharti struct SSCOP_MBUF_T *m; 1530121326Sharti 1531121326Sharti seqno.sscop_null = 0; 1532121326Sharti seqno.sscop_n = sscop->vt_ps; 1533121326Sharti 1534121326Sharti pdu.sscop_null = 0; 1535121326Sharti pdu.sscop_ns = sscop->vt_s; 1536121326Sharti pdu.sscop_type = PDU_POLL; 1537121326Sharti 1538121326Sharti if((m = MBUF_ALLOC(8)) == NULL) { 1539121326Sharti FAILURE("sscop: cannot allocate POLL"); 1540121326Sharti return; 1541121326Sharti } 1542121326Sharti MBUF_APPEND32(m, seqno.sscop_null); 1543121326Sharti MBUF_APPEND32(m, pdu.sscop_null); 1544121326Sharti 1545121326Sharti AAL_SEND(sscop, m); 1546121326Sharti} 1547121326Sharti 1548121326Sharti/* 1549121326Sharti * Send STAT PDU. List is already in buffer. 1550121326Sharti */ 1551121326Shartistatic void 1552121326Shartisend_stat(struct sscop *sscop, u_int nps, struct SSCOP_MBUF_T *m) 1553121326Sharti{ 1554121326Sharti union pdu pdu; 1555121326Sharti union seqno seqno; 1556121326Sharti 1557121326Sharti seqno.sscop_null = 0; 1558121326Sharti seqno.sscop_n = nps; 1559121326Sharti MBUF_APPEND32(m, seqno.sscop_null); 1560121326Sharti 1561121326Sharti seqno.sscop_null = 0; 1562121326Sharti seqno.sscop_n = sscop->vr_mr; 1563121326Sharti MBUF_APPEND32(m, seqno.sscop_null); 1564121326Sharti 1565121326Sharti pdu.sscop_null = 0; 1566121326Sharti pdu.sscop_type = PDU_STAT; 1567121326Sharti pdu.sscop_ns = sscop->vr_r; 1568121326Sharti MBUF_APPEND32(m, pdu.sscop_null); 1569121326Sharti 1570121326Sharti AAL_SEND(sscop, m); 1571121326Sharti} 1572121326Sharti 1573121326Sharti/* 1574121326Sharti * Send ENDAK PDU. 1575121326Sharti */ 1576121326Shartistatic void 1577121326Shartisend_endak(struct sscop *sscop) 1578121326Sharti{ 1579121326Sharti union pdu pdu; 1580121326Sharti union seqno seqno; 1581121326Sharti struct SSCOP_MBUF_T *m; 1582121326Sharti 1583121326Sharti seqno.sscop_null = 0; 1584121326Sharti pdu.sscop_null = 0; 1585121326Sharti pdu.sscop_type = PDU_ENDAK; 1586121326Sharti 1587121326Sharti if((m = MBUF_ALLOC(8)) == NULL) { 1588121326Sharti FAILURE("sscop: cannot allocate ENDAK"); 1589121326Sharti return; 1590121326Sharti } 1591121326Sharti MBUF_APPEND32(m, seqno.sscop_null); 1592121326Sharti MBUF_APPEND32(m, pdu.sscop_null); 1593121326Sharti 1594121326Sharti AAL_SEND(sscop, m); 1595121326Sharti} 1596121326Sharti 1597121326Sharti/* 1598121326Sharti * Send ERAK PDU. 1599121326Sharti */ 1600121326Shartistatic void 1601121326Shartisend_erak(struct sscop *sscop) 1602121326Sharti{ 1603121326Sharti union pdu pdu; 1604121326Sharti union seqno seqno; 1605121326Sharti struct SSCOP_MBUF_T *m; 1606121326Sharti 1607121326Sharti seqno.sscop_null = 0; 1608121326Sharti pdu.sscop_null = 0; 1609121326Sharti pdu.sscop_type = PDU_ERAK; 1610121326Sharti pdu.sscop_ns = sscop->vr_mr; 1611121326Sharti 1612121326Sharti if((m = MBUF_ALLOC(8)) == NULL) { 1613121326Sharti FAILURE("sscop: cannot allocate ERAK"); 1614121326Sharti return; 1615121326Sharti } 1616121326Sharti MBUF_APPEND32(m, seqno.sscop_null); 1617121326Sharti MBUF_APPEND32(m, pdu.sscop_null); 1618121326Sharti 1619121326Sharti AAL_SEND(sscop, m); 1620121326Sharti} 1621121326Sharti 1622121326Sharti/* 1623121326Sharti * Send RS PDU 1624121326Sharti */ 1625121326Shartistatic void 1626121326Shartisend_rs(struct sscop *sscop, int resend, struct SSCOP_MBUF_T *uu) 1627121326Sharti{ 1628121326Sharti union pdu pdu; 1629121326Sharti union bgn bgn; 1630121326Sharti struct SSCOP_MBUF_T *m; 1631121326Sharti 1632121326Sharti pdu.sscop_null = 0; 1633121326Sharti pdu.sscop_type = PDU_RS; 1634121326Sharti pdu.sscop_ns = resend ? sscop->rs_mr : sscop->vr_mr; 1635121326Sharti 1636121326Sharti bgn.sscop_null = 0; 1637121326Sharti bgn.sscop_bgns = resend ? sscop->rs_sq : sscop->vt_sq; 1638121326Sharti 1639121326Sharti sscop->rs_mr = pdu.sscop_ns; 1640121326Sharti sscop->rs_sq = bgn.sscop_bgns; 1641121326Sharti 1642121326Sharti if(uu) { 1643121326Sharti if((m = MBUF_DUP(uu)) == NULL) { 1644121326Sharti FAILURE("sscop: cannot allocate RS"); 1645121326Sharti return; 1646121326Sharti } 1647121326Sharti pdu.sscop_pl += MBUF_PAD4(m); 1648121326Sharti } else { 1649121326Sharti if((m = MBUF_ALLOC(8)) == NULL) { 1650121326Sharti FAILURE("sscop: cannot allocate RS"); 1651121326Sharti return; 1652121326Sharti } 1653121326Sharti } 1654121326Sharti 1655121326Sharti MBUF_APPEND32(m, bgn.sscop_null); 1656121326Sharti MBUF_APPEND32(m, pdu.sscop_null); 1657121326Sharti 1658121326Sharti AAL_SEND(sscop, m); 1659121326Sharti} 1660121326Sharti 1661121326Sharti/* 1662121326Sharti * Send RSAK pdu 1663121326Sharti */ 1664121326Shartistatic void 1665121326Shartisend_rsak(struct sscop *sscop) 1666121326Sharti{ 1667121326Sharti union pdu pdu; 1668121326Sharti union seqno seqno; 1669121326Sharti struct SSCOP_MBUF_T *m; 1670121326Sharti 1671121326Sharti seqno.sscop_null = 0; 1672121326Sharti pdu.sscop_null = 0; 1673121326Sharti pdu.sscop_type = PDU_RSAK; 1674121326Sharti pdu.sscop_ns = sscop->vr_mr; 1675121326Sharti 1676121326Sharti if((m = MBUF_ALLOC(8)) == NULL) { 1677121326Sharti FAILURE("sscop: cannot allocate RSAK"); 1678121326Sharti return; 1679121326Sharti } 1680121326Sharti 1681121326Sharti MBUF_APPEND32(m, seqno.sscop_null); 1682121326Sharti MBUF_APPEND32(m, pdu.sscop_null); 1683121326Sharti 1684121326Sharti AAL_SEND(sscop, m); 1685121326Sharti} 1686121326Sharti 1687121326Sharti/************************************************************/ 1688121326Sharti/* 1689121326Sharti * P 31; IDLE && AA-ESTABLISH-request 1690121326Sharti * arg is UU data (opt). 1691121326Sharti */ 1692121326Shartistatic void 1693121326Shartisscop_idle_establish_req(struct sscop *sscop, struct sscop_msg *uu) 1694121326Sharti{ 1695121326Sharti u_int br = uu->rexmit; 1696121326Sharti 1697121326Sharti SET_UU(uu_bgn, uu); 1698121326Sharti 1699121326Sharti m_clear_transmitter(sscop); 1700121326Sharti 1701121326Sharti sscop->clear_buffers = br; 1702121326Sharti 1703121326Sharti sscop->vt_cc = 1; 1704121326Sharti sscop->vt_sq++; 1705121326Sharti 1706121326Sharti m_initialize_mr(sscop); 1707121326Sharti 1708121326Sharti send_bgn(sscop, sscop->uu_bgn); 1709121326Sharti 1710121326Sharti TIMER_RESTART(sscop, cc); 1711121326Sharti 1712121326Sharti sscop_set_state(sscop, SSCOP_OUT_PEND); 1713121326Sharti} 1714121326Sharti 1715121326Sharti/* 1716121326Sharti * P 31: IDLE && BGN PDU 1717121326Sharti * arg is the received PDU (freed). 1718121326Sharti */ 1719121326Shartistatic void 1720121326Shartisscop_idle_bgn(struct sscop *sscop, struct sscop_msg *msg) 1721121326Sharti{ 1722121326Sharti union pdu pdu; 1723121326Sharti union bgn bgn; 1724121326Sharti 1725121326Sharti pdu.sscop_null = MBUF_STRIP32(msg->m); 1726121326Sharti 1727121326Sharti if(sscop->robustness) { 1728121326Sharti bgn.sscop_null = MBUF_STRIP32(msg->m); 1729121326Sharti sscop->vr_sq = bgn.sscop_bgns; 1730121326Sharti } else { 1731121326Sharti if(m_detect_retransmission(sscop, msg)) { 1732121326Sharti send_bgrej(sscop, sscop->uu_bgrej); 1733121326Sharti SSCOP_MSG_FREE(msg); 1734121326Sharti return; 1735121326Sharti } 1736121326Sharti (void)MBUF_STRIP32(msg->m); 1737121326Sharti } 1738121326Sharti 1739121326Sharti sscop->vt_ms = pdu.sscop_ns; 1740121326Sharti sscop_set_state(sscop, SSCOP_IN_PEND); 1741121326Sharti 1742121326Sharti AAL_UU_SIGNAL(sscop, SSCOP_ESTABLISH_indication, msg, pdu.sscop_pl, 0); 1743121326Sharti} 1744121326Sharti 1745121326Sharti/* 1746121326Sharti * p 31: IDLE && ENDAK PDU 1747121326Sharti * p 34: OUT_PEND && ENDAK PDU 1748121326Sharti * p 34: OUT_PEND && SD PDU 1749121326Sharti * p 34: OUT_PEND && ERAK PDU 1750121326Sharti * p 34: OUT_PEND && END PDU 1751121326Sharti * p 34: OUT_PEND && STAT PDU 1752121326Sharti * p 34: OUT_PEND && USTAT PDU 1753121326Sharti * p 34: OUT_PEND && POLL PDU 1754121326Sharti * p 36: OUT_PEND && RS PDU 1755121326Sharti * p 36: OUT_PEND && RSAK PDU 1756121326Sharti * p 40: OUTGOING_DISCONNECT_PENDING && SD PDU 1757121326Sharti * p 40: OUTGOING_DISCONNECT_PENDING && BGAK PDU 1758121326Sharti * p 40: OUTGOING_DISCONNECT_PENDING && POLL PDU 1759121326Sharti * p 40: OUTGOING_DISCONNECT_PENDING && STAT PDU 1760121326Sharti * p 40: OUTGOING_DISCONNECT_PENDING && USTAT PDU 1761121326Sharti * p 41: OUTGOING_DISCONNECT_PENDING && ERAK PDU 1762121326Sharti * p 42: OUTGOING_DISCONNECT_PENDING && ER PDU 1763121326Sharti * p 42: OUTGOING_DISCONNECT_PENDING && RS PDU 1764121326Sharti * p 42: OUTGOING_DISCONNECT_PENDING && RSAK PDU 1765121326Sharti * p 43: OUTGOING_RESYNC && ER PDU 1766121326Sharti * p 43: OUTGOING_RESYNC && POLL PDU 1767121326Sharti * p 44: OUTGOING_RESYNC && STAT PDU 1768121326Sharti * p 44: OUTGOING_RESYNC && USTAT PDU 1769121326Sharti * p 45: OUTGOING_RESYNC && BGAK PDU 1770121326Sharti * p 45: OUTGOING_RESYNC && SD PDU 1771121326Sharti * p 45: OUTGOING_RESYNC && ERAK PDU 1772121326Sharti * P 60: READY && BGAK PDU 1773121326Sharti * P 60: READY && ERAK PDU 1774121326Sharti * arg is pdu (freed). 1775121326Sharti */ 1776121326Shartistatic void 1777121326Shartisscop_ignore_pdu(struct sscop *sscop __unused, struct sscop_msg *msg) 1778121326Sharti{ 1779121326Sharti SSCOP_MSG_FREE(msg); 1780121326Sharti} 1781121326Sharti 1782121326Sharti/* 1783121326Sharti * p 31: IDLE && END PDU 1784121326Sharti * arg is pdu (freed). 1785121326Sharti */ 1786121326Shartistatic void 1787121326Shartisscop_idle_end(struct sscop *sscop, struct sscop_msg *msg) 1788121326Sharti{ 1789121326Sharti SSCOP_MSG_FREE(msg); 1790121326Sharti send_endak(sscop); 1791121326Sharti} 1792121326Sharti 1793121326Sharti/* 1794121326Sharti * p 31: IDLE && ER PDU 1795121326Sharti * arg is pdu (freed). 1796121326Sharti */ 1797121326Shartistatic void 1798121326Shartisscop_idle_er(struct sscop *sscop, struct sscop_msg *msg) 1799121326Sharti{ 1800121326Sharti SSCOP_MSG_FREE(msg); 1801121326Sharti MAAL_ERROR(sscop, 'L', 0); 1802121326Sharti FREE_UU(uu_end); 1803121326Sharti send_end(sscop, 1, NULL); 1804121326Sharti} 1805121326Sharti 1806121326Sharti/* 1807121326Sharti * p 31: IDLE && BGREJ PDU 1808121326Sharti * arg is pdu (freed). 1809121326Sharti */ 1810121326Shartistatic void 1811121326Shartisscop_idle_bgrej(struct sscop *sscop, struct sscop_msg *msg) 1812121326Sharti{ 1813121326Sharti SSCOP_MSG_FREE(msg); 1814121326Sharti MAAL_ERROR(sscop, 'D', 0); 1815121326Sharti FREE_UU(uu_end); 1816121326Sharti} 1817121326Sharti 1818121326Sharti/* 1819121326Sharti * p 32: IDLE && POLL PDU 1820121326Sharti * arg is pdu (freed). 1821121326Sharti */ 1822121326Shartistatic void 1823121326Shartisscop_idle_poll(struct sscop *sscop, struct sscop_msg *msg) 1824121326Sharti{ 1825121326Sharti SSCOP_MSG_FREE(msg); 1826121326Sharti MAAL_ERROR(sscop, 'G', 0); 1827121326Sharti FREE_UU(uu_end); 1828121326Sharti send_end(sscop, 1, NULL); 1829121326Sharti} 1830121326Sharti 1831121326Sharti/* 1832121326Sharti * p 32: IDLE && SD PDU 1833121326Sharti * arg is pdu (freed). 1834121326Sharti */ 1835121326Shartistatic void 1836121326Shartisscop_idle_sd(struct sscop *sscop, struct sscop_msg *msg) 1837121326Sharti{ 1838121326Sharti SSCOP_MSG_FREE(msg); 1839121326Sharti MAAL_ERROR(sscop, 'A', 0); 1840121326Sharti FREE_UU(uu_end); 1841121326Sharti send_end(sscop, 1, NULL); 1842121326Sharti} 1843121326Sharti 1844121326Sharti/* 1845121326Sharti * p 32: IDLE && BGAK PDU 1846121326Sharti * arg is pdu (freed). 1847121326Sharti */ 1848121326Shartistatic void 1849121326Shartisscop_idle_bgak(struct sscop *sscop, struct sscop_msg *msg) 1850121326Sharti{ 1851121326Sharti SSCOP_MSG_FREE(msg); 1852121326Sharti MAAL_ERROR(sscop, 'C', 0); 1853121326Sharti FREE_UU(uu_end); 1854121326Sharti send_end(sscop, 1, NULL); 1855121326Sharti} 1856121326Sharti 1857121326Sharti/* 1858121326Sharti * p 32: IDLE && ERAK PDU 1859121326Sharti * arg is pdu (freed). 1860121326Sharti */ 1861121326Shartistatic void 1862121326Shartisscop_idle_erak(struct sscop *sscop, struct sscop_msg *msg) 1863121326Sharti{ 1864121326Sharti SSCOP_MSG_FREE(msg); 1865121326Sharti MAAL_ERROR(sscop, 'M', 0); 1866121326Sharti FREE_UU(uu_end); 1867121326Sharti send_end(sscop, 1, NULL); 1868121326Sharti} 1869121326Sharti 1870121326Sharti/* 1871121326Sharti * p 32: IDLE && STAT PDU 1872121326Sharti * arg is pdu (freed). 1873121326Sharti */ 1874121326Shartistatic void 1875121326Shartisscop_idle_stat(struct sscop *sscop, struct sscop_msg *msg) 1876121326Sharti{ 1877121326Sharti SSCOP_MSG_FREE(msg); 1878121326Sharti MAAL_ERROR(sscop, 'H', 0); 1879121326Sharti FREE_UU(uu_end); 1880121326Sharti send_end(sscop, 1, NULL); 1881121326Sharti} 1882121326Sharti 1883121326Sharti/* 1884121326Sharti * p 32: IDLE && USTAT PDU 1885121326Sharti * arg is pdu (freed). 1886121326Sharti */ 1887121326Shartistatic void 1888121326Shartisscop_idle_ustat(struct sscop *sscop, struct sscop_msg *msg) 1889121326Sharti{ 1890121326Sharti SSCOP_MSG_FREE(msg); 1891121326Sharti MAAL_ERROR(sscop, 'I', 0); 1892121326Sharti FREE_UU(uu_end); 1893121326Sharti send_end(sscop, 1, NULL); 1894121326Sharti} 1895121326Sharti 1896121326Sharti/* 1897121326Sharti * p 33: IDLE & RS PDU 1898121326Sharti * arg is pdu (freed). 1899121326Sharti */ 1900121326Shartistatic void 1901121326Shartisscop_idle_rs(struct sscop *sscop, struct sscop_msg *msg) 1902121326Sharti{ 1903121326Sharti SSCOP_MSG_FREE(msg); 1904121326Sharti MAAL_ERROR(sscop, 'J', 0); 1905121326Sharti FREE_UU(uu_end); 1906121326Sharti send_end(sscop, 1, NULL); 1907121326Sharti} 1908121326Sharti 1909121326Sharti/* 1910121326Sharti * p 33: IDLE & RSAK PDU 1911121326Sharti * arg is pdu (freed). 1912121326Sharti */ 1913121326Shartistatic void 1914121326Shartisscop_idle_rsak(struct sscop *sscop, struct sscop_msg *msg) 1915121326Sharti{ 1916121326Sharti SSCOP_MSG_FREE(msg); 1917121326Sharti MAAL_ERROR(sscop, 'K', 0); 1918121326Sharti FREE_UU(uu_end); 1919121326Sharti send_end(sscop, 1, NULL); 1920121326Sharti} 1921121326Sharti 1922121326Sharti/* 1923121326Sharti * p 33: IDLE && PDU_Q 1924121326Sharti * p XX: OUTPEND && PDU_Q 1925121326Sharti * p 39: IN_PEND && PDU_Q 1926121326Sharti * p 45: OUT_RESYNC_PEND && PDU_Q 1927121326Sharti * p 48: IN_RESYNC_PEND && PDU_Q 1928121326Sharti * no arg 1929121326Sharti */ 1930121326Shartistatic void 1931121326Shartisscop_flush_pduq(struct sscop *sscop __unused, struct sscop_msg *unused __unused) 1932121326Sharti{ 1933121326Sharti#if 0 1934121326Sharti MSGQ_CLEAR(&sscop->xq); 1935121326Sharti#endif 1936121326Sharti} 1937121326Sharti 1938121326Sharti/* 1939121326Sharti * p 34: OUT_PEND && BGAK PDU 1940121326Sharti * arg is pdu (freed). 1941121326Sharti */ 1942121326Shartistatic void 1943121326Shartisscop_outpend_bgak(struct sscop *sscop, struct sscop_msg *msg) 1944121326Sharti{ 1945121326Sharti union pdu pdu; 1946121326Sharti 1947121326Sharti pdu.sscop_null = MBUF_STRIP32(msg->m); 1948121326Sharti (void)MBUF_STRIP32(msg->m); 1949121326Sharti 1950121326Sharti TIMER_STOP(sscop, cc); 1951121326Sharti sscop->vt_ms = pdu.sscop_ns; 1952121326Sharti 1953121326Sharti AAL_UU_SIGNAL(sscop, SSCOP_ESTABLISH_confirm, msg, pdu.sscop_pl, 0); 1954121326Sharti 1955121326Sharti m_initialize_state(sscop); 1956121326Sharti m_set_data_xfer_timers(sscop); 1957121326Sharti 1958121326Sharti sscop_set_state(sscop, SSCOP_READY); 1959121326Sharti} 1960121326Sharti 1961121326Sharti/* 1962121326Sharti * P 34: OUT_PEND && BGREJ PDU 1963121326Sharti */ 1964121326Shartistatic void 1965121326Shartisscop_outpend_bgrej(struct sscop *sscop, struct sscop_msg *msg) 1966121326Sharti{ 1967121326Sharti union pdu pdu; 1968121326Sharti 1969121326Sharti pdu.sscop_null = MBUF_STRIP32(msg->m); 1970121326Sharti (void)MBUF_STRIP32(msg->m); 1971121326Sharti 1972121326Sharti TIMER_STOP(sscop, cc); 1973121326Sharti 1974121326Sharti AAL_UU_SIGNAL(sscop, SSCOP_RELEASE_indication, msg, pdu.sscop_pl, 0); 1975121326Sharti 1976121326Sharti sscop_set_state(sscop, SSCOP_IDLE); 1977121326Sharti} 1978121326Sharti 1979121326Sharti/* 1980121326Sharti * P 35: OUT_PEND && TIMER_CC expiry 1981121326Sharti * no arg 1982121326Sharti */ 1983121326Shartistatic void 1984121326Shartisscop_outpend_tcc(struct sscop *sscop, struct sscop_msg *unused __unused) 1985121326Sharti{ 1986121326Sharti if(sscop->vt_cc >= sscop->maxcc) { 1987121326Sharti MAAL_ERROR(sscop, 'O', 0); 1988121326Sharti FREE_UU(uu_end); 1989121326Sharti send_end(sscop, 1, NULL); 1990121326Sharti 1991121326Sharti AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1); 1992121326Sharti 1993121326Sharti sscop_set_state(sscop, SSCOP_IDLE); 1994121326Sharti } else { 1995121326Sharti sscop->vt_cc++; 1996121326Sharti send_bgn(sscop, sscop->uu_bgn); 1997121326Sharti TIMER_RESTART(sscop, cc); 1998121326Sharti } 1999121326Sharti} 2000121326Sharti 2001121326Sharti/* 2002121326Sharti * P 35: OUT_PEND && RELEASE_REQ 2003121326Sharti * arg is UU 2004121326Sharti */ 2005121326Shartistatic void 2006121326Shartisscop_outpend_release_req(struct sscop *sscop, struct sscop_msg *uu) 2007121326Sharti{ 2008121326Sharti SET_UU(uu_end, uu); 2009121326Sharti 2010121326Sharti TIMER_STOP(sscop, cc); 2011121326Sharti sscop->vt_cc = 1; 2012121326Sharti send_end(sscop, 0, sscop->uu_end); 2013121326Sharti TIMER_RESTART(sscop, cc); 2014121326Sharti 2015121326Sharti sscop_set_state(sscop, SSCOP_OUT_DIS_PEND); 2016121326Sharti} 2017121326Sharti 2018121326Sharti/* 2019121326Sharti * P 36: OUT_PEND && BGN PDU 2020121326Sharti * arg is the received PDU (freed). 2021121326Sharti */ 2022121326Shartistatic void 2023121326Shartisscop_outpend_bgn(struct sscop *sscop, struct sscop_msg *msg) 2024121326Sharti{ 2025121326Sharti union pdu pdu; 2026121326Sharti 2027121326Sharti pdu.sscop_null = MBUF_STRIP32(msg->m); 2028121326Sharti 2029121326Sharti if(m_detect_retransmission(sscop, msg)) { 2030121326Sharti SSCOP_MSG_FREE(msg); 2031121326Sharti return; 2032121326Sharti } 2033121326Sharti (void)MBUF_STRIP32(msg->m); 2034121326Sharti 2035121326Sharti TIMER_STOP(sscop, cc); 2036121326Sharti 2037121326Sharti sscop->vt_ms = pdu.sscop_ns; 2038121326Sharti 2039121326Sharti m_initialize_mr(sscop); 2040121326Sharti 2041121326Sharti send_bgak(sscop, sscop->uu_bgak); 2042121326Sharti 2043121326Sharti AAL_UU_SIGNAL(sscop, SSCOP_ESTABLISH_confirm, msg, pdu.sscop_pl, 0); 2044121326Sharti 2045121326Sharti m_initialize_state(sscop); 2046121326Sharti 2047121326Sharti m_set_data_xfer_timers(sscop); 2048121326Sharti 2049121326Sharti sscop_set_state(sscop, SSCOP_READY); 2050121326Sharti} 2051121326Sharti 2052121326Sharti/* 2053121326Sharti * p 37: IN_PEND && AA-ESTABLISH.response 2054121326Sharti * arg is UU 2055121326Sharti */ 2056121326Shartistatic void 2057121326Shartisscop_inpend_establish_resp(struct sscop *sscop, struct sscop_msg *uu) 2058121326Sharti{ 2059121326Sharti u_int br = uu->rexmit; 2060121326Sharti 2061121326Sharti SET_UU(uu_bgak, uu); 2062121326Sharti 2063121326Sharti m_clear_transmitter(sscop); 2064121326Sharti sscop->clear_buffers = br; 2065121326Sharti m_initialize_mr(sscop); 2066121326Sharti send_bgak(sscop, sscop->uu_bgak); 2067121326Sharti m_initialize_state(sscop); 2068121326Sharti m_set_data_xfer_timers(sscop); 2069121326Sharti 2070121326Sharti sscop_set_state(sscop, SSCOP_READY); 2071121326Sharti} 2072121326Sharti 2073121326Sharti/* 2074121326Sharti * p 37: IN_PEND && AA-RELEASE.request 2075121326Sharti * arg is uu. 2076121326Sharti */ 2077121326Shartistatic void 2078121326Shartisscop_inpend_release_req(struct sscop *sscop, struct sscop_msg *uu) 2079121326Sharti{ 2080121326Sharti SET_UU(uu_bgrej, uu); 2081121326Sharti 2082121326Sharti send_bgrej(sscop, sscop->uu_bgrej); 2083121326Sharti 2084121326Sharti sscop_set_state(sscop, SSCOP_IDLE); 2085121326Sharti} 2086121326Sharti 2087121326Sharti/* 2088121326Sharti * p 37: IN_PEND && BGN PDU 2089121326Sharti * arg is pdu. (freed) 2090121326Sharti */ 2091121326Shartistatic void 2092121326Shartisscop_inpend_bgn(struct sscop *sscop, struct sscop_msg *msg) 2093121326Sharti{ 2094121326Sharti union pdu pdu; 2095121326Sharti 2096121326Sharti pdu.sscop_null = MBUF_STRIP32(msg->m); 2097121326Sharti 2098121326Sharti if(m_detect_retransmission(sscop, msg)) { 2099121326Sharti SSCOP_MSG_FREE(msg); 2100121326Sharti return; 2101121326Sharti } 2102121326Sharti (void)MBUF_STRIP32(msg->m); 2103121326Sharti 2104121326Sharti sscop->vt_ms = pdu.sscop_ns; 2105121326Sharti 2106121326Sharti AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 0); 2107121326Sharti AAL_UU_SIGNAL(sscop, SSCOP_ESTABLISH_indication, msg, pdu.sscop_pl, 0); 2108121326Sharti} 2109121326Sharti 2110121326Sharti/* 2111121326Sharti * p 37: IN_PEND && ER PDU 2112121326Sharti * arg is pdu (freed). 2113121326Sharti */ 2114121326Shartistatic void 2115121326Shartisscop_inpend_er(struct sscop *sscop, struct sscop_msg *msg) 2116121326Sharti{ 2117121326Sharti MAAL_ERROR(sscop, 'L', 0); 2118121326Sharti SSCOP_MSG_FREE(msg); 2119121326Sharti} 2120121326Sharti 2121121326Sharti/* 2122121326Sharti * p 37: IN_PEND && ENDAK PDU 2123121326Sharti * arg is pdu (freed). 2124121326Sharti */ 2125121326Shartistatic void 2126121326Shartisscop_inpend_endak(struct sscop *sscop, struct sscop_msg *msg) 2127121326Sharti{ 2128121326Sharti MAAL_ERROR(sscop, 'F', 0); 2129121326Sharti 2130121326Sharti AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1); 2131121326Sharti 2132121326Sharti sscop_set_state(sscop, SSCOP_IDLE); 2133121326Sharti 2134121326Sharti SSCOP_MSG_FREE(msg); 2135121326Sharti} 2136121326Sharti 2137121326Sharti/* 2138121326Sharti * p 38: IN_PEND && BGAK PDU 2139121326Sharti * arg is pdu (freed). 2140121326Sharti */ 2141121326Shartistatic void 2142121326Shartisscop_inpend_bgak(struct sscop *sscop, struct sscop_msg *msg) 2143121326Sharti{ 2144121326Sharti MAAL_ERROR(sscop, 'C', 0); 2145121326Sharti 2146121326Sharti SSCOP_MSG_FREE(msg); 2147121326Sharti} 2148121326Sharti 2149121326Sharti/* 2150121326Sharti * p 38: IN_PEND && BGREJ PDU 2151121326Sharti * arg is pdu (freed). 2152121326Sharti */ 2153121326Shartistatic void 2154121326Shartisscop_inpend_bgrej(struct sscop *sscop, struct sscop_msg *msg) 2155121326Sharti{ 2156121326Sharti MAAL_ERROR(sscop, 'D', 0); 2157121326Sharti 2158121326Sharti AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1); 2159121326Sharti 2160121326Sharti SSCOP_MSG_FREE(msg); 2161121326Sharti 2162121326Sharti sscop_set_state(sscop, SSCOP_IDLE); 2163121326Sharti} 2164121326Sharti 2165121326Sharti/* 2166121326Sharti * p 38: IN_PEND && SD PDU 2167121326Sharti * arg is pdu (freed). 2168121326Sharti */ 2169121326Shartistatic void 2170121326Shartisscop_inpend_sd(struct sscop *sscop, struct sscop_msg *msg) 2171121326Sharti{ 2172121326Sharti MAAL_ERROR(sscop, 'A', 0); 2173121326Sharti 2174121326Sharti SSCOP_MSG_FREE(msg); 2175121326Sharti 2176121326Sharti FREE_UU(uu_end); 2177121326Sharti send_end(sscop, 1, NULL); 2178121326Sharti 2179121326Sharti AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1); 2180121326Sharti 2181121326Sharti sscop_set_state(sscop, SSCOP_IDLE); 2182121326Sharti} 2183121326Sharti 2184121326Sharti/* 2185121326Sharti * p 38: IN_PEND && USTAT PDU 2186121326Sharti * arg is pdu (freed). 2187121326Sharti */ 2188121326Shartistatic void 2189121326Shartisscop_inpend_ustat(struct sscop *sscop, struct sscop_msg *msg) 2190121326Sharti{ 2191121326Sharti MAAL_ERROR(sscop, 'I', 0); 2192121326Sharti 2193121326Sharti SSCOP_MSG_FREE(msg); 2194121326Sharti 2195121326Sharti FREE_UU(uu_end); 2196121326Sharti send_end(sscop, 1, NULL); 2197121326Sharti 2198121326Sharti AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1); 2199121326Sharti 2200121326Sharti sscop_set_state(sscop, SSCOP_IDLE); 2201121326Sharti} 2202121326Sharti 2203121326Sharti/* 2204121326Sharti * p 38: IN_PEND && STAT PDU 2205121326Sharti * arg is pdu (freed). 2206121326Sharti */ 2207121326Shartistatic void 2208121326Shartisscop_inpend_stat(struct sscop *sscop, struct sscop_msg *msg) 2209121326Sharti{ 2210121326Sharti MAAL_ERROR(sscop, 'H', 0); 2211121326Sharti 2212121326Sharti SSCOP_MSG_FREE(msg); 2213121326Sharti 2214121326Sharti FREE_UU(uu_end); 2215121326Sharti send_end(sscop, 1, NULL); 2216121326Sharti 2217121326Sharti AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1); 2218121326Sharti 2219121326Sharti sscop_set_state(sscop, SSCOP_IDLE); 2220121326Sharti} 2221121326Sharti 2222121326Sharti/* 2223121326Sharti * p 38: IN_PEND && POLL PDU 2224121326Sharti * arg is pdu (freed). 2225121326Sharti */ 2226121326Shartistatic void 2227121326Shartisscop_inpend_poll(struct sscop *sscop, struct sscop_msg *msg) 2228121326Sharti{ 2229121326Sharti MAAL_ERROR(sscop, 'G', 0); 2230121326Sharti 2231121326Sharti SSCOP_MSG_FREE(msg); 2232121326Sharti 2233121326Sharti FREE_UU(uu_end); 2234121326Sharti send_end(sscop, 1, NULL); 2235121326Sharti 2236121326Sharti AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1); 2237121326Sharti 2238121326Sharti sscop_set_state(sscop, SSCOP_IDLE); 2239121326Sharti} 2240121326Sharti 2241121326Sharti/* 2242121326Sharti * p 39: IN_PEND && ERAK PDU 2243121326Sharti * arg is pdu (freed). 2244121326Sharti */ 2245121326Shartistatic void 2246121326Shartisscop_inpend_erak(struct sscop *sscop, struct sscop_msg *msg) 2247121326Sharti{ 2248121326Sharti SSCOP_MSG_FREE(msg); 2249121326Sharti MAAL_ERROR(sscop, 'M', 0); 2250121326Sharti} 2251121326Sharti 2252121326Sharti/* 2253121326Sharti * p 39: IN_PEND & RS PDU 2254121326Sharti * arg is pdu (freed). 2255121326Sharti */ 2256121326Shartistatic void 2257121326Shartisscop_inpend_rs(struct sscop *sscop, struct sscop_msg *msg) 2258121326Sharti{ 2259121326Sharti SSCOP_MSG_FREE(msg); 2260121326Sharti MAAL_ERROR(sscop, 'J', 0); 2261121326Sharti} 2262121326Sharti 2263121326Sharti/* 2264121326Sharti * p 39: IN_PEND & RSAK PDU 2265121326Sharti * arg is pdu (freed). 2266121326Sharti */ 2267121326Shartistatic void 2268121326Shartisscop_inpend_rsak(struct sscop *sscop, struct sscop_msg *msg) 2269121326Sharti{ 2270121326Sharti SSCOP_MSG_FREE(msg); 2271121326Sharti MAAL_ERROR(sscop, 'K', 0); 2272121326Sharti} 2273121326Sharti 2274121326Sharti/* 2275121326Sharti * p 39: IN_PEND && END PDU 2276121326Sharti * arg is pdu (freed). 2277121326Sharti * no uui 2278121326Sharti */ 2279121326Shartistatic void 2280121326Shartisscop_inpend_end(struct sscop *sscop, struct sscop_msg *msg) 2281121326Sharti{ 2282121326Sharti union pdu pdu; 2283121326Sharti 2284121326Sharti pdu.sscop_null = MBUF_STRIP32(msg->m); 2285121326Sharti (void)MBUF_STRIP32(msg->m); 2286121326Sharti 2287121326Sharti send_endak(sscop); 2288121326Sharti 2289121326Sharti AAL_UU_SIGNAL(sscop, SSCOP_RELEASE_indication, 2290121326Sharti msg, pdu.sscop_pl, (u_int)pdu.sscop_s); 2291121326Sharti 2292121326Sharti sscop_set_state(sscop, SSCOP_IDLE); 2293121326Sharti} 2294121326Sharti 2295121326Sharti/* 2296121326Sharti * p 40: OUT_DIS_PEND && SSCOP_ESTABLISH_request 2297121326Sharti * no arg. 2298121326Sharti * no uui. 2299121326Sharti */ 2300121326Shartistatic void 2301121326Shartisscop_outdis_establish_req(struct sscop *sscop, struct sscop_msg *uu) 2302121326Sharti{ 2303121326Sharti SET_UU(uu_bgn, uu); 2304121326Sharti 2305121326Sharti TIMER_STOP(sscop, cc); 2306121326Sharti m_clear_transmitter(sscop); 2307121326Sharti sscop->clear_buffers = 1; 2308121326Sharti sscop->vt_cc = 1; 2309121326Sharti sscop->vt_sq++; 2310121326Sharti m_initialize_mr(sscop); 2311121326Sharti send_bgn(sscop, sscop->uu_bgn); 2312121326Sharti TIMER_RESTART(sscop, cc); 2313121326Sharti 2314121326Sharti sscop_set_state(sscop, SSCOP_OUT_PEND); 2315121326Sharti} 2316121326Sharti 2317121326Sharti/* 2318121326Sharti * p 41: OUT_DIS_PEND && END PDU 2319121326Sharti * arg is pdu (freed). 2320121326Sharti */ 2321121326Shartistatic void 2322121326Shartisscop_outdis_end(struct sscop *sscop, struct sscop_msg *msg) 2323121326Sharti{ 2324121326Sharti union pdu pdu; 2325121326Sharti 2326121326Sharti pdu.sscop_null = MBUF_STRIP32(msg->m); 2327121326Sharti (void)MBUF_STRIP32(msg->m); 2328121326Sharti 2329121326Sharti TIMER_STOP(sscop, cc); 2330121326Sharti send_endak(sscop); 2331121326Sharti 2332121326Sharti AAL_UU_SIGNAL(sscop, SSCOP_RELEASE_confirm, msg, pdu.sscop_pl, 0); 2333121326Sharti 2334121326Sharti sscop_set_state(sscop, SSCOP_IDLE); 2335121326Sharti} 2336121326Sharti 2337121326Sharti/* 2338121326Sharti * p 41: OUT_DIS_PEND && ENDAK PDU 2339121326Sharti * p 41: OUT_DIS_PEND && BGREJ PDU 2340121326Sharti * arg is pdu (freed) 2341121326Sharti */ 2342121326Shartistatic void 2343121326Shartisscop_outdis_endak(struct sscop *sscop, struct sscop_msg *msg) 2344121326Sharti{ 2345121326Sharti union pdu pdu; 2346121326Sharti 2347121326Sharti pdu.sscop_null = MBUF_STRIP32(msg->m); 2348121326Sharti (void)MBUF_STRIP32(msg->m); 2349121326Sharti 2350121326Sharti TIMER_STOP(sscop, cc); 2351121326Sharti 2352121326Sharti AAL_UU_SIGNAL(sscop, SSCOP_RELEASE_confirm, msg, pdu.sscop_pl, 0); 2353121326Sharti 2354121326Sharti sscop_set_state(sscop, SSCOP_IDLE); 2355121326Sharti} 2356121326Sharti 2357121326Sharti/* 2358121326Sharti * p 41: OUT_DIS_PEND && TIMER CC expiry 2359121326Sharti * no arg 2360121326Sharti */ 2361121326Shartistatic void 2362121326Shartisscop_outdis_cc(struct sscop *sscop, struct sscop_msg *unused __unused) 2363121326Sharti{ 2364121326Sharti if(sscop->vt_cc >= sscop->maxcc) { 2365121326Sharti MAAL_ERROR(sscop, 'O', 0); 2366121326Sharti AAL_SIG(sscop, SSCOP_RELEASE_confirm); 2367121326Sharti sscop_set_state(sscop, SSCOP_IDLE); 2368121326Sharti } else { 2369121326Sharti sscop->vt_cc++; 2370121326Sharti send_end(sscop, sscop->last_end_src, sscop->uu_end); 2371121326Sharti TIMER_RESTART(sscop, cc); 2372121326Sharti } 2373121326Sharti} 2374121326Sharti 2375121326Sharti/* 2376121326Sharti * p 42: OUT_DIS_PEND && BGN PDU 2377121326Sharti * arg is pdu (freed). 2378121326Sharti */ 2379121326Shartistatic void 2380121326Shartisscop_outdis_bgn(struct sscop *sscop, struct sscop_msg *msg) 2381121326Sharti{ 2382121326Sharti union pdu pdu; 2383121326Sharti 2384121326Sharti pdu.sscop_null = MBUF_STRIP32(msg->m); 2385121326Sharti 2386121326Sharti if(m_detect_retransmission(sscop, msg)) { 2387121326Sharti FREE_UU(uu_bgak); 2388121326Sharti send_bgak(sscop, NULL); 2389121326Sharti send_end(sscop, sscop->last_end_src, sscop->uu_end); 2390121326Sharti SSCOP_MSG_FREE(msg); 2391121326Sharti 2392121326Sharti } else { 2393121326Sharti (void)MBUF_STRIP32(msg->m); 2394121326Sharti 2395121326Sharti TIMER_STOP(sscop, cc); 2396121326Sharti sscop->vt_ms = pdu.sscop_ns; 2397121326Sharti AAL_SIG(sscop, SSCOP_RELEASE_confirm); 2398121326Sharti AAL_UU_SIGNAL(sscop, SSCOP_ESTABLISH_indication, 2399121326Sharti msg, pdu.sscop_pl, 0); 2400121326Sharti sscop_set_state(sscop, SSCOP_IN_PEND); 2401121326Sharti } 2402121326Sharti} 2403121326Sharti 2404121326Sharti/* 2405121326Sharti * p 43: OUT_RESYNC_PEND && BGN PDU 2406121326Sharti * arg is pdu (freed). 2407121326Sharti */ 2408121326Shartistatic void 2409121326Shartisscop_outsync_bgn(struct sscop *sscop, struct sscop_msg *msg) 2410121326Sharti{ 2411121326Sharti union pdu pdu; 2412121326Sharti 2413121326Sharti pdu.sscop_null = MBUF_STRIP32(msg->m); 2414121326Sharti 2415121326Sharti if(m_detect_retransmission(sscop, msg)) { 2416121326Sharti send_bgak(sscop, sscop->uu_bgak); 2417121326Sharti send_rs(sscop, 1, sscop->uu_rs); 2418121326Sharti SSCOP_MSG_FREE(msg); 2419121326Sharti } else { 2420121326Sharti (void)MBUF_STRIP32(msg->m); 2421121326Sharti 2422121326Sharti TIMER_STOP(sscop, cc); 2423121326Sharti sscop->vt_ms = pdu.sscop_ns; 2424121326Sharti AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 0); 2425121326Sharti AAL_UU_SIGNAL(sscop, SSCOP_ESTABLISH_indication, 2426121326Sharti msg, pdu.sscop_pl, 0); 2427121326Sharti sscop_set_state(sscop, SSCOP_IN_PEND); 2428121326Sharti } 2429121326Sharti} 2430121326Sharti 2431121326Sharti/* 2432121326Sharti * p 43: OUT_RESYNC_PEND && ENDAK PDU 2433121326Sharti * arg is pdu (freed). 2434121326Sharti */ 2435121326Shartistatic void 2436121326Shartisscop_outsync_endak(struct sscop *sscop, struct sscop_msg *msg) 2437121326Sharti{ 2438121326Sharti SSCOP_MSG_FREE(msg); 2439121326Sharti TIMER_STOP(sscop, cc); 2440121326Sharti MAAL_ERROR(sscop, 'F', 0); 2441121326Sharti AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1); 2442121326Sharti sscop_set_state(sscop, SSCOP_IDLE); 2443121326Sharti} 2444121326Sharti 2445121326Sharti/* 2446121326Sharti * p 43: OUT_RESYNC_PEND && BGREJ PDU 2447121326Sharti * arg is pdu (freed). 2448121326Sharti */ 2449121326Shartistatic void 2450121326Shartisscop_outsync_bgrej(struct sscop *sscop, struct sscop_msg *msg) 2451121326Sharti{ 2452121326Sharti SSCOP_MSG_FREE(msg); 2453121326Sharti TIMER_STOP(sscop, cc); 2454121326Sharti MAAL_ERROR(sscop, 'D', 0); 2455121326Sharti AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1); 2456121326Sharti sscop_set_state(sscop, SSCOP_IDLE); 2457121326Sharti} 2458121326Sharti 2459121326Sharti/* 2460121326Sharti * p 43: OUT_RESYNC_PEND && END PDU 2461121326Sharti * arg is pdu (freed). 2462121326Sharti * no UU-data 2463121326Sharti */ 2464121326Shartistatic void 2465121326Shartisscop_outsync_end(struct sscop *sscop, struct sscop_msg *msg) 2466121326Sharti{ 2467121326Sharti union pdu pdu; 2468121326Sharti 2469121326Sharti pdu.sscop_null = MBUF_STRIP32(msg->m); 2470121326Sharti (void)MBUF_STRIP32(msg->m); 2471121326Sharti 2472121326Sharti TIMER_STOP(sscop, cc); 2473121326Sharti send_endak(sscop); 2474121326Sharti AAL_UU_SIGNAL(sscop, SSCOP_RELEASE_indication, msg, pdu.sscop_pl, 2475121326Sharti (u_int)pdu.sscop_s); 2476121326Sharti sscop_set_state(sscop, SSCOP_IDLE); 2477121326Sharti} 2478121326Sharti 2479121326Sharti/* 2480121326Sharti * p 44: OUT_RESYNC && TIMER CC expiry 2481121326Sharti */ 2482121326Shartistatic void 2483121326Shartisscop_outsync_cc(struct sscop *sscop, struct sscop_msg *msg __unused) 2484121326Sharti{ 2485121326Sharti if(sscop->vt_cc == sscop->maxcc) { 2486121326Sharti MAAL_ERROR(sscop, 'O', 0); 2487121326Sharti FREE_UU(uu_end); 2488121326Sharti send_end(sscop, 1, NULL); 2489121326Sharti AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1); 2490121326Sharti sscop_set_state(sscop, SSCOP_IDLE); 2491121326Sharti } else { 2492121326Sharti sscop->vt_cc++; 2493121326Sharti send_rs(sscop, 1, sscop->uu_rs); 2494121326Sharti TIMER_RESTART(sscop, cc); 2495121326Sharti } 2496121326Sharti} 2497121326Sharti 2498121326Sharti/* 2499121326Sharti * p 44: OUT_RESYNC && AA-RELEASE.request 2500121326Sharti * arg is UU 2501121326Sharti */ 2502121326Shartistatic void 2503121326Shartisscop_outsync_release_req(struct sscop *sscop, struct sscop_msg *uu) 2504121326Sharti{ 2505121326Sharti SET_UU(uu_end, uu); 2506121326Sharti 2507121326Sharti TIMER_STOP(sscop, cc); 2508121326Sharti sscop->vt_cc = 1; 2509121326Sharti send_end(sscop, 0, sscop->uu_end); 2510121326Sharti TIMER_RESTART(sscop, cc); 2511121326Sharti sscop_set_state(sscop, SSCOP_OUT_DIS_PEND); 2512121326Sharti} 2513121326Sharti 2514121326Sharti/* 2515121326Sharti * p 45: OUT_RESYNC && RS PDU 2516121326Sharti * arg is pdu (freed). 2517121326Sharti */ 2518121326Shartistatic void 2519121326Shartisscop_outsync_rs(struct sscop *sscop, struct sscop_msg *msg) 2520121326Sharti{ 2521121326Sharti union pdu pdu; 2522121326Sharti 2523121326Sharti pdu.sscop_null = MBUF_STRIP32(msg->m); 2524121326Sharti 2525121326Sharti if(m_detect_retransmission(sscop, msg)) { 2526121326Sharti SSCOP_MSG_FREE(msg); 2527121326Sharti return; 2528121326Sharti } 2529121326Sharti (void)MBUF_STRIP32(msg->m); 2530121326Sharti 2531121326Sharti TIMER_STOP(sscop, cc); 2532121326Sharti sscop->vt_ms = pdu.sscop_ns; 2533121326Sharti m_initialize_mr(sscop); 2534121326Sharti send_rsak(sscop); 2535121326Sharti AAL_UU_SIGNAL(sscop, SSCOP_RESYNC_confirm, msg, pdu.sscop_pl, 0); 2536121326Sharti m_initialize_state(sscop); 2537121326Sharti m_set_data_xfer_timers(sscop); 2538121326Sharti sscop_set_state(sscop, SSCOP_READY); 2539121326Sharti} 2540121326Sharti 2541121326Sharti/* 2542121326Sharti * p 45: OUT_RESYNC && RSAK PDU 2543121326Sharti * arg is pdu (freed). 2544121326Sharti */ 2545121326Shartistatic void 2546121326Shartisscop_outsync_rsak(struct sscop *sscop, struct sscop_msg *msg) 2547121326Sharti{ 2548121326Sharti union pdu pdu; 2549121326Sharti 2550121326Sharti pdu.sscop_null = MBUF_STRIP32(msg->m); 2551121326Sharti 2552121326Sharti SSCOP_MSG_FREE(msg); 2553121326Sharti 2554121326Sharti TIMER_STOP(sscop, cc); 2555121326Sharti sscop->vt_ms = pdu.sscop_ns; 2556121326Sharti AAL_SIG(sscop, SSCOP_RESYNC_confirm); 2557121326Sharti m_initialize_state(sscop); 2558121326Sharti m_set_data_xfer_timers(sscop); 2559121326Sharti sscop_set_state(sscop, SSCOP_READY); 2560121326Sharti} 2561121326Sharti 2562121326Sharti/* 2563121326Sharti * p 46: IN_RESYNC_PEND && AA-RESYNC.response 2564121326Sharti */ 2565121326Shartistatic void 2566121326Shartisscop_insync_sync_resp(struct sscop *sscop, struct sscop_msg *noarg __unused) 2567121326Sharti{ 2568121326Sharti m_initialize_mr(sscop); 2569121326Sharti send_rsak(sscop); 2570121326Sharti m_clear_transmitter(sscop); 2571121326Sharti m_initialize_state(sscop); 2572121326Sharti m_set_data_xfer_timers(sscop); 2573121326Sharti sscop_set_state(sscop, SSCOP_READY); 2574121326Sharti} 2575121326Sharti 2576121326Sharti/* 2577121326Sharti * p 46: IN_RESYNC_PEND && AA-RELEASE.request 2578121326Sharti * arg is uu 2579121326Sharti */ 2580121326Shartistatic void 2581121326Shartisscop_insync_release_req(struct sscop *sscop, struct sscop_msg *uu) 2582121326Sharti{ 2583121326Sharti SET_UU(uu_end, uu); 2584121326Sharti 2585121326Sharti sscop->vt_cc = 1; 2586121326Sharti send_end(sscop, 0, sscop->uu_end); 2587121326Sharti TIMER_RESTART(sscop, cc); 2588121326Sharti sscop_set_state(sscop, SSCOP_OUT_DIS_PEND); 2589121326Sharti} 2590121326Sharti 2591121326Sharti/* 2592121326Sharti * p 46: IN_RESYNC_PEND && ENDAK PDU 2593121326Sharti * arg is pdu (freed). 2594121326Sharti */ 2595121326Shartistatic void 2596121326Shartisscop_insync_endak(struct sscop *sscop, struct sscop_msg *msg) 2597121326Sharti{ 2598121326Sharti SSCOP_MSG_FREE(msg); 2599121326Sharti MAAL_ERROR(sscop, 'F', 0); 2600121326Sharti AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1); 2601121326Sharti sscop_set_state(sscop, SSCOP_IDLE); 2602121326Sharti} 2603121326Sharti 2604121326Sharti/* 2605121326Sharti * p 46: IN_RESYNC_PEND && BGREJ PDU 2606121326Sharti * arg is pdu (freed). 2607121326Sharti */ 2608121326Shartistatic void 2609121326Shartisscop_insync_bgrej(struct sscop *sscop, struct sscop_msg *msg) 2610121326Sharti{ 2611121326Sharti SSCOP_MSG_FREE(msg); 2612121326Sharti MAAL_ERROR(sscop, 'D', 0); 2613121326Sharti AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1); 2614121326Sharti sscop_set_state(sscop, SSCOP_IDLE); 2615121326Sharti} 2616121326Sharti 2617121326Sharti/* 2618121326Sharti * p 46: IN_RESYNC_PEND && END PDU 2619121326Sharti * arg is pdu (freed). 2620121326Sharti */ 2621121326Shartistatic void 2622121326Shartisscop_insync_end(struct sscop *sscop, struct sscop_msg *msg) 2623121326Sharti{ 2624121326Sharti union pdu pdu; 2625121326Sharti 2626121326Sharti pdu.sscop_null = MBUF_STRIP32(msg->m); 2627121326Sharti (void)MBUF_STRIP32(msg->m); 2628121326Sharti 2629121326Sharti send_endak(sscop); 2630121326Sharti AAL_UU_SIGNAL(sscop, SSCOP_RELEASE_indication, 2631121326Sharti msg, pdu.sscop_pl, (u_int)pdu.sscop_s); 2632121326Sharti sscop_set_state(sscop, SSCOP_IDLE); 2633121326Sharti} 2634121326Sharti 2635121326Sharti/* 2636121326Sharti * p 47: IN_RESYNC_PEND && ER PDU 2637121326Sharti * arg is pdu (freed). 2638121326Sharti */ 2639121326Shartistatic void 2640121326Shartisscop_insync_er(struct sscop *sscop, struct sscop_msg *msg) 2641121326Sharti{ 2642121326Sharti SSCOP_MSG_FREE(msg); 2643121326Sharti MAAL_ERROR(sscop, 'L', 0); 2644121326Sharti} 2645121326Sharti 2646121326Sharti/* 2647121326Sharti * p 47: IN_RESYNC_PEND && BGN PDU 2648121326Sharti * arg is pdu (freed). 2649121326Sharti */ 2650121326Shartistatic void 2651121326Shartisscop_insync_bgn(struct sscop *sscop, struct sscop_msg *msg) 2652121326Sharti{ 2653121326Sharti union pdu pdu; 2654121326Sharti 2655121326Sharti pdu.sscop_null = MBUF_STRIP32(msg->m); 2656121326Sharti 2657121326Sharti if(m_detect_retransmission(sscop, msg)) { 2658121326Sharti MAAL_ERROR(sscop, 'B', 0); 2659121326Sharti SSCOP_MSG_FREE(msg); 2660121326Sharti return; 2661121326Sharti } 2662121326Sharti (void)MBUF_STRIP32(msg->m); 2663121326Sharti 2664121326Sharti sscop->vt_ms = pdu.sscop_ns; 2665121326Sharti AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 0); 2666121326Sharti AAL_UU_SIGNAL(sscop, SSCOP_ESTABLISH_indication, msg, pdu.sscop_pl, 0); 2667121326Sharti 2668121326Sharti sscop_set_state(sscop, SSCOP_IN_PEND); 2669121326Sharti} 2670121326Sharti 2671121326Sharti/* 2672121326Sharti * p 47: IN_RESYNC_PEND && SD PDU 2673121326Sharti * arg is pdu (freed). 2674121326Sharti */ 2675121326Shartistatic void 2676121326Shartisscop_insync_sd(struct sscop *sscop, struct sscop_msg *msg) 2677121326Sharti{ 2678121326Sharti SSCOP_MSG_FREE(msg); 2679121326Sharti MAAL_ERROR(sscop, 'A', 0); 2680121326Sharti FREE_UU(uu_end); 2681121326Sharti send_end(sscop, 1, NULL); 2682121326Sharti AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1); 2683121326Sharti sscop_set_state(sscop, SSCOP_IDLE); 2684121326Sharti} 2685121326Sharti 2686121326Sharti/* 2687121326Sharti * p 47: IN_RESYNC_PEND && POLL PDU 2688121326Sharti * arg is pdu (freed). 2689121326Sharti */ 2690121326Shartistatic void 2691121326Shartisscop_insync_poll(struct sscop *sscop, struct sscop_msg *msg) 2692121326Sharti{ 2693121326Sharti SSCOP_MSG_FREE(msg); 2694121326Sharti MAAL_ERROR(sscop, 'G', 0); 2695121326Sharti FREE_UU(uu_end); 2696121326Sharti send_end(sscop, 1, NULL); 2697121326Sharti AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1); 2698121326Sharti sscop_set_state(sscop, SSCOP_IDLE); 2699121326Sharti} 2700121326Sharti 2701121326Sharti/* 2702121326Sharti * p 47: IN_RESYNC_PEND && STAT PDU 2703121326Sharti * arg is pdu (freed). 2704121326Sharti */ 2705121326Shartistatic void 2706121326Shartisscop_insync_stat(struct sscop *sscop, struct sscop_msg *msg) 2707121326Sharti{ 2708121326Sharti SSCOP_MSG_FREE(msg); 2709121326Sharti MAAL_ERROR(sscop, 'H', 0); 2710121326Sharti FREE_UU(uu_end); 2711121326Sharti send_end(sscop, 1, NULL); 2712121326Sharti AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1); 2713121326Sharti sscop_set_state(sscop, SSCOP_IDLE); 2714121326Sharti} 2715121326Sharti 2716121326Sharti/* 2717121326Sharti * p 47: IN_RESYNC_PEND && USTAT PDU 2718121326Sharti * arg is pdu (freed). 2719121326Sharti */ 2720121326Shartistatic void 2721121326Shartisscop_insync_ustat(struct sscop *sscop, struct sscop_msg *msg) 2722121326Sharti{ 2723121326Sharti SSCOP_MSG_FREE(msg); 2724121326Sharti MAAL_ERROR(sscop, 'I', 0); 2725121326Sharti FREE_UU(uu_end); 2726121326Sharti send_end(sscop, 1, NULL); 2727121326Sharti AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1); 2728121326Sharti sscop_set_state(sscop, SSCOP_IDLE); 2729121326Sharti} 2730121326Sharti 2731121326Sharti/* 2732121326Sharti * p 48: IN_RESYNC_PEND && BGAK PDU 2733121326Sharti * arg is pdu (freed). 2734121326Sharti */ 2735121326Shartistatic void 2736121326Shartisscop_insync_bgak(struct sscop *sscop, struct sscop_msg *msg) 2737121326Sharti{ 2738121326Sharti MAAL_ERROR(sscop, 'C', 0); 2739121326Sharti SSCOP_MSG_FREE(msg); 2740121326Sharti} 2741121326Sharti 2742121326Sharti/* 2743121326Sharti * p 48: IN_RESYNC_PEND && ERAK PDU 2744121326Sharti * arg is pdu (freed). 2745121326Sharti */ 2746121326Shartistatic void 2747121326Shartisscop_insync_erak(struct sscop *sscop, struct sscop_msg *msg) 2748121326Sharti{ 2749121326Sharti MAAL_ERROR(sscop, 'M', 0); 2750121326Sharti SSCOP_MSG_FREE(msg); 2751121326Sharti} 2752121326Sharti 2753121326Sharti/* 2754121326Sharti * p 48: IN_RESYNC_PEND && RS PDU 2755121326Sharti * arg is pdu (freed). 2756121326Sharti */ 2757121326Shartistatic void 2758121326Shartisscop_insync_rs(struct sscop *sscop, struct sscop_msg *msg) 2759121326Sharti{ 2760121326Sharti union pdu pdu; 2761121326Sharti 2762121326Sharti pdu.sscop_null = MBUF_STRIP32(msg->m); 2763121326Sharti 2764121326Sharti if(m_detect_retransmission(sscop, msg)) { 2765121326Sharti SSCOP_MSG_FREE(msg); 2766121326Sharti return; 2767121326Sharti } 2768121326Sharti SSCOP_MSG_FREE(msg); 2769121326Sharti MAAL_ERROR(sscop, 'J', 0); 2770121326Sharti} 2771121326Sharti 2772121326Sharti/* 2773121326Sharti * p 48: IN_RESYNC_PEND && RSAK PDU 2774121326Sharti * arg is pdu (freed). 2775121326Sharti */ 2776121326Shartistatic void 2777121326Shartisscop_insync_rsak(struct sscop *sscop, struct sscop_msg *msg) 2778121326Sharti{ 2779121326Sharti MAAL_ERROR(sscop, 'K', 0); 2780121326Sharti SSCOP_MSG_FREE(msg); 2781121326Sharti} 2782121326Sharti 2783121326Sharti 2784121326Sharti/* 2785121326Sharti * p 49: OUT_REC_PEND && AA-DATA.request 2786121326Sharti * arg is message (queued). 2787121326Sharti */ 2788121326Shartistatic void 2789121326Shartisscop_outrec_userdata(struct sscop *sscop, struct sscop_msg *msg) 2790121326Sharti{ 2791121326Sharti if(!sscop->clear_buffers) { 2792121326Sharti MSGQ_APPEND(&sscop->xq, msg); 2793121326Sharti sscop_signal(sscop, SIG_PDU_Q, msg); 2794121326Sharti } else { 2795121326Sharti SSCOP_MSG_FREE(msg); 2796121326Sharti } 2797121326Sharti} 2798121326Sharti 2799121326Sharti/* 2800121326Sharti * p 49: OUT_REC_PEND && BGAK PDU 2801121326Sharti * arg is pdu (freed) 2802121326Sharti */ 2803121326Shartistatic void 2804121326Shartisscop_outrec_bgak(struct sscop *sscop, struct sscop_msg *msg) 2805121326Sharti{ 2806121326Sharti MAAL_ERROR(sscop, 'C', 0); 2807121326Sharti 2808121326Sharti SSCOP_MSG_FREE(msg); 2809121326Sharti} 2810121326Sharti 2811121326Sharti/* 2812121326Sharti * p 49: OUT_REC_PEND && ERAK PDU 2813121326Sharti * arg is pdu (freed) 2814121326Sharti */ 2815121326Shartistatic void 2816121326Shartisscop_outrec_erak(struct sscop *sscop, struct sscop_msg *msg) 2817121326Sharti{ 2818121326Sharti union pdu pdu; 2819121326Sharti 2820121326Sharti pdu.sscop_null = MBUF_STRIP32(msg->m); 2821121326Sharti 2822121326Sharti TIMER_STOP(sscop, cc); 2823121326Sharti sscop->vt_ms = pdu.sscop_ns; 2824121326Sharti m_deliver_data(sscop); 2825121326Sharti 2826121326Sharti AAL_SIG(sscop, SSCOP_RECOVER_indication); 2827121326Sharti 2828121326Sharti sscop_set_state(sscop, SSCOP_REC_PEND); 2829121326Sharti 2830121326Sharti SSCOP_MSG_FREE(msg); 2831121326Sharti} 2832121326Sharti 2833121326Sharti/* 2834121326Sharti * p 49: OUT_REC_PEND && END PDU 2835121326Sharti * arg is pdu (freed) 2836121326Sharti */ 2837121326Shartistatic void 2838121326Shartisscop_outrec_end(struct sscop *sscop, struct sscop_msg *msg) 2839121326Sharti{ 2840121326Sharti union pdu pdu; 2841121326Sharti 2842121326Sharti pdu.sscop_null = MBUF_STRIP32(msg->m); 2843121326Sharti (void)MBUF_STRIP32(msg->m); 2844121326Sharti 2845121326Sharti TIMER_STOP(sscop, cc); 2846121326Sharti send_endak(sscop); 2847121326Sharti AAL_UU_SIGNAL(sscop, SSCOP_RELEASE_indication, 2848121326Sharti msg, pdu.sscop_pl, (u_int)pdu.sscop_s); 2849121326Sharti 2850121326Sharti MSGQ_CLEAR(&sscop->rbuf); 2851121326Sharti 2852121326Sharti sscop_set_state(sscop, SSCOP_IDLE); 2853121326Sharti} 2854121326Sharti 2855121326Sharti/* 2856121326Sharti * p 49: OUT_REC_PEND && ENDAK PDU 2857121326Sharti * arg is pdu (freed) 2858121326Sharti */ 2859121326Shartistatic void 2860121326Shartisscop_outrec_endak(struct sscop *sscop, struct sscop_msg *msg) 2861121326Sharti{ 2862121326Sharti MAAL_ERROR(sscop, 'F', 0); 2863121326Sharti TIMER_STOP(sscop, cc); 2864121326Sharti AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1); 2865121326Sharti MSGQ_CLEAR(&sscop->rbuf); 2866121326Sharti 2867121326Sharti sscop_set_state(sscop, SSCOP_IDLE); 2868121326Sharti 2869121326Sharti SSCOP_MSG_FREE(msg); 2870121326Sharti} 2871121326Sharti 2872121326Sharti/* 2873121326Sharti * p 49: OUT_REC_PEND && BGREJ PDU 2874121326Sharti * arg is pdu (freed) 2875121326Sharti */ 2876121326Shartistatic void 2877121326Shartisscop_outrec_bgrej(struct sscop *sscop, struct sscop_msg *msg) 2878121326Sharti{ 2879121326Sharti MAAL_ERROR(sscop, 'D', 0); 2880121326Sharti TIMER_STOP(sscop, cc); 2881121326Sharti AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1); 2882121326Sharti MSGQ_CLEAR(&sscop->rbuf); 2883121326Sharti 2884121326Sharti sscop_set_state(sscop, SSCOP_IDLE); 2885121326Sharti 2886121326Sharti SSCOP_MSG_FREE(msg); 2887121326Sharti} 2888121326Sharti 2889121326Sharti/* 2890121326Sharti * p 50: OUT_REC_PEND && TIMER CC expiry 2891121326Sharti * no arg. 2892121326Sharti */ 2893121326Shartistatic void 2894121326Shartisscop_outrec_cc(struct sscop *sscop, struct sscop_msg *unused __unused) 2895121326Sharti{ 2896121326Sharti if(sscop->vt_cc >= sscop->maxcc) { 2897121326Sharti MAAL_ERROR(sscop, 'O', 0); 2898121326Sharti FREE_UU(uu_end); 2899121326Sharti send_end(sscop, 1, NULL); 2900121326Sharti AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1); 2901121326Sharti MSGQ_CLEAR(&sscop->rbuf); 2902121326Sharti sscop_set_state(sscop, SSCOP_IDLE); 2903121326Sharti } else { 2904121326Sharti sscop->vt_cc++; 2905121326Sharti send_er(sscop); 2906121326Sharti TIMER_RESTART(sscop, cc); 2907121326Sharti } 2908121326Sharti} 2909121326Sharti 2910121326Sharti/* 2911121326Sharti * p 50: OUT_REC_PEND && SSCOP_RELEASE_request 2912121326Sharti * arg is UU 2913121326Sharti */ 2914121326Shartistatic void 2915121326Shartisscop_outrec_release_req(struct sscop *sscop, struct sscop_msg *uu) 2916121326Sharti{ 2917121326Sharti SET_UU(uu_end, uu); 2918121326Sharti 2919121326Sharti TIMER_STOP(sscop, cc); 2920121326Sharti sscop->vt_cc = 1; 2921121326Sharti send_end(sscop, 0, sscop->uu_end); 2922121326Sharti MSGQ_CLEAR(&sscop->rbuf); 2923121326Sharti TIMER_RESTART(sscop, cc); 2924121326Sharti 2925121326Sharti sscop_set_state(sscop, SSCOP_OUT_DIS_PEND); 2926121326Sharti} 2927121326Sharti 2928121326Sharti/* 2929121326Sharti * p 51: OUT_REC_PEND && AA-RESYNC.request 2930121326Sharti * arg is uu 2931121326Sharti */ 2932121326Shartistatic void 2933121326Shartisscop_outrec_sync_req(struct sscop *sscop, struct sscop_msg *uu) 2934121326Sharti{ 2935121326Sharti SET_UU(uu_rs, uu); 2936121326Sharti 2937121326Sharti TIMER_STOP(sscop, cc); 2938121326Sharti sscop->vt_cc = 1; 2939121326Sharti sscop->vt_sq++; 2940121326Sharti m_initialize_mr(sscop); 2941121326Sharti send_rs(sscop, 0, sscop->uu_rs); 2942121326Sharti m_clear_transmitter(sscop); 2943121326Sharti MSGQ_CLEAR(&sscop->rbuf); 2944121326Sharti TIMER_RESTART(sscop, cc); 2945121326Sharti} 2946121326Sharti 2947121326Sharti/* 2948121326Sharti * p 51: OUT_REC_PEND && BGN PDU 2949121326Sharti * arg is pdu (freed). 2950121326Sharti * no uui 2951121326Sharti */ 2952121326Shartistatic void 2953121326Shartisscop_outrec_bgn(struct sscop *sscop, struct sscop_msg *msg) 2954121326Sharti{ 2955121326Sharti union pdu pdu; 2956121326Sharti 2957121326Sharti pdu.sscop_null = MBUF_STRIP32(msg->m); 2958121326Sharti 2959121326Sharti if(m_detect_retransmission(sscop, msg)) { 2960121326Sharti MAAL_ERROR(sscop, 'B', 0); 2961121326Sharti SSCOP_MSG_FREE(msg); 2962121326Sharti } else { 2963121326Sharti (void)MBUF_STRIP32(msg->m); 2964121326Sharti 2965121326Sharti TIMER_STOP(sscop, cc); 2966121326Sharti sscop->vt_ms = pdu.sscop_ns; 2967121326Sharti AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 0); 2968121326Sharti AAL_UU_SIGNAL(sscop, SSCOP_ESTABLISH_indication, 2969121326Sharti msg, pdu.sscop_pl, 0); 2970121326Sharti MSGQ_CLEAR(&sscop->rbuf); 2971121326Sharti 2972121326Sharti sscop_set_state(sscop, SSCOP_IN_PEND); 2973121326Sharti } 2974121326Sharti} 2975121326Sharti 2976121326Sharti/* 2977121326Sharti * p 51: OUT_REC_PEND && ER PDU 2978121326Sharti * arg is pdu (freed). 2979121326Sharti */ 2980121326Shartistatic void 2981121326Shartisscop_outrec_er(struct sscop *sscop, struct sscop_msg *msg) 2982121326Sharti{ 2983121326Sharti union pdu pdu; 2984121326Sharti 2985121326Sharti pdu.sscop_null = MBUF_STRIP32(msg->m); 2986121326Sharti 2987121326Sharti if(m_detect_retransmission(sscop, msg)) { 2988121326Sharti MAAL_ERROR(sscop, 'L', 0); 2989121326Sharti } else { 2990121326Sharti TIMER_STOP(sscop, cc); 2991121326Sharti sscop->vt_ms = pdu.sscop_ns; 2992121326Sharti m_initialize_mr(sscop); 2993121326Sharti send_erak(sscop); 2994121326Sharti m_deliver_data(sscop); 2995121326Sharti 2996121326Sharti AAL_SIG(sscop, SSCOP_RECOVER_indication); 2997121326Sharti 2998121326Sharti sscop_set_state(sscop, SSCOP_REC_PEND); 2999121326Sharti } 3000121326Sharti 3001121326Sharti SSCOP_MSG_FREE(msg); 3002121326Sharti} 3003121326Sharti 3004121326Sharti/* 3005121326Sharti * p 52: OUT_REC_PEND && SD PDU queued 3006121326Sharti * no arg. 3007121326Sharti */ 3008121326Shartistatic void 3009121326Shartisscop_outrec_pduq(struct sscop *sscop, struct sscop_msg *msg) 3010121326Sharti{ 3011121326Sharti sscop_save_signal(sscop, SIG_PDU_Q, msg); 3012121326Sharti} 3013121326Sharti 3014121326Sharti/* 3015121326Sharti * p 52: OUT_REC_PEND && RSAK PDU 3016121326Sharti * arg is pdu (freed). 3017121326Sharti */ 3018121326Shartistatic void 3019121326Shartisscop_outrec_rsak(struct sscop *sscop, struct sscop_msg *msg) 3020121326Sharti{ 3021121326Sharti SSCOP_MSG_FREE(msg); 3022121326Sharti MAAL_ERROR(sscop, 'K', 0); 3023121326Sharti} 3024121326Sharti 3025121326Sharti/* 3026121326Sharti * p 52: OUT_REC_PEND && RS PDU 3027121326Sharti * arg is pdu (freed). 3028121326Sharti */ 3029121326Shartistatic void 3030121326Shartisscop_outrec_rs(struct sscop *sscop, struct sscop_msg *msg) 3031121326Sharti{ 3032121326Sharti union pdu pdu; 3033121326Sharti 3034121326Sharti pdu.sscop_null = MBUF_STRIP32(msg->m); 3035121326Sharti 3036121326Sharti if(m_detect_retransmission(sscop, msg)) { 3037121326Sharti SSCOP_MSG_FREE(msg); 3038121326Sharti MAAL_ERROR(sscop, 'J', 0); 3039121326Sharti return; 3040121326Sharti } 3041121326Sharti (void)MBUF_STRIP32(msg->m); 3042121326Sharti 3043121326Sharti TIMER_STOP(sscop, cc); 3044121326Sharti sscop->vt_ms = pdu.sscop_ns; 3045121326Sharti AAL_UU_SIGNAL(sscop, SSCOP_RESYNC_indication, msg, pdu.sscop_pl, 0); 3046121326Sharti MSGQ_CLEAR(&sscop->rbuf); 3047121326Sharti sscop_set_state(sscop, SSCOP_IN_RESYNC_PEND); 3048121326Sharti} 3049121326Sharti 3050121326Sharti/* 3051121326Sharti * p 53: REC_PEND && BGAK PDU 3052121326Sharti * arg is pdu (freed) 3053121326Sharti */ 3054121326Shartistatic void 3055121326Shartisscop_rec_bgak(struct sscop *sscop, struct sscop_msg *msg) 3056121326Sharti{ 3057121326Sharti MAAL_ERROR(sscop, 'C', 0); 3058121326Sharti 3059121326Sharti SSCOP_MSG_FREE(msg); 3060121326Sharti} 3061121326Sharti 3062121326Sharti/* 3063121326Sharti * p 53: REC_PEND && END PDU 3064121326Sharti * arg is pdu (freed) 3065121326Sharti * no uui 3066121326Sharti */ 3067121326Shartistatic void 3068121326Shartisscop_rec_end(struct sscop *sscop, struct sscop_msg *msg) 3069121326Sharti{ 3070121326Sharti union pdu pdu; 3071121326Sharti 3072121326Sharti pdu.sscop_null = MBUF_STRIP32(msg->m); 3073121326Sharti (void)MBUF_STRIP32(msg->m); 3074121326Sharti 3075121326Sharti send_endak(sscop); 3076121326Sharti AAL_UU_SIGNAL(sscop, SSCOP_RELEASE_indication, 3077121326Sharti msg, pdu.sscop_pl, (u_int)pdu.sscop_s); 3078121326Sharti 3079121326Sharti sscop_set_state(sscop, SSCOP_IDLE); 3080121326Sharti} 3081121326Sharti 3082121326Sharti/* 3083121326Sharti * p 53: REC_PEND && ENDAK PDU 3084121326Sharti * arg is pdu (freed) 3085121326Sharti */ 3086121326Shartistatic void 3087121326Shartisscop_rec_endak(struct sscop *sscop, struct sscop_msg *msg) 3088121326Sharti{ 3089121326Sharti MAAL_ERROR(sscop, 'F', 0); 3090121326Sharti AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1); 3091121326Sharti sscop_set_state(sscop, SSCOP_IDLE); 3092121326Sharti SSCOP_MSG_FREE(msg); 3093121326Sharti} 3094121326Sharti 3095121326Sharti/* 3096121326Sharti * p 53: REC_PEND && BGREJ PDU 3097121326Sharti * arg is pdu (freed) 3098121326Sharti */ 3099121326Shartistatic void 3100121326Shartisscop_rec_bgrej(struct sscop *sscop, struct sscop_msg *msg) 3101121326Sharti{ 3102121326Sharti MAAL_ERROR(sscop, 'D', 0); 3103121326Sharti AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1); 3104121326Sharti sscop_set_state(sscop, SSCOP_IDLE); 3105121326Sharti SSCOP_MSG_FREE(msg); 3106121326Sharti} 3107121326Sharti 3108121326Sharti/* 3109121326Sharti * p 54: REC_PEND && RELEASE 3110121326Sharti * arg is UU 3111121326Sharti */ 3112121326Shartistatic void 3113121326Shartisscop_rec_release_req(struct sscop *sscop, struct sscop_msg *uu) 3114121326Sharti{ 3115121326Sharti SET_UU(uu_end, uu); 3116121326Sharti 3117121326Sharti sscop->vt_cc = 1; 3118121326Sharti send_end(sscop, 0, sscop->uu_end); 3119121326Sharti TIMER_RESTART(sscop, cc); 3120121326Sharti 3121121326Sharti sscop_set_state(sscop, SSCOP_OUT_DIS_PEND); 3122121326Sharti} 3123121326Sharti 3124121326Sharti/* 3125121326Sharti * p 54: REC_PEND && RSAK PDU 3126121326Sharti * arg is pdu (freed). 3127121326Sharti */ 3128121326Shartistatic void 3129121326Shartisscop_rec_rsak(struct sscop *sscop, struct sscop_msg *msg) 3130121326Sharti{ 3131121326Sharti MAAL_ERROR(sscop, 'K', 0); 3132121326Sharti SSCOP_MSG_FREE(msg); 3133121326Sharti} 3134121326Sharti 3135121326Sharti 3136121326Sharti/* 3137121326Sharti * p 54: REC_PEND && RS PDU 3138121326Sharti * arg is pdu (freed). 3139121326Sharti */ 3140121326Shartistatic void 3141121326Shartisscop_rec_rs(struct sscop *sscop, struct sscop_msg *msg) 3142121326Sharti{ 3143121326Sharti union pdu pdu; 3144121326Sharti 3145121326Sharti pdu.sscop_null = MBUF_STRIP32(msg->m); 3146121326Sharti 3147121326Sharti if(m_detect_retransmission(sscop, msg)) { 3148121326Sharti SSCOP_MSG_FREE(msg); 3149121326Sharti MAAL_ERROR(sscop, 'J', 0); 3150121326Sharti return; 3151121326Sharti } 3152121326Sharti (void)MBUF_STRIP32(msg->m); 3153121326Sharti 3154121326Sharti sscop->vt_ms = pdu.sscop_ns; 3155121326Sharti AAL_UU_SIGNAL(sscop, SSCOP_RESYNC_indication, msg, pdu.sscop_pl, 0); 3156121326Sharti 3157121326Sharti sscop_set_state(sscop, SSCOP_IN_RESYNC_PEND); 3158121326Sharti} 3159121326Sharti 3160121326Sharti/* 3161121326Sharti * p 54: REC_PEND && RECOVER response 3162121326Sharti * no arg 3163121326Sharti */ 3164121326Shartistatic void 3165121326Shartisscop_rec_recover(struct sscop *sscop, struct sscop_msg *unused __unused) 3166121326Sharti{ 3167121326Sharti if(!sscop->clear_buffers) { 3168121326Sharti MSGQ_CLEAR(&sscop->xbuf); 3169121326Sharti } 3170121326Sharti m_initialize_state(sscop); 3171121326Sharti m_set_data_xfer_timers(sscop); 3172121326Sharti 3173121326Sharti sscop_set_state(sscop, SSCOP_READY); 3174121326Sharti} 3175121326Sharti 3176121326Sharti/* 3177121326Sharti * p 54: REC_PEND && RESYNC request 3178121326Sharti * arg is uu 3179121326Sharti */ 3180121326Shartistatic void 3181121326Shartisscop_rec_sync_req(struct sscop *sscop, struct sscop_msg *uu) 3182121326Sharti{ 3183121326Sharti SET_UU(uu_rs, uu); 3184121326Sharti 3185121326Sharti m_clear_transmitter(sscop); 3186121326Sharti sscop->vt_cc = 1; 3187121326Sharti sscop->vt_sq++; 3188121326Sharti m_initialize_mr(sscop); 3189121326Sharti send_rs(sscop, 0, sscop->uu_rs); 3190121326Sharti TIMER_RESTART(sscop, cc); 3191121326Sharti 3192121326Sharti sscop_set_state(sscop, SSCOP_OUT_RESYNC_PEND); 3193121326Sharti} 3194121326Sharti 3195121326Sharti/* 3196121326Sharti * p 55: REC_PEND && SD PDU queued 3197121326Sharti * no arg 3198121326Sharti */ 3199121326Shartistatic void 3200121326Shartisscop_rec_pduq(struct sscop *sscop, struct sscop_msg *msg) 3201121326Sharti{ 3202121326Sharti sscop_save_signal(sscop, SIG_PDU_Q, msg); 3203121326Sharti} 3204121326Sharti 3205121326Sharti/* 3206121326Sharti * p 55: REC_PEND && ER PDU 3207121326Sharti * arg is pdu (freed). 3208121326Sharti */ 3209121326Shartistatic void 3210121326Shartisscop_rec_er(struct sscop *sscop, struct sscop_msg *msg) 3211121326Sharti{ 3212121326Sharti union pdu pdu; 3213121326Sharti 3214121326Sharti pdu.sscop_null = MBUF_STRIP32(msg->m); 3215121326Sharti 3216121326Sharti if(m_detect_retransmission(sscop, msg)) { 3217121326Sharti send_erak(sscop); 3218121326Sharti } else { 3219121326Sharti MAAL_ERROR(sscop, 'L', 0); 3220121326Sharti } 3221121326Sharti SSCOP_MSG_FREE(msg); 3222121326Sharti} 3223121326Sharti 3224121326Sharti/* 3225121326Sharti * p 55: REC_PEND && BGN PDU 3226121326Sharti * arg is pdu (freed) 3227121326Sharti * no uui 3228121326Sharti */ 3229121326Shartistatic void 3230121326Shartisscop_rec_bgn(struct sscop *sscop, struct sscop_msg *msg) 3231121326Sharti{ 3232121326Sharti union pdu pdu; 3233121326Sharti 3234121326Sharti pdu.sscop_null = MBUF_STRIP32(msg->m); 3235121326Sharti 3236121326Sharti if(m_detect_retransmission(sscop, msg)) { 3237121326Sharti MAAL_ERROR(sscop, 'B', 0); 3238121326Sharti SSCOP_MSG_FREE(msg); 3239121326Sharti return; 3240121326Sharti } 3241121326Sharti (void)MBUF_STRIP32(msg->m); 3242121326Sharti 3243121326Sharti sscop->vt_ms = pdu.sscop_ns; 3244121326Sharti AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 0); 3245121326Sharti AAL_UU_SIGNAL(sscop, SSCOP_ESTABLISH_indication, msg, pdu.sscop_pl, 0); 3246121326Sharti 3247121326Sharti sscop_set_state(sscop, SSCOP_IN_PEND); 3248121326Sharti} 3249121326Sharti 3250121326Sharti/* 3251121326Sharti * p 55: REC_PEND && STAT PDU 3252121326Sharti * arg is pdu (freed) 3253121326Sharti */ 3254121326Shartistatic void 3255121326Shartisscop_rec_stat(struct sscop *sscop, struct sscop_msg *msg) 3256121326Sharti{ 3257121326Sharti MAAL_ERROR(sscop, 'H', 0); 3258121326Sharti FREE_UU(uu_end); 3259121326Sharti send_end(sscop, 1, NULL); 3260121326Sharti AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1); 3261121326Sharti sscop_set_state(sscop, SSCOP_IDLE); 3262121326Sharti SSCOP_MSG_FREE(msg); 3263121326Sharti} 3264121326Sharti 3265121326Sharti/* 3266121326Sharti * p 55: REC_PEND && USTAT PDU 3267121326Sharti * arg is pdu (freed) 3268121326Sharti */ 3269121326Shartistatic void 3270121326Shartisscop_rec_ustat(struct sscop *sscop, struct sscop_msg *msg) 3271121326Sharti{ 3272121326Sharti MAAL_ERROR(sscop, 'I', 0); 3273121326Sharti FREE_UU(uu_end); 3274121326Sharti send_end(sscop, 1, NULL); 3275121326Sharti AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1); 3276121326Sharti sscop_set_state(sscop, SSCOP_IDLE); 3277121326Sharti SSCOP_MSG_FREE(msg); 3278121326Sharti} 3279121326Sharti 3280121326Sharti/* 3281121326Sharti * p 56: IN_REC_PEND && AA-RECOVER.response 3282121326Sharti * no arg 3283121326Sharti */ 3284121326Shartistatic void 3285121326Shartisscop_inrec_recover(struct sscop *sscop, struct sscop_msg *unused __unused) 3286121326Sharti{ 3287121326Sharti if(!sscop->clear_buffers) { 3288121326Sharti MSGQ_CLEAR(&sscop->xbuf); 3289121326Sharti } 3290121326Sharti m_initialize_mr(sscop); 3291121326Sharti send_erak(sscop); 3292121326Sharti m_initialize_state(sscop); 3293121326Sharti m_set_data_xfer_timers(sscop); 3294121326Sharti 3295121326Sharti sscop_set_state(sscop, SSCOP_READY); 3296121326Sharti} 3297121326Sharti 3298121326Sharti/* 3299121326Sharti * p 56: IN_REC_PEND && SD PDU queued 3300121326Sharti * no arg 3301121326Sharti */ 3302121326Shartistatic void 3303121326Shartisscop_inrec_pduq(struct sscop *sscop, struct sscop_msg *msg) 3304121326Sharti{ 3305121326Sharti sscop_save_signal(sscop, SIG_PDU_Q, msg); 3306121326Sharti} 3307121326Sharti 3308121326Sharti/* 3309121326Sharti * p 56: IN_REC_PEND && AA-RELEASE.request 3310121326Sharti * arg is UU 3311121326Sharti */ 3312121326Shartistatic void 3313121326Shartisscop_inrec_release_req(struct sscop *sscop, struct sscop_msg *uu) 3314121326Sharti{ 3315121326Sharti SET_UU(uu_end, uu); 3316121326Sharti 3317121326Sharti sscop->vt_cc = 1; 3318121326Sharti send_end(sscop, 0, sscop->uu_end); 3319121326Sharti TIMER_RESTART(sscop, cc); 3320121326Sharti 3321121326Sharti sscop_set_state(sscop, SSCOP_OUT_DIS_PEND); 3322121326Sharti} 3323121326Sharti 3324121326Sharti/* 3325121326Sharti * p 56: IN_REC_PEND && END PDU 3326121326Sharti * arg is pdu (freed). 3327121326Sharti * no uui 3328121326Sharti */ 3329121326Shartistatic void 3330121326Shartisscop_inrec_end(struct sscop *sscop, struct sscop_msg *msg) 3331121326Sharti{ 3332121326Sharti union pdu pdu; 3333121326Sharti 3334121326Sharti pdu.sscop_null = MBUF_STRIP32(msg->m); 3335121326Sharti (void)MBUF_STRIP32(msg->m); 3336121326Sharti 3337121326Sharti send_endak(sscop); 3338121326Sharti AAL_UU_SIGNAL(sscop, SSCOP_RELEASE_indication, 3339121326Sharti msg, pdu.sscop_pl, (u_int)pdu.sscop_s); 3340121326Sharti 3341121326Sharti sscop_set_state(sscop, SSCOP_IDLE); 3342121326Sharti} 3343121326Sharti 3344121326Sharti/* 3345121326Sharti * p 56: IN_REC_PEND && RESYNC_REQ 3346121326Sharti */ 3347121326Shartistatic void 3348121326Shartisscop_inrec_sync_req(struct sscop *sscop, struct sscop_msg *uu) 3349121326Sharti{ 3350121326Sharti SET_UU(uu_rs, uu); 3351121326Sharti 3352121326Sharti m_clear_transmitter(sscop); 3353121326Sharti sscop->vt_cc = 1; 3354121326Sharti sscop->vt_sq++; 3355121326Sharti m_initialize_mr(sscop); 3356121326Sharti send_rs(sscop, 0, sscop->uu_rs); 3357121326Sharti TIMER_RESTART(sscop, cc); 3358121326Sharti 3359121326Sharti sscop_set_state(sscop, SSCOP_OUT_RESYNC_PEND); 3360121326Sharti} 3361121326Sharti 3362121326Sharti 3363121326Sharti/* 3364121326Sharti * p 57: IN_REC_PEND && ENDAK PDU 3365121326Sharti * arg is pdu (freed) 3366121326Sharti */ 3367121326Shartistatic void 3368121326Shartisscop_inrec_endak(struct sscop *sscop, struct sscop_msg *msg) 3369121326Sharti{ 3370121326Sharti MAAL_ERROR(sscop, 'F', 0); 3371121326Sharti AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1); 3372121326Sharti SSCOP_MSG_FREE(msg); 3373121326Sharti sscop_set_state(sscop, SSCOP_IDLE); 3374121326Sharti} 3375121326Sharti 3376121326Sharti/* 3377121326Sharti * p 57: IN_REC_PEND && BGREJ PDU 3378121326Sharti * arg is pdu (freed) 3379121326Sharti */ 3380121326Shartistatic void 3381121326Shartisscop_inrec_bgrej(struct sscop *sscop, struct sscop_msg *msg) 3382121326Sharti{ 3383121326Sharti MAAL_ERROR(sscop, 'D', 0); 3384121326Sharti AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1); 3385121326Sharti SSCOP_MSG_FREE(msg); 3386121326Sharti sscop_set_state(sscop, SSCOP_IDLE); 3387121326Sharti} 3388121326Sharti 3389121326Sharti/* 3390121326Sharti * p 57: IN_REC_PEND && USTAT PDU 3391121326Sharti * arg is pdu (freed) 3392121326Sharti */ 3393121326Shartistatic void 3394121326Shartisscop_inrec_ustat(struct sscop *sscop, struct sscop_msg *msg) 3395121326Sharti{ 3396121326Sharti MAAL_ERROR(sscop, 'I', 0); 3397121326Sharti FREE_UU(uu_end); 3398121326Sharti send_end(sscop, 1, NULL); 3399121326Sharti AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1); 3400121326Sharti SSCOP_MSG_FREE(msg); 3401121326Sharti sscop_set_state(sscop, SSCOP_IDLE); 3402121326Sharti} 3403121326Sharti 3404121326Sharti/* 3405121326Sharti * p 57: IN_REC_PEND && STAT PDU 3406121326Sharti * arg is pdu (freed) 3407121326Sharti */ 3408121326Shartistatic void 3409121326Shartisscop_inrec_stat(struct sscop *sscop, struct sscop_msg *msg) 3410121326Sharti{ 3411121326Sharti MAAL_ERROR(sscop, 'H', 0); 3412121326Sharti FREE_UU(uu_end); 3413121326Sharti send_end(sscop, 1, NULL); 3414121326Sharti AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1); 3415121326Sharti SSCOP_MSG_FREE(msg); 3416121326Sharti sscop_set_state(sscop, SSCOP_IDLE); 3417121326Sharti} 3418121326Sharti 3419121326Sharti/* 3420121326Sharti * p 57: IN_REC_PEND && POLL PDU 3421121326Sharti * arg is pdu (freed) 3422121326Sharti */ 3423121326Shartistatic void 3424121326Shartisscop_inrec_poll(struct sscop *sscop, struct sscop_msg *msg) 3425121326Sharti{ 3426121326Sharti MAAL_ERROR(sscop, 'G', 0); 3427121326Sharti FREE_UU(uu_end); 3428121326Sharti send_end(sscop, 1, NULL); 3429121326Sharti AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1); 3430121326Sharti SSCOP_MSG_FREE(msg); 3431121326Sharti sscop_set_state(sscop, SSCOP_IDLE); 3432121326Sharti} 3433121326Sharti 3434121326Sharti/* 3435121326Sharti * p 57: IN_REC_PEND && SD PDU 3436121326Sharti * arg is pdu (freed) 3437121326Sharti */ 3438121326Shartistatic void 3439121326Shartisscop_inrec_sd(struct sscop *sscop, struct sscop_msg *msg) 3440121326Sharti{ 3441121326Sharti MAAL_ERROR(sscop, 'A', 0); 3442121326Sharti FREE_UU(uu_end); 3443121326Sharti send_end(sscop, 1, NULL); 3444121326Sharti AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1); 3445121326Sharti SSCOP_MSG_FREE(msg); 3446121326Sharti sscop_set_state(sscop, SSCOP_IDLE); 3447121326Sharti} 3448121326Sharti 3449121326Sharti/* 3450121326Sharti * p 58: IN_REC_PEND && RSAK PDU 3451121326Sharti * arg is pdu (freed). 3452121326Sharti */ 3453121326Shartistatic void 3454121326Shartisscop_inrec_rsak(struct sscop *sscop, struct sscop_msg *msg) 3455121326Sharti{ 3456121326Sharti SSCOP_MSG_FREE(msg); 3457121326Sharti MAAL_ERROR(sscop, 'K', 0); 3458121326Sharti} 3459121326Sharti 3460121326Sharti/* 3461121326Sharti * p 58: IN_REC_PEND && RS PDU 3462121326Sharti * arg is pdu (freed). 3463121326Sharti */ 3464121326Shartistatic void 3465121326Shartisscop_inrec_rs(struct sscop *sscop, struct sscop_msg *msg) 3466121326Sharti{ 3467121326Sharti union pdu pdu; 3468121326Sharti 3469121326Sharti pdu.sscop_null = MBUF_STRIP32(msg->m); 3470121326Sharti 3471121326Sharti if(m_detect_retransmission(sscop, msg)) { 3472121326Sharti SSCOP_MSG_FREE(msg); 3473121326Sharti MAAL_ERROR(sscop, 'J', 0); 3474121326Sharti return; 3475121326Sharti } 3476121326Sharti (void)MBUF_STRIP32(msg->m); 3477121326Sharti 3478121326Sharti sscop->vt_ms = pdu.sscop_ns; 3479121326Sharti AAL_UU_SIGNAL(sscop, SSCOP_RESYNC_indication, msg, pdu.sscop_pl, 0); 3480121326Sharti 3481121326Sharti sscop_set_state(sscop, SSCOP_IN_RESYNC_PEND); 3482121326Sharti} 3483121326Sharti 3484121326Sharti/* 3485121326Sharti * p 59: IN_REC_PEND && ER PDU 3486121326Sharti * arg is pdu (freed) 3487121326Sharti */ 3488121326Shartistatic void 3489121326Shartisscop_inrec_er(struct sscop *sscop, struct sscop_msg *msg) 3490121326Sharti{ 3491121326Sharti union pdu pdu; 3492121326Sharti 3493121326Sharti pdu.sscop_null = MBUF_STRIP32(msg->m); 3494121326Sharti 3495121326Sharti if(!m_detect_retransmission(sscop, msg)) { 3496121326Sharti MAAL_ERROR(sscop, 'L', 0); 3497121326Sharti } 3498121326Sharti 3499121326Sharti SSCOP_MSG_FREE(msg); 3500121326Sharti} 3501121326Sharti 3502121326Sharti/* 3503121326Sharti * p 59: IN_REC_PEND && BGN PDU 3504121326Sharti * arg is pdu (freed). 3505121326Sharti * no uui 3506121326Sharti */ 3507121326Shartistatic void 3508121326Shartisscop_inrec_bgn(struct sscop *sscop, struct sscop_msg *msg) 3509121326Sharti{ 3510121326Sharti union pdu pdu; 3511121326Sharti 3512121326Sharti pdu.sscop_null = MBUF_STRIP32(msg->m); 3513121326Sharti 3514121326Sharti if(m_detect_retransmission(sscop, msg)) { 3515121326Sharti MAAL_ERROR(sscop, 'B', 0); 3516121326Sharti SSCOP_MSG_FREE(msg); 3517121326Sharti return; 3518121326Sharti } 3519121326Sharti (void)MBUF_STRIP32(msg->m); 3520121326Sharti 3521121326Sharti sscop->vt_ms = pdu.sscop_ns; 3522121326Sharti AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 0); 3523121326Sharti AAL_UU_SIGNAL(sscop, SSCOP_ESTABLISH_indication, msg, pdu.sscop_pl, 0); 3524121326Sharti 3525121326Sharti sscop_set_state(sscop, SSCOP_IN_PEND); 3526121326Sharti} 3527121326Sharti 3528121326Sharti/* 3529121326Sharti * p 59: IN_REC_PEND && BGAK PDU 3530121326Sharti * arg is pdu (freed) 3531121326Sharti * no uui 3532121326Sharti */ 3533121326Shartistatic void 3534121326Shartisscop_inrec_bgak(struct sscop *sscop, struct sscop_msg *msg) 3535121326Sharti{ 3536121326Sharti MAAL_ERROR(sscop, 'C', 0); 3537121326Sharti SSCOP_MSG_FREE(msg); 3538121326Sharti} 3539121326Sharti 3540121326Sharti/* 3541121326Sharti * p 59: IN_REC_PEND && ERAK PDU 3542121326Sharti * arg is pdu (freed) 3543121326Sharti * no uui 3544121326Sharti */ 3545121326Shartistatic void 3546121326Shartisscop_inrec_erak(struct sscop *sscop, struct sscop_msg *msg) 3547121326Sharti{ 3548121326Sharti MAAL_ERROR(sscop, 'M', 0); 3549121326Sharti SSCOP_MSG_FREE(msg); 3550121326Sharti} 3551121326Sharti 3552121326Sharti/* 3553121326Sharti * p 60: READY && RESYNC request 3554121326Sharti * arg is UU 3555121326Sharti */ 3556121326Shartistatic void 3557121326Shartisscop_ready_sync_req(struct sscop *sscop, struct sscop_msg *uu) 3558121326Sharti{ 3559121326Sharti SET_UU(uu_rs, uu); 3560121326Sharti 3561121326Sharti m_reset_data_xfer_timers(sscop); 3562121326Sharti sscop->vt_cc = 1; 3563121326Sharti sscop->vt_sq++; 3564121326Sharti m_initialize_mr(sscop); 3565121326Sharti send_rs(sscop, 0, sscop->uu_rs); 3566121326Sharti m_release_buffers(sscop); 3567121326Sharti TIMER_RESTART(sscop, cc); 3568121326Sharti 3569121326Sharti sscop_set_state(sscop, SSCOP_OUT_RESYNC_PEND); 3570121326Sharti} 3571121326Sharti 3572121326Sharti 3573121326Sharti/* 3574121326Sharti * p 60: READY && AA-RELEASE.request 3575121326Sharti * arg is uu. 3576121326Sharti */ 3577121326Shartistatic void 3578121326Shartisscop_ready_release_req(struct sscop *sscop, struct sscop_msg *uu) 3579121326Sharti{ 3580121326Sharti SET_UU(uu_end, uu); 3581121326Sharti 3582121326Sharti m_reset_data_xfer_timers(sscop); 3583121326Sharti sscop->vt_cc = 1; 3584121326Sharti send_end(sscop, 0, sscop->uu_end); 3585121326Sharti m_prepare_retrieval(sscop); 3586121326Sharti TIMER_RESTART(sscop, cc); 3587121326Sharti 3588121326Sharti sscop_set_state(sscop, SSCOP_OUT_DIS_PEND); 3589121326Sharti} 3590121326Sharti 3591121326Sharti/* 3592121326Sharti * p 61: READY && ER PDU 3593121326Sharti * arg is pdu (freed). 3594121326Sharti */ 3595121326Shartistatic void 3596121326Shartisscop_ready_er(struct sscop *sscop, struct sscop_msg *msg) 3597121326Sharti{ 3598121326Sharti union pdu pdu; 3599121326Sharti 3600121326Sharti pdu.sscop_null = MBUF_STRIP32(msg->m); 3601121326Sharti 3602121326Sharti if(m_detect_retransmission(sscop, msg)) { 3603121326Sharti TIMER_RESTART(sscop, nr); 3604121326Sharti send_erak(sscop); 3605121326Sharti } else { 3606121326Sharti m_reset_data_xfer_timers(sscop); 3607121326Sharti sscop->vt_ms = pdu.sscop_ns; 3608121326Sharti m_prepare_recovery(sscop); 3609121326Sharti m_deliver_data(sscop); 3610121326Sharti 3611121326Sharti AAL_SIG(sscop, SSCOP_RECOVER_indication); 3612121326Sharti 3613121326Sharti sscop_set_state(sscop, SSCOP_IN_REC_PEND); 3614121326Sharti } 3615121326Sharti 3616121326Sharti SSCOP_MSG_FREE(msg); 3617121326Sharti} 3618121326Sharti 3619121326Sharti/* 3620121326Sharti * p 61: READY && BGN PDU 3621121326Sharti * arg is pdu (freed) 3622121326Sharti */ 3623121326Shartistatic void 3624121326Shartisscop_ready_bgn(struct sscop *sscop, struct sscop_msg *msg) 3625121326Sharti{ 3626121326Sharti union pdu pdu; 3627121326Sharti 3628121326Sharti pdu.sscop_null = MBUF_STRIP32(msg->m); 3629121326Sharti 3630121326Sharti if(m_detect_retransmission(sscop, msg)) { 3631121326Sharti TIMER_RESTART(sscop, nr); 3632121326Sharti send_bgak(sscop, sscop->uu_bgak); 3633121326Sharti SSCOP_MSG_FREE(msg); 3634121326Sharti return; 3635121326Sharti } 3636121326Sharti (void)MBUF_STRIP32(msg->m); 3637121326Sharti 3638121326Sharti m_reset_data_xfer_timers(sscop); 3639121326Sharti sscop->vt_ms = pdu.sscop_ns; 3640121326Sharti 3641121326Sharti AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 0); 3642121326Sharti AAL_UU_SIGNAL(sscop, SSCOP_ESTABLISH_indication, msg, pdu.sscop_pl, 0); 3643121326Sharti 3644121326Sharti m_prepare_retrieval(sscop); 3645121326Sharti 3646121326Sharti sscop_set_state(sscop, SSCOP_IN_PEND); 3647121326Sharti} 3648121326Sharti 3649121326Sharti/* 3650121326Sharti * p 62: READY && ENDAK PDU 3651121326Sharti * arg is pdu (freed) 3652121326Sharti */ 3653121326Shartistatic void 3654121326Shartisscop_ready_endak(struct sscop *sscop, struct sscop_msg *msg) 3655121326Sharti{ 3656121326Sharti m_reset_data_xfer_timers(sscop); 3657121326Sharti MAAL_ERROR(sscop, 'F', 0); 3658121326Sharti AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1); 3659121326Sharti m_prepare_retrieval(sscop); 3660121326Sharti SSCOP_MSG_FREE(msg); 3661121326Sharti sscop_set_state(sscop, SSCOP_IDLE); 3662121326Sharti} 3663121326Sharti 3664121326Sharti/* 3665121326Sharti * p 62: READY && BGREJ PDU 3666121326Sharti * arg is pdu (freed) 3667121326Sharti */ 3668121326Shartistatic void 3669121326Shartisscop_ready_bgrej(struct sscop *sscop, struct sscop_msg *msg) 3670121326Sharti{ 3671121326Sharti m_reset_data_xfer_timers(sscop); 3672121326Sharti MAAL_ERROR(sscop, 'D', 0); 3673121326Sharti AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1); 3674121326Sharti m_prepare_retrieval(sscop); 3675121326Sharti SSCOP_MSG_FREE(msg); 3676121326Sharti sscop_set_state(sscop, SSCOP_IDLE); 3677121326Sharti} 3678121326Sharti 3679121326Sharti/* 3680121326Sharti * p 62: READY && RS PDU 3681121326Sharti * arg is pdu (freed) 3682121326Sharti */ 3683121326Shartistatic void 3684121326Shartisscop_ready_rs(struct sscop *sscop, struct sscop_msg *msg) 3685121326Sharti{ 3686121326Sharti union pdu pdu; 3687121326Sharti 3688121326Sharti pdu.sscop_null = MBUF_STRIP32(msg->m); 3689121326Sharti 3690121326Sharti if(m_detect_retransmission(sscop, msg)) { 3691121326Sharti SSCOP_MSG_FREE(msg); 3692121326Sharti TIMER_RESTART(sscop, nr); 3693121326Sharti send_rsak(sscop); 3694121326Sharti return; 3695121326Sharti } 3696121326Sharti (void)MBUF_STRIP32(msg->m); 3697121326Sharti 3698121326Sharti m_reset_data_xfer_timers(sscop); 3699121326Sharti sscop->vt_ms = pdu.sscop_ns; 3700121326Sharti AAL_UU_SIGNAL(sscop, SSCOP_RESYNC_indication, msg, pdu.sscop_pl, 0); 3701121326Sharti m_prepare_retrieval(sscop); 3702121326Sharti 3703121326Sharti sscop_set_state(sscop, SSCOP_IN_RESYNC_PEND); 3704121326Sharti} 3705121326Sharti 3706121326Sharti/* 3707121326Sharti * p 62: READY && END PDU 3708121326Sharti * arg is pdu (freed) 3709121326Sharti */ 3710121326Shartistatic void 3711121326Shartisscop_ready_end(struct sscop *sscop, struct sscop_msg *msg) 3712121326Sharti{ 3713121326Sharti union pdu pdu; 3714121326Sharti 3715121326Sharti pdu.sscop_null = MBUF_STRIP32(msg->m); 3716121326Sharti (void)MBUF_STRIP32(msg->m); 3717121326Sharti 3718121326Sharti m_reset_data_xfer_timers(sscop); 3719121326Sharti send_endak(sscop); 3720121326Sharti AAL_UU_SIGNAL(sscop, SSCOP_RELEASE_indication, 3721121326Sharti msg, pdu.sscop_pl, (u_int)pdu.sscop_s); 3722121326Sharti m_prepare_retrieval(sscop); 3723121326Sharti 3724121326Sharti sscop_set_state(sscop, SSCOP_IDLE); 3725121326Sharti} 3726121326Sharti 3727121326Sharti/* 3728121326Sharti * p 63: READY && POLL expiry 3729121326Sharti */ 3730121326Shartistatic void 3731121326Shartisscop_ready_tpoll(struct sscop *sscop, struct sscop_msg *unused __unused) 3732121326Sharti{ 3733121326Sharti sscop->vt_ps++; 3734121326Sharti send_poll(sscop); 3735121326Sharti sscop->vt_pd = 0; 3736121326Sharti m_set_poll_timer(sscop); 3737121326Sharti} 3738121326Sharti 3739121326Sharti/* 3740121326Sharti * p 63: READY && KEEP_ALIVE expiry 3741121326Sharti */ 3742121326Shartistatic void 3743121326Shartisscop_ready_tka(struct sscop *sscop, struct sscop_msg *unused __unused) 3744121326Sharti{ 3745121326Sharti sscop->vt_ps++; 3746121326Sharti send_poll(sscop); 3747121326Sharti sscop->vt_pd = 0; 3748121326Sharti m_set_poll_timer(sscop); 3749121326Sharti} 3750121326Sharti 3751121326Sharti/* 3752121326Sharti * p 63: READY && IDLE expiry 3753121326Sharti */ 3754121326Shartistatic void 3755121326Shartisscop_ready_tidle(struct sscop *sscop, struct sscop_msg *unused __unused) 3756121326Sharti{ 3757121326Sharti TIMER_RESTART(sscop, nr); 3758121326Sharti sscop->vt_ps++; 3759121326Sharti send_poll(sscop); 3760121326Sharti sscop->vt_pd = 0; 3761121326Sharti m_set_poll_timer(sscop); 3762121326Sharti} 3763121326Sharti 3764121326Sharti/* 3765121326Sharti * p 63: READY && NO_RESPONSE expiry 3766121326Sharti * no arg 3767121326Sharti */ 3768121326Shartistatic void 3769121326Shartisscop_ready_nr(struct sscop *sscop, struct sscop_msg *unused __unused) 3770121326Sharti{ 3771121326Sharti m_reset_data_xfer_timers(sscop); 3772121326Sharti MAAL_ERROR(sscop, 'P', 0); 3773121326Sharti FREE_UU(uu_end); 3774121326Sharti send_end(sscop, 1, NULL); 3775121326Sharti AAL_DATA(sscop, SSCOP_RELEASE_indication, NULL, 1); 3776121326Sharti m_prepare_retrieval(sscop); 3777121326Sharti sscop_set_state(sscop, SSCOP_IDLE); 3778121326Sharti} 3779121326Sharti 3780121326Sharti/* 3781121326Sharti * p 63: READY && AA-DATA.request 3782121326Sharti * arg is message (queued). 3783121326Sharti */ 3784121326Shartistatic void 3785121326Shartisscop_ready_userdata(struct sscop *sscop, struct sscop_msg *msg) 3786121326Sharti{ 3787121326Sharti MSGQ_APPEND(&sscop->xq, msg); 3788121326Sharti 3789121326Sharti sscop_signal(sscop, SIG_PDU_Q, msg); 3790121326Sharti} 3791121326Sharti 3792121326Sharti/* 3793121326Sharti * p 64: READY && SD PDU queued up 3794121326Sharti * arg is unused. 3795121326Sharti */ 3796121326Shartistatic void 3797121326Shartisscop_ready_pduq(struct sscop *sscop, struct sscop_msg *unused __unused) 3798121326Sharti{ 3799121326Sharti struct sscop_msg *msg; 3800121326Sharti 3801121326Sharti if(sscop->rxq != 0) { 3802121326Sharti TAILQ_FOREACH(msg, &sscop->xbuf, link) 3803121326Sharti if(msg->rexmit) 3804121326Sharti break; 3805121326Sharti ASSERT(msg != NULL); 3806121326Sharti msg->rexmit = 0; 3807121326Sharti sscop->rxq--; 3808121326Sharti send_sd(sscop, msg->m, msg->seqno); 3809121326Sharti msg->poll_seqno = sscop->vt_ps; 3810121326Sharti if(sscop->poll_after_rex && sscop->rxq == 0) 3811121326Sharti goto poll; /* -> A */ 3812121326Sharti else 3813121326Sharti goto maybe_poll; /* -> B */ 3814121326Sharti 3815121326Sharti } 3816121326Sharti if(MSGQ_EMPTY(&sscop->xq)) 3817121326Sharti return; 3818121326Sharti 3819121326Sharti if(sscop->vt_s >= sscop->vt_ms) { 3820121326Sharti /* Send windows closed */ 3821121326Sharti TIMER_STOP(sscop, idle); 3822121326Sharti TIMER_RESTART(sscop, nr); 3823121326Sharti goto poll; /* -> A */ 3824121326Sharti 3825121326Sharti } else { 3826121326Sharti msg = MSGQ_GET(&sscop->xq); 3827121326Sharti msg->seqno = sscop->vt_s; 3828121326Sharti send_sd(sscop, msg->m, msg->seqno); 3829121326Sharti msg->poll_seqno = sscop->vt_ps; 3830121326Sharti sscop->vt_s++; 3831121326Sharti MSGQ_APPEND(&sscop->xbuf, msg); 3832121326Sharti goto maybe_poll; /* -> B */ 3833121326Sharti } 3834121326Sharti 3835121326Sharti /* 3836121326Sharti * p 65: Poll handling 3837121326Sharti */ 3838121326Sharti maybe_poll: /* label B */ 3839121326Sharti sscop->vt_pd++; 3840121326Sharti if(TIMER_ISACT(sscop, poll)) { 3841121326Sharti if(sscop->vt_pd < sscop->maxpd) 3842121326Sharti return; 3843121326Sharti } else { 3844121326Sharti if(TIMER_ISACT(sscop, idle)) { 3845121326Sharti TIMER_STOP(sscop, idle); 3846121326Sharti TIMER_RESTART(sscop, nr); 3847121326Sharti } else { 3848121326Sharti TIMER_STOP(sscop, ka); 3849121326Sharti } 3850121326Sharti if(sscop->vt_pd < sscop->maxpd) { 3851121326Sharti TIMER_RESTART(sscop, poll); 3852121326Sharti return; 3853121326Sharti } 3854121326Sharti } 3855121326Sharti poll: /* label A */ 3856121326Sharti sscop->vt_ps++; 3857121326Sharti send_poll(sscop); 3858121326Sharti sscop->vt_pd = 0; 3859121326Sharti TIMER_RESTART(sscop, poll); 3860121326Sharti} 3861121326Sharti 3862121326Sharti/* 3863121326Sharti * p 67: common recovery start 3864121326Sharti */ 3865121326Shartistatic void 3866121326Shartisscop_recover(struct sscop *sscop) 3867121326Sharti{ 3868121326Sharti sscop->vt_cc = 1; 3869121326Sharti sscop->vt_sq++; 3870121326Sharti 3871121326Sharti m_initialize_mr(sscop); 3872121326Sharti send_er(sscop); 3873121326Sharti m_prepare_recovery(sscop); 3874121326Sharti 3875121326Sharti TIMER_RESTART(sscop, cc); 3876121326Sharti 3877121326Sharti sscop_set_state(sscop, SSCOP_OUT_REC_PEND); 3878121326Sharti} 3879121326Sharti 3880121326Sharti/* 3881121326Sharti * p 66: READY && SD PDU 3882121326Sharti * arg is received message. 3883121326Sharti */ 3884121326Shartistatic void 3885121326Shartisscop_ready_sd(struct sscop *sscop, struct sscop_msg *msg) 3886121326Sharti{ 3887121326Sharti union pdu pdu; 3888121326Sharti u_int sn; 3889121326Sharti 3890121326Sharti pdu.sscop_null = MBUF_STRIP32(msg->m); 3891121326Sharti msg->seqno = pdu.sscop_ns; 3892121326Sharti 3893121326Sharti /* Fix padding */ 3894121326Sharti MBUF_UNPAD(msg->m, pdu.sscop_pl); 3895121326Sharti 3896121326Sharti if(msg->seqno >= sscop->vr_mr) { 3897121326Sharti /* message outside window */ 3898121326Sharti if(sscop->vr_h < sscop->vr_mr) { 3899121326Sharti send_ustat(sscop, sscop->vr_h, sscop->vr_mr, -1); 3900121326Sharti sscop->vr_h = sscop->vr_mr; 3901121326Sharti } 3902121326Sharti SSCOP_MSG_FREE(msg); 3903121326Sharti return; 3904121326Sharti } 3905121326Sharti 3906121326Sharti if(msg->seqno == sscop->vr_r) { 3907121326Sharti if(msg->seqno == sscop->vr_h) { 3908121326Sharti sscop->vr_r = msg->seqno + 1; 3909121326Sharti sscop->vr_h = msg->seqno + 1; 3910121326Sharti 3911121326Sharti AAL_DATA(sscop, SSCOP_DATA_indication, 3912121326Sharti msg->m, msg->seqno); 3913121326Sharti msg->m = NULL; 3914121326Sharti SSCOP_MSG_FREE(msg); 3915121326Sharti 3916121326Sharti return; 3917121326Sharti } 3918121326Sharti for(;;) { 3919121326Sharti AAL_DATA(sscop, SSCOP_DATA_indication, 3920121326Sharti msg->m, msg->seqno); 3921121326Sharti msg->m = NULL; 3922121326Sharti SSCOP_MSG_FREE(msg); 3923121326Sharti 3924121326Sharti sscop->vr_r++; 3925121326Sharti if((msg = MSGQ_PEEK(&sscop->rbuf)) == NULL) 3926121326Sharti break; 3927121326Sharti sn = msg->seqno; 3928121326Sharti ASSERT(sn >= sscop->vr_r); 3929121326Sharti if(sn != sscop->vr_r) 3930121326Sharti break; 3931121326Sharti msg = MSGQ_GET(&sscop->rbuf); 3932121326Sharti } 3933121326Sharti return; 3934121326Sharti } 3935121326Sharti 3936121326Sharti /* Messages were lost */ 3937121326Sharti 3938121326Sharti /* XXX Flow control */ 3939121326Sharti if(msg->seqno == sscop->vr_h) { 3940121326Sharti QINSERT(&sscop->rbuf, msg); 3941121326Sharti sscop->vr_h++; 3942121326Sharti return; 3943121326Sharti } 3944121326Sharti if(sscop->vr_h < msg->seqno) { 3945121326Sharti QINSERT(&sscop->rbuf, msg); 3946121326Sharti send_ustat(sscop, sscop->vr_h, msg->seqno, -1); 3947121326Sharti sscop->vr_h = msg->seqno + 1; 3948121326Sharti return; 3949121326Sharti } 3950121326Sharti 3951121326Sharti if(QFIND(&sscop->rbuf, msg->seqno) == NULL) { 3952121326Sharti QINSERT(&sscop->rbuf, msg); 3953121326Sharti return; 3954121326Sharti } 3955121326Sharti 3956121326Sharti /* error: start recovery */ 3957121326Sharti SSCOP_MSG_FREE(msg); 3958121326Sharti m_reset_data_xfer_timers(sscop); 3959121326Sharti MAAL_ERROR(sscop, 'Q', 0); 3960121326Sharti sscop_recover(sscop); 3961121326Sharti} 3962121326Sharti 3963121326Sharti/* 3964121326Sharti * p 67: READY && POLL PDU 3965121326Sharti */ 3966121326Shartistatic void 3967121326Shartisscop_ready_poll(struct sscop *sscop, struct sscop_msg *msg) 3968121326Sharti{ 3969121326Sharti union pdu pdu; 3970121326Sharti union seqno seqno; 3971121326Sharti u_int sn, nps; 3972121326Sharti struct SSCOP_MBUF_T *m; 3973121326Sharti 3974121326Sharti pdu.sscop_null = MBUF_STRIP32(msg->m); 3975121326Sharti seqno.sscop_null = MBUF_STRIP32(msg->m); 3976121326Sharti 3977121326Sharti if((u_int)pdu.sscop_ns < sscop->vr_h) { 3978121326Sharti SSCOP_MSG_FREE(msg); 3979121326Sharti m_reset_data_xfer_timers(sscop); 3980121326Sharti MAAL_ERROR(sscop, 'Q', 0); 3981121326Sharti sscop_recover(sscop); 3982121326Sharti return; 3983121326Sharti } 3984121326Sharti nps = seqno.sscop_n; 3985121326Sharti 3986121326Sharti if((u_int)pdu.sscop_ns > sscop->vr_mr) 3987121326Sharti sscop->vr_h = sscop->vr_mr; 3988121326Sharti else 3989121326Sharti sscop->vr_h = pdu.sscop_ns; 3990121326Sharti 3991121326Sharti SSCOP_MSG_FREE(msg); 3992121326Sharti 3993121326Sharti /* build stat pdu */ 3994121326Sharti if((m = MBUF_ALLOC(sscop->maxstat * 4 + 12)) == NULL) { 3995121326Sharti FAILURE("sscop: cannot allocate STAT"); 3996121326Sharti return; 3997121326Sharti } 3998121326Sharti sn = sscop->vr_r; 3999121326Sharti 4000121326Sharti while(sn != sscop->vr_h) { 4001121326Sharti /* loop through burst we already have */ 4002121326Sharti for(;;) { 4003121326Sharti if(sn >= sscop->vr_h) { 4004121326Sharti seqno.sscop_null = 0; 4005121326Sharti seqno.sscop_n = sn; 4006121326Sharti MBUF_APPEND32(m, seqno.sscop_null); 4007121326Sharti goto out; 4008121326Sharti } 4009121326Sharti if(QFIND(&sscop->rbuf, sn) == NULL) 4010121326Sharti break; 4011121326Sharti sn++; 4012121326Sharti } 4013121326Sharti 4014121326Sharti /* start of a hole */ 4015121326Sharti seqno.sscop_null = 0; 4016121326Sharti seqno.sscop_n = sn; 4017121326Sharti MBUF_APPEND32(m, seqno.sscop_null); 4018121326Sharti if(MBUF_LEN(m)/4 >= sscop->maxstat) { 4019121326Sharti send_stat(sscop, nps, m); 4020121326Sharti if((m = MBUF_ALLOC(sscop->maxstat * 4 + 12)) == NULL) { 4021121326Sharti FAILURE("sscop: cannot allocate STAT"); 4022121326Sharti return; 4023121326Sharti } 4024121326Sharti seqno.sscop_null = 0; 4025121326Sharti seqno.sscop_n = sn; 4026121326Sharti MBUF_APPEND32(m, seqno.sscop_null); 4027121326Sharti } 4028121326Sharti do { 4029121326Sharti sn++; 4030121326Sharti } while(sn < sscop->vr_h && !QFIND(&sscop->rbuf, sn)); 4031121326Sharti seqno.sscop_null = 0; 4032121326Sharti seqno.sscop_n = sn; 4033121326Sharti MBUF_APPEND32(m, seqno.sscop_null); 4034121326Sharti } 4035121326Sharti out: 4036121326Sharti send_stat(sscop, nps, m); 4037121326Sharti} 4038121326Sharti 4039121326Sharti/* 4040121326Sharti * p 69: READY && USTAT PDU 4041121326Sharti * arg is msg (freed) 4042121326Sharti */ 4043121326Shartistatic void 4044121326Shartisscop_ready_ustat(struct sscop *sscop, struct sscop_msg *msg) 4045121326Sharti{ 4046121326Sharti union pdu pdu; 4047121326Sharti union seqno nmr, sq1, sq2; 4048121326Sharti u_int cnt; 4049121326Sharti 4050121326Sharti pdu.sscop_null = MBUF_STRIP32(msg->m); 4051121326Sharti nmr.sscop_null = MBUF_STRIP32(msg->m); 4052121326Sharti sq2.sscop_null = MBUF_STRIP32(msg->m); 4053121326Sharti sq1.sscop_null = MBUF_STRIP32(msg->m); 4054121326Sharti 4055121326Sharti SSCOP_MSG_FREE(msg); 4056121326Sharti 4057121326Sharti cnt = sq1.sscop_n - sq2.sscop_n; 4058121326Sharti 4059121326Sharti if((u_int)pdu.sscop_ns < sscop->vt_a || (u_int)pdu.sscop_ns >= sscop->vt_s) { 4060121326Sharti VERBERR(sscop, SSCOP_DBG_ERR, (sscop, sscop->aarg, 4061121326Sharti "USTAT: N(R) outside VT(A)...VT(S)-1: N(R)=%u VT(A)=%u " 4062121326Sharti "VT(S)=%u", (u_int)pdu.sscop_ns, sscop->vt_a, sscop->vt_s)); 4063121326Sharti goto err_f; 4064121326Sharti } 4065121326Sharti 4066121326Sharti /* Acknowledge all messages between VT(A) and N(R)-1. N(R) is the new 4067121326Sharti * next in sequence-SD-number of the receiver and means, it has all 4068121326Sharti * messages below N(R). Remove all message below N(R) from the 4069121326Sharti * transmission buffer. It may already be removed because of an 4070121326Sharti * earlier selective ACK in a STAT message. 4071121326Sharti */ 4072121326Sharti while((msg = MSGQ_PEEK(&sscop->xbuf)) != NULL && msg->seqno < (u_int)pdu.sscop_ns) { 4073121326Sharti ASSERT(msg->seqno >= sscop->vt_a); 4074121326Sharti MSGQ_REMOVE(&sscop->xbuf, msg); 4075121326Sharti SSCOP_MSG_FREE(msg); 4076121326Sharti } 4077121326Sharti 4078121326Sharti /* Update the in-sequence acknowledge and the send window */ 4079121326Sharti sscop->vt_a = pdu.sscop_ns; 4080121326Sharti sscop->vt_ms = nmr.sscop_n; 4081121326Sharti 4082121326Sharti /* check, that the range of requested re-transmissions is between 4083121326Sharti * the in-sequence-ack and the highest up-to-now transmitted SD 4084121326Sharti */ 4085121326Sharti if(sq1.sscop_n >= sq2.sscop_n 4086121326Sharti || (u_int)sq1.sscop_n < sscop->vt_a 4087121326Sharti || (u_int)sq2.sscop_n >= sscop->vt_s) { 4088121326Sharti VERBERR(sscop, SSCOP_DBG_ERR, (sscop, sscop->aarg, 4089121326Sharti "USTAT: seq1 or seq2 outside VT(A)...VT(S)-1 or seq1>=seq2:" 4090121326Sharti " seq1=%u seq2=%u VT(A)=%u VT(S)=%u", 4091121326Sharti sq1.sscop_n, sq2.sscop_n, sscop->vt_a, sscop->vt_s)); 4092121326Sharti goto err_f; 4093121326Sharti } 4094121326Sharti 4095121326Sharti /* 4096121326Sharti * Retransmit all messages from seq1 to seq2-1 4097121326Sharti */ 4098121326Sharti do { 4099121326Sharti /* 4100121326Sharti * The message may not be in the transmit buffer if it was 4101121326Sharti * already acked by a STAT. This means, the receiver is 4102121326Sharti * confused. 4103121326Sharti */ 4104121326Sharti if((msg = QFIND(&sscop->xbuf, sq1.sscop_n)) == NULL) { 4105121326Sharti VERBERR(sscop, SSCOP_DBG_ERR, (sscop, sscop->aarg, 4106121326Sharti "USTAT: message %u not found in xmit buffer", 4107121326Sharti sq1.sscop_n)); 4108121326Sharti goto err_f; 4109121326Sharti } 4110121326Sharti 4111121326Sharti /* 4112121326Sharti * If it is not yet in the re-transmission queue, put it there 4113121326Sharti */ 4114121326Sharti if(!msg->rexmit) { 4115121326Sharti msg->rexmit = 1; 4116121326Sharti sscop->rxq++; 4117121326Sharti sscop_signal(sscop, SIG_PDU_Q, msg); 4118121326Sharti } 4119121326Sharti sq1.sscop_n++; 4120121326Sharti } while(sq1.sscop_n != sq2.sscop_n); 4121121326Sharti 4122121326Sharti /* 4123121326Sharti * report the re-transmission to the management 4124121326Sharti */ 4125121326Sharti MAAL_ERROR(sscop, 'V', cnt); 4126121326Sharti return; 4127121326Sharti 4128121326Sharti err_f: 4129121326Sharti m_reset_data_xfer_timers(sscop); 4130121326Sharti MAAL_ERROR(sscop, 'T', 0); 4131121326Sharti sscop_recover(sscop); 4132121326Sharti} 4133121326Sharti 4134121326Sharti/* 4135121326Sharti * p 70: READY && STAT PDU 4136121326Sharti * arg is msg (freed). 4137121326Sharti */ 4138121326Shartistatic void 4139121326Shartisscop_ready_stat(struct sscop *sscop, struct sscop_msg *msg) 4140121326Sharti{ 4141121326Sharti union pdu pdu; 4142121326Sharti union seqno nps, nmr; 4143121326Sharti u_int len, seq1, seq2, cnt; 4144121326Sharti struct sscop_msg *m; 4145121326Sharti 4146121326Sharti pdu.sscop_null = MBUF_STRIP32(msg->m); 4147121326Sharti nmr.sscop_null = MBUF_STRIP32(msg->m); 4148121326Sharti nps.sscop_null = MBUF_STRIP32(msg->m); 4149121326Sharti 4150121326Sharti len = MBUF_LEN(msg->m) / 4; 4151121326Sharti 4152121326Sharti if((u_int)nps.sscop_n < sscop->vt_pa 4153121326Sharti || (u_int)nps.sscop_n > sscop->vt_ps) { 4154121326Sharti SSCOP_MSG_FREE(msg); 4155121326Sharti m_reset_data_xfer_timers(sscop); 4156121326Sharti MAAL_ERROR(sscop, 'R', 0); 4157121326Sharti sscop_recover(sscop); 4158121326Sharti return; 4159121326Sharti } 4160121326Sharti 4161121326Sharti if((u_int)pdu.sscop_ns < sscop->vt_a 4162121326Sharti || (u_int)pdu.sscop_ns > sscop->vt_s) { 4163121326Sharti /* 4164121326Sharti * The in-sequence acknowledge, i.e. the receivers's next 4165121326Sharti * expected in-sequence msg is outside the window between 4166121326Sharti * the transmitters in-sequence ack and highest seqno - 4167121326Sharti * the receiver seems to be confused. 4168121326Sharti */ 4169121326Sharti VERBERR(sscop, SSCOP_DBG_ERR, (sscop, sscop->aarg, 4170121326Sharti "STAT: N(R) outside VT(A)...VT(S)-1: N(R)=%u VT(A)=%u " 4171121326Sharti "VT(S)=%u", (u_int)pdu.sscop_ns, sscop->vt_a, sscop->vt_s)); 4172121326Sharti err_H: 4173121326Sharti SSCOP_MSG_FREE(msg); 4174121326Sharti m_reset_data_xfer_timers(sscop); 4175121326Sharti MAAL_ERROR(sscop, 'S', 0); 4176121326Sharti sscop_recover(sscop); 4177121326Sharti return; 4178121326Sharti } 4179121326Sharti 4180121326Sharti /* Acknowledge all messages between VT(A) and N(R)-1. N(R) is the new 4181121326Sharti * next in sequence-SD-number of the receiver and means, it has all 4182121326Sharti * messages below N(R). Remove all message below N(R) from the 4183121326Sharti * transmission buffer. It may already be removed because of an 4184121326Sharti * earlier selective ACK in a STAT message. 4185121326Sharti */ 4186121326Sharti while((m = MSGQ_PEEK(&sscop->xbuf)) != NULL 4187121326Sharti && m->seqno < (u_int)pdu.sscop_ns) { 4188121326Sharti ASSERT(m->seqno >= sscop->vt_a); 4189121326Sharti MSGQ_REMOVE(&sscop->xbuf, m); 4190121326Sharti SSCOP_MSG_FREE(m); 4191121326Sharti } 4192121326Sharti 4193121326Sharti /* 4194121326Sharti * Update in-sequence ack, poll-ack and send window. 4195121326Sharti */ 4196121326Sharti sscop->vt_a = pdu.sscop_ns; 4197121326Sharti sscop->vt_pa = nps.sscop_n; 4198121326Sharti sscop->vt_ms = nmr.sscop_n; 4199121326Sharti 4200121326Sharti cnt = 0; 4201121326Sharti if(len > 1) { 4202121326Sharti seq1 = MBUF_GET32(msg->m); 4203121326Sharti len--; 4204121326Sharti if(seq1 >= sscop->vt_s) { 4205121326Sharti VERBERR(sscop, SSCOP_DBG_ERR, (sscop, sscop->aarg, 4206121326Sharti "STAT: seq1 >= VT(S): seq1=%u VT(S)=%u", 4207121326Sharti seq1, sscop->vt_s)); 4208121326Sharti goto err_H; 4209121326Sharti } 4210121326Sharti 4211121326Sharti for(;;) { 4212121326Sharti seq2 = MBUF_GET32(msg->m); 4213121326Sharti len--; 4214121326Sharti if(seq1 >= seq2 || seq2 > sscop->vt_s) { 4215121326Sharti VERBERR(sscop, SSCOP_DBG_ERR, (sscop, 4216121326Sharti sscop->aarg, "STAT: seq1 >= seq2 or " 4217121326Sharti "seq2 > VT(S): seq1=%u seq2=%u VT(S)=%u", 4218121326Sharti seq1, seq2, sscop->vt_s)); 4219121326Sharti goto err_H; 4220121326Sharti } 4221121326Sharti 4222121326Sharti do { 4223121326Sharti /* 4224121326Sharti * The receiver requests the re-transmission 4225121326Sharti * of some message, but has acknowledged it 4226121326Sharti * already in an earlier STAT (it isn't in the 4227121326Sharti * transmitt buffer anymore). 4228121326Sharti */ 4229121326Sharti if((m = QFIND(&sscop->xbuf, seq1)) == NULL) { 4230121326Sharti VERBERR(sscop, SSCOP_DBG_ERR, 4231121326Sharti (sscop, sscop->aarg, "STAT: message" 4232121326Sharti " %u not found in xmit buffer", 4233121326Sharti seq1)); 4234121326Sharti goto err_H; 4235121326Sharti } 4236121326Sharti if(m->poll_seqno < (u_int)nps.sscop_n 4237121326Sharti && (u_int)nps.sscop_n <= sscop->vt_ps) 4238121326Sharti if(!m->rexmit) { 4239121326Sharti m->rexmit = 1; 4240121326Sharti sscop->rxq++; 4241121326Sharti cnt++; 4242121326Sharti sscop_signal(sscop, SIG_PDU_Q, msg); 4243121326Sharti } 4244121326Sharti } while(++seq1 < seq2); 4245121326Sharti 4246121326Sharti if(len == 0) 4247121326Sharti break; 4248121326Sharti 4249121326Sharti seq2 = MBUF_GET32(msg->m); 4250121326Sharti len--; 4251121326Sharti 4252121326Sharti if(seq1 >= seq2 || seq2 > sscop->vt_s) { 4253121326Sharti VERBERR(sscop, SSCOP_DBG_ERR, (sscop, 4254121326Sharti sscop->aarg, "STAT: seq1 >= seq2 or " 4255121326Sharti "seq2 > VT(S): seq1=%u seq2=%u VT(S)=%u", 4256121326Sharti seq1, seq2, sscop->vt_s)); 4257121326Sharti goto err_H; 4258121326Sharti } 4259121326Sharti 4260121326Sharti /* OK now the sucessful transmitted messages. Note, that 4261121326Sharti * some messages may already be out of the buffer because 4262121326Sharti * of earlier STATS */ 4263121326Sharti do { 4264121326Sharti if(sscop->clear_buffers) { 4265121326Sharti if((m = QFIND(&sscop->xbuf, seq1)) != NULL) { 4266121326Sharti MSGQ_REMOVE(&sscop->xbuf, m); 4267121326Sharti SSCOP_MSG_FREE(m); 4268121326Sharti } 4269121326Sharti } 4270121326Sharti } while(++seq1 != seq2); 4271121326Sharti 4272121326Sharti if(len == 0) 4273121326Sharti break; 4274121326Sharti } 4275121326Sharti MAAL_ERROR(sscop, 'V', cnt); 4276121326Sharti } 4277121326Sharti SSCOP_MSG_FREE(msg); 4278121326Sharti 4279121326Sharti /* label L: */ 4280121326Sharti if(sscop->vt_s >= sscop->vt_ms) { 4281121326Sharti /* 4282121326Sharti * The receiver has closed the window: report to management 4283121326Sharti */ 4284121326Sharti if(sscop->credit) { 4285121326Sharti sscop->credit = 0; 4286121326Sharti MAAL_ERROR(sscop, 'W', 0); 4287121326Sharti } 4288121326Sharti } else if(!sscop->credit) { 4289121326Sharti /* 4290121326Sharti * The window was forcefully closed above, but 4291121326Sharti * now re-opened. Report to management. 4292121326Sharti */ 4293121326Sharti sscop->credit = 1; 4294121326Sharti MAAL_ERROR(sscop, 'X', 0); 4295121326Sharti } 4296121326Sharti 4297121326Sharti if(TIMER_ISACT(sscop, poll)) { 4298121326Sharti TIMER_RESTART(sscop, nr); 4299121326Sharti } else if(!TIMER_ISACT(sscop, idle)) { 4300121326Sharti TIMER_STOP(sscop, ka); 4301121326Sharti TIMER_STOP(sscop, nr); 4302121326Sharti TIMER_RESTART(sscop, idle); 4303121326Sharti } 4304121326Sharti} 4305121326Sharti 4306121326Sharti/* 4307121326Sharti * P. 73: any state & UDATA_REQUEST 4308121326Sharti * arg is pdu (queued) 4309121326Sharti */ 4310121326Shartistatic void 4311121326Shartisscop_udata_req(struct sscop *sscop, struct sscop_msg *msg) 4312121326Sharti{ 4313121326Sharti MSGQ_APPEND(&sscop->uxq, msg); 4314121326Sharti sscop_signal(sscop, SIG_UPDU_Q, msg); 4315121326Sharti} 4316121326Sharti 4317121326Sharti/* 4318121326Sharti * P. 73: any state & MDATA_REQUEST 4319121326Sharti * arg is pdu (queued) 4320121326Sharti */ 4321121326Shartistatic void 4322121326Shartisscop_mdata_req(struct sscop *sscop, struct sscop_msg *msg) 4323121326Sharti{ 4324121326Sharti MSGQ_APPEND(&sscop->mxq, msg); 4325121326Sharti sscop_signal(sscop, SIG_MPDU_Q, msg); 4326121326Sharti} 4327121326Sharti 4328121326Sharti/* 4329121326Sharti * P. 74: any state & UDATA queued 4330121326Sharti * no arg. 4331121326Sharti */ 4332121326Shartistatic void 4333121326Shartisscop_upduq(struct sscop *sscop, struct sscop_msg *unused __unused) 4334121326Sharti{ 4335121326Sharti struct sscop_msg *msg; 4336121326Sharti 4337121326Sharti if(sscop->ll_busy) 4338121326Sharti return; 4339121326Sharti while((msg = MSGQ_GET(&sscop->uxq)) != NULL) { 4340121326Sharti send_ud(sscop, msg->m); 4341121326Sharti msg->m = NULL; 4342121326Sharti SSCOP_MSG_FREE(msg); 4343121326Sharti } 4344121326Sharti} 4345121326Sharti 4346121326Sharti/* 4347121326Sharti * P. 74: any state & MDATA queued 4348121326Sharti * no arg. 4349121326Sharti */ 4350121326Shartistatic void 4351121326Shartisscop_mpduq(struct sscop *sscop, struct sscop_msg *unused __unused) 4352121326Sharti{ 4353121326Sharti struct sscop_msg *msg; 4354121326Sharti 4355121326Sharti if(sscop->ll_busy) 4356121326Sharti return; 4357121326Sharti while((msg = MSGQ_GET(&sscop->mxq)) != NULL) { 4358121326Sharti send_md(sscop, msg->m); 4359121326Sharti msg->m = NULL; 4360121326Sharti SSCOP_MSG_FREE(msg); 4361121326Sharti } 4362121326Sharti} 4363121326Sharti 4364121326Sharti/* 4365121326Sharti * p 73: MD PDU 4366121326Sharti * arg is PDU 4367121326Sharti */ 4368121326Shartistatic void 4369121326Shartisscop_md(struct sscop *sscop, struct sscop_msg *msg) 4370121326Sharti{ 4371121326Sharti union pdu pdu; 4372121326Sharti 4373121326Sharti pdu.sscop_null = MBUF_STRIP32(msg->m); 4374121326Sharti 4375121326Sharti MBUF_UNPAD(msg->m, pdu.sscop_pl); 4376121326Sharti 4377121326Sharti MAAL_DATA(sscop, msg->m); 4378121326Sharti msg->m = NULL; 4379121326Sharti SSCOP_MSG_FREE(msg); 4380121326Sharti} 4381121326Sharti 4382121326Sharti/* 4383121326Sharti * p 73: UD PDU 4384121326Sharti * arg is PDU 4385121326Sharti */ 4386121326Shartistatic void 4387121326Shartisscop_ud(struct sscop *sscop, struct sscop_msg *msg) 4388121326Sharti{ 4389121326Sharti union pdu pdu; 4390121326Sharti 4391121326Sharti pdu.sscop_null = MBUF_STRIP32(msg->m); 4392121326Sharti 4393121326Sharti MBUF_UNPAD(msg->m, pdu.sscop_pl); 4394121326Sharti 4395121326Sharti AAL_DATA(sscop, SSCOP_UDATA_indication, msg->m, 0); 4396121326Sharti msg->m = NULL; 4397121326Sharti SSCOP_MSG_FREE(msg); 4398121326Sharti} 4399121326Sharti 4400121326Sharti 4401121326Sharti/* 4402121326Sharti * p 33: IDLE & RETRIEVE 4403121326Sharti * p 39: IN_PEND & RETRIEVE 4404121326Sharti * p 42: OUT_DIS_PEND & RETRIEVE 4405121326Sharti * p 48: IN_RESYNC_PEND & RETRIEVE 4406121326Sharti * p 53: REC_PEND & RETRIEVE 4407121326Sharti * p 58: IN_REC_PEND & RETRIEVE 4408121326Sharti */ 4409121326Shartistatic void 4410121326Shartisscop_retrieve(struct sscop *sscop, struct sscop_msg *msg) 4411121326Sharti{ 4412121326Sharti m_data_retrieval(sscop, msg->rexmit); 4413121326Sharti SSCOP_MSG_FREE(msg); 4414121326Sharti} 4415121326Sharti 4416121326Sharti/************************************************************/ 4417121326Sharti/* 4418121326Sharti * GENERAL EVENT HANDLING 4419121326Sharti */ 4420121326Sharti 4421121326Sharti/* 4422121326Sharti * State/event matrix. 4423121326Sharti * 4424121326Sharti * Entries marked with Z are not specified in Q.2110, but are added for 4425121326Sharti * the sake of stability. 4426121326Sharti */ 4427121326Shartistatic struct { 4428121326Sharti void (*func)(struct sscop *, struct sscop_msg *); 4429121326Sharti int (*cond)(struct sscop *); 4430121326Sharti} state_matrix[SSCOP_NSTATES][SIG_NUM] = { 4431121326Sharti /* SSCOP_IDLE */ { 4432121326Sharti /* SIG_BGN */ { sscop_idle_bgn, NULL }, 4433121326Sharti /* SIG_BGAK */ { sscop_idle_bgak, NULL }, 4434121326Sharti /* SIG_END */ { sscop_idle_end, NULL }, 4435121326Sharti /* SIG_ENDAK */ { sscop_ignore_pdu, NULL }, 4436121326Sharti /* SIG_RS */ { sscop_idle_rs, NULL }, 4437121326Sharti /* SIG_RSAK */ { sscop_idle_rsak, NULL }, 4438121326Sharti /* SIG_BGREJ */ { sscop_idle_bgrej, NULL }, 4439121326Sharti /* SIG_SD */ { sscop_idle_sd, NULL }, 4440121326Sharti /* SIG_ER */ { sscop_idle_er, NULL }, 4441121326Sharti /* SIG_POLL */ { sscop_idle_poll, NULL }, 4442121326Sharti /* SIG_STAT */ { sscop_idle_stat, NULL }, 4443121326Sharti /* SIG_USTAT */ { sscop_idle_ustat, NULL }, 4444121326Sharti /* SIG_UD */ { sscop_ud, NULL }, 4445121326Sharti /* SIG_MD */ { sscop_md, NULL }, 4446121326Sharti /* SIG_ERAK */ { sscop_idle_erak, NULL }, 4447121326Sharti /* SIG_T_CC */ { NULL, NULL }, 4448121326Sharti /* SIG_T_POLL */ { NULL, NULL }, 4449121326Sharti /* SIG_T_KA */ { NULL, NULL }, 4450121326Sharti /* SIG_T_NR */ { NULL, NULL }, 4451121326Sharti /* SIG_T_IDLE */ { NULL, NULL }, 4452121326Sharti /* SIG_PDU_Q */ { sscop_flush_pduq, NULL }, 4453121326Sharti /* SIG_USER_DATA */ { NULL, NULL }, 4454121326Sharti /* SIG_ESTAB_REQ */ { sscop_idle_establish_req, NULL }, 4455121326Sharti /* SIG_ESTAB_RESP */ { NULL, NULL }, 4456121326Sharti /* SIG_RELEASE_REQ */ { NULL, NULL }, 4457121326Sharti /* SIG_RECOVER */ { NULL, NULL }, 4458121326Sharti /* SIG_SYNC_REQ */ { NULL, NULL }, 4459121326Sharti /* SIG_SYNC_RESP */ { NULL, NULL }, 4460121326Sharti /* SIG_UDATA */ { sscop_udata_req, NULL }, 4461121326Sharti /* SIG_MDATA */ { sscop_mdata_req, NULL }, 4462121326Sharti /* SIG_UPDU_Q */ { sscop_upduq, NULL }, 4463121326Sharti /* SIG_MPDU_Q */ { sscop_mpduq, NULL }, 4464121326Sharti /* SIG_RETRIEVE */ { sscop_retrieve, NULL }, 4465121326Sharti }, 4466121326Sharti /* SSCOP_OUT_PEND */ { 4467121326Sharti /* SIG_BGN */ { sscop_outpend_bgn, NULL }, 4468121326Sharti /* SIG_BGAK */ { sscop_outpend_bgak, NULL }, 4469121326Sharti /* SIG_END */ { sscop_ignore_pdu, NULL }, 4470121326Sharti /* SIG_ENDAK */ { sscop_ignore_pdu, NULL }, 4471121326Sharti /* SIG_RS */ { sscop_ignore_pdu, NULL }, 4472121326Sharti /* SIG_RSAK */ { sscop_ignore_pdu, NULL }, 4473121326Sharti /* SIG_BGREJ */ { sscop_outpend_bgrej, NULL }, 4474121326Sharti /* SIG_SD */ { sscop_ignore_pdu, NULL }, 4475121326Sharti /* SIG_ER */ { sscop_ignore_pdu, NULL }, 4476121326Sharti /* SIG_POLL */ { sscop_ignore_pdu, NULL }, 4477121326Sharti /* SIG_STAT */ { sscop_ignore_pdu, NULL }, 4478121326Sharti /* SIG_USTAT */ { sscop_ignore_pdu, NULL }, 4479121326Sharti /* SIG_UD */ { sscop_ud, NULL }, 4480121326Sharti /* SIG_MD */ { sscop_md, NULL }, 4481121326Sharti /* SIG_ERAK */ { sscop_ignore_pdu, NULL }, 4482121326Sharti /* SIG_T_CC */ { sscop_outpend_tcc, NULL }, 4483121326Sharti /* SIG_T_POLL */ { NULL, NULL }, 4484121326Sharti /* SIG_T_KA */ { NULL, NULL }, 4485121326Sharti /* SIG_T_NR */ { NULL, NULL }, 4486121326Sharti /* SIG_T_IDLE */ { NULL, NULL }, 4487121326Sharti /* SIG_PDU_Q */ { sscop_flush_pduq, NULL }, 4488121326Sharti /* SIG_USER_DATA */ { NULL, NULL }, 4489121326Sharti /* SIG_ESTAB_REQ */ { NULL, NULL }, 4490121326Sharti /* SIG_ESTAB_RESP */ { NULL, NULL }, 4491121326Sharti /* SIG_RELEASE_REQ */ { sscop_outpend_release_req, NULL }, 4492121326Sharti /* SIG_RECOVER */ { NULL, NULL }, 4493121326Sharti /* SIG_SYNC_REQ */ { NULL, NULL }, 4494121326Sharti /* SIG_SYNC_RESP */ { NULL, NULL }, 4495121326Sharti /* SIG_UDATA */ { sscop_udata_req, NULL }, 4496121326Sharti /* SIG_MDATA */ { sscop_mdata_req, NULL }, 4497121326Sharti /* SIG_UPDU_Q */ { sscop_upduq, NULL }, 4498121326Sharti /* SIG_MPDU_Q */ { sscop_mpduq, NULL }, 4499121326Sharti /* SIG_RETRIEVE */ { NULL, NULL }, 4500121326Sharti }, 4501121326Sharti /* SSCOP_IN_PEND */ { 4502121326Sharti /* SIG_BGN */ { sscop_inpend_bgn, NULL }, 4503121326Sharti /* SIG_BGAK */ { sscop_inpend_bgak, NULL }, 4504121326Sharti /* SIG_END */ { sscop_inpend_end, NULL }, 4505121326Sharti /* SIG_ENDAK */ { sscop_inpend_endak, NULL }, 4506121326Sharti /* SIG_RS */ { sscop_inpend_rs, NULL }, 4507121326Sharti /* SIG_RSAK */ { sscop_inpend_rsak, NULL }, 4508121326Sharti /* SIG_BGREJ */ { sscop_inpend_bgrej, NULL }, 4509121326Sharti /* SIG_SD */ { sscop_inpend_sd, NULL }, 4510121326Sharti /* SIG_ER */ { sscop_inpend_er, NULL }, 4511121326Sharti /* SIG_POLL */ { sscop_inpend_poll, NULL }, 4512121326Sharti /* SIG_STAT */ { sscop_inpend_stat, NULL }, 4513121326Sharti /* SIG_USTAT */ { sscop_inpend_ustat, NULL }, 4514121326Sharti /* SIG_UD */ { sscop_ud, NULL }, 4515121326Sharti /* SIG_MD */ { sscop_md, NULL }, 4516121326Sharti /* SIG_ERAK */ { sscop_inpend_erak, NULL }, 4517121326Sharti /* SIG_T_CC */ { NULL, NULL }, 4518121326Sharti /* SIG_T_POLL */ { NULL, NULL }, 4519121326Sharti /* SIG_T_KA */ { NULL, NULL }, 4520121326Sharti /* SIG_T_NR */ { NULL, NULL }, 4521121326Sharti /* SIG_T_IDLE */ { NULL, NULL }, 4522121326Sharti /* SIG_PDU_Q */ { sscop_flush_pduq, NULL }, 4523121326Sharti /* SIG_USER_DATA */ { NULL, NULL }, 4524121326Sharti /* SIG_ESTAB_REQ */ { NULL, NULL }, 4525121326Sharti /* SIG_ESTAB_RESP */ { sscop_inpend_establish_resp, NULL }, 4526121326Sharti /* SIG_RELEASE_REQ */ { sscop_inpend_release_req, NULL }, 4527121326Sharti /* SIG_RECOVER */ { NULL, NULL }, 4528121326Sharti /* SIG_SYNC_REQ */ { NULL, NULL }, 4529121326Sharti /* SIG_SYNC_RESP */ { NULL, NULL }, 4530121326Sharti /* SIG_UDATA */ { sscop_udata_req, NULL }, 4531121326Sharti /* SIG_MDATA */ { sscop_mdata_req, NULL }, 4532121326Sharti /* SIG_UPDU_Q */ { sscop_upduq, NULL }, 4533121326Sharti /* SIG_MPDU_Q */ { sscop_mpduq, NULL }, 4534121326Sharti /* SIG_RETRIEVE */ { sscop_retrieve, NULL }, 4535121326Sharti }, 4536121326Sharti /* SSCOP_OUT_DIS_PEND */ { 4537121326Sharti /* SIG_BGN */ { sscop_outdis_bgn, NULL }, 4538121326Sharti /* SIG_BGAK */ { sscop_ignore_pdu, NULL }, 4539121326Sharti /* SIG_END */ { sscop_outdis_end, NULL }, 4540121326Sharti /* SIG_ENDAK */ { sscop_outdis_endak, NULL }, 4541121326Sharti /* SIG_RS */ { sscop_ignore_pdu, NULL }, 4542121326Sharti /* SIG_RSAK */ { sscop_ignore_pdu, NULL }, 4543121326Sharti /* SIG_BGREJ */ { sscop_outdis_endak, NULL }, 4544121326Sharti /* SIG_SD */ { sscop_ignore_pdu, NULL }, 4545121326Sharti /* SIG_ER */ { sscop_ignore_pdu, NULL }, 4546121326Sharti /* SIG_POLL */ { sscop_ignore_pdu, NULL }, 4547121326Sharti /* SIG_STAT */ { sscop_ignore_pdu, NULL }, 4548121326Sharti /* SIG_USTAT */ { sscop_ignore_pdu, NULL }, 4549121326Sharti /* SIG_UD */ { sscop_ud, NULL }, 4550121326Sharti /* SIG_MD */ { sscop_md, NULL }, 4551121326Sharti /* SIG_ERAK */ { sscop_ignore_pdu, NULL }, 4552121326Sharti /* SIG_T_CC */ { sscop_outdis_cc, NULL }, 4553121326Sharti /* SIG_T_POLL */ { NULL, NULL }, 4554121326Sharti /* SIG_T_KA */ { NULL, NULL }, 4555121326Sharti /* SIG_T_NR */ { NULL, NULL }, 4556121326Sharti /* SIG_T_IDLE */ { NULL, NULL }, 4557121326Sharti /* SIG_PDU_Q */ { sscop_flush_pduq, NULL }, 4558121326Sharti /* SIG_USER_DATA */ { NULL, NULL }, 4559121326Sharti /* SIG_ESTAB_REQ */ { sscop_outdis_establish_req, NULL }, 4560121326Sharti /* SIG_ESTAB_RESP */ { NULL, NULL }, 4561121326Sharti /* SIG_RELEASE_REQ */ { NULL, NULL }, 4562121326Sharti /* SIG_RECOVER */ { NULL, NULL }, 4563121326Sharti /* SIG_SYNC_REQ */ { NULL, NULL }, 4564121326Sharti /* SIG_SYNC_RESP */ { NULL, NULL }, 4565121326Sharti /* SIG_UDATA */ { sscop_udata_req, NULL }, 4566121326Sharti /* SIG_MDATA */ { sscop_mdata_req, NULL }, 4567121326Sharti /* SIG_UPDU_Q */ { sscop_upduq, NULL }, 4568121326Sharti /* SIG_MPDU_Q */ { sscop_mpduq, NULL }, 4569121326Sharti /* SIG_RETRIEVE */ { sscop_retrieve, NULL }, 4570121326Sharti }, 4571121326Sharti /* SSCOP_OUT_RESYNC_PEND */ { 4572121326Sharti /* SIG_BGN */ { sscop_outsync_bgn, NULL }, 4573121326Sharti /* SIG_BGAK */ { sscop_ignore_pdu, NULL }, 4574121326Sharti /* SIG_END */ { sscop_outsync_end, NULL }, 4575121326Sharti /* SIG_ENDAK */ { sscop_outsync_endak, NULL }, 4576121326Sharti /* SIG_RS */ { sscop_outsync_rs, NULL }, 4577121326Sharti /* SIG_RSAK */ { sscop_outsync_rsak, NULL }, 4578121326Sharti /* SIG_BGREJ */ { sscop_outsync_bgrej, NULL }, 4579121326Sharti /* SIG_SD */ { sscop_ignore_pdu, NULL }, 4580121326Sharti /* SIG_ER */ { sscop_ignore_pdu, NULL }, 4581121326Sharti /* SIG_POLL */ { sscop_ignore_pdu, NULL }, 4582121326Sharti /* SIG_STAT */ { sscop_ignore_pdu, NULL }, 4583121326Sharti /* SIG_USTAT */ { sscop_ignore_pdu, NULL }, 4584121326Sharti /* SIG_UD */ { sscop_ud, NULL }, 4585121326Sharti /* SIG_MD */ { sscop_md, NULL }, 4586121326Sharti /* SIG_ERAK */ { sscop_ignore_pdu, NULL }, 4587121326Sharti /* SIG_T_CC */ { sscop_outsync_cc, NULL }, 4588121326Sharti /* SIG_T_POLL */ { NULL, NULL }, 4589121326Sharti /* SIG_T_KA */ { NULL, NULL }, 4590121326Sharti /* SIG_T_NR */ { NULL, NULL }, 4591121326Sharti /* SIG_T_IDLE */ { NULL, NULL }, 4592121326Sharti /* SIG_PDU_Q */ { sscop_flush_pduq, NULL }, 4593121326Sharti /* SIG_USER_DATA */ { NULL, NULL }, 4594121326Sharti /* SIG_ESTAB_REQ */ { NULL, NULL }, 4595121326Sharti /* SIG_ESTAB_RESP */ { NULL, NULL }, 4596121326Sharti /* SIG_RELEASE_REQ */ { sscop_outsync_release_req, NULL }, 4597121326Sharti /* SIG_RECOVER */ { NULL, NULL }, 4598121326Sharti /* SIG_SYNC_REQ */ { NULL, NULL }, 4599121326Sharti /* SIG_SYNC_RESP */ { NULL, NULL }, 4600121326Sharti /* SIG_UDATA */ { sscop_udata_req, NULL }, 4601121326Sharti /* SIG_MDATA */ { sscop_mdata_req, NULL }, 4602121326Sharti /* SIG_UPDU_Q */ { sscop_upduq, NULL }, 4603121326Sharti /* SIG_MPDU_Q */ { sscop_mpduq, NULL }, 4604121326Sharti /* SIG_RETRIEVE */ { NULL, NULL }, 4605121326Sharti }, 4606121326Sharti /* SSCOP_IN_RESYNC_PEND */ { 4607121326Sharti /* SIG_BGN */ { sscop_insync_bgn, NULL }, 4608121326Sharti /* SIG_BGAK */ { sscop_insync_bgak, NULL }, 4609121326Sharti /* SIG_END */ { sscop_insync_end, NULL }, 4610121326Sharti /* SIG_ENDAK */ { sscop_insync_endak, NULL }, 4611121326Sharti /* SIG_RS */ { sscop_insync_rs, NULL }, 4612121326Sharti /* SIG_RSAK */ { sscop_insync_rsak, NULL }, 4613121326Sharti /* SIG_BGREJ */ { sscop_insync_bgrej, NULL }, 4614121326Sharti /* SIG_SD */ { sscop_insync_sd, NULL }, 4615121326Sharti /* SIG_ER */ { sscop_insync_er, NULL }, 4616121326Sharti /* SIG_POLL */ { sscop_insync_poll, NULL }, 4617121326Sharti /* SIG_STAT */ { sscop_insync_stat, NULL }, 4618121326Sharti /* SIG_USTAT */ { sscop_insync_ustat, NULL }, 4619121326Sharti /* SIG_UD */ { sscop_ud, NULL }, 4620121326Sharti /* SIG_MD */ { sscop_md, NULL }, 4621121326Sharti /* SIG_ERAK */ { sscop_insync_erak, NULL }, 4622121326Sharti /* SIG_T_CC */ { NULL, NULL }, 4623121326Sharti /* SIG_T_POLL */ { NULL, NULL }, 4624121326Sharti /* SIG_T_KA */ { NULL, NULL }, 4625121326Sharti /* SIG_T_NR */ { NULL, NULL }, 4626121326Sharti /* SIG_T_IDLE */ { NULL, NULL }, 4627121326Sharti /* SIG_PDU_Q */ { sscop_flush_pduq, NULL }, 4628121326Sharti /* SIG_USER_DATA */ { NULL, NULL }, 4629121326Sharti /* SIG_ESTAB_REQ */ { NULL, NULL }, 4630121326Sharti /* SIG_ESTAB_RESP */ { NULL, NULL }, 4631121326Sharti /* SIG_RELEASE_REQ */ { sscop_insync_release_req, NULL }, 4632121326Sharti /* SIG_RECOVER */ { NULL, NULL }, 4633121326Sharti /* SIG_SYNC_REQ */ { NULL, NULL }, 4634121326Sharti /* SIG_SYNC_RESP */ { sscop_insync_sync_resp, NULL }, 4635121326Sharti /* SIG_UDATA */ { sscop_udata_req, NULL }, 4636121326Sharti /* SIG_MDATA */ { sscop_mdata_req, NULL }, 4637121326Sharti /* SIG_UPDU_Q */ { sscop_upduq, NULL }, 4638121326Sharti /* SIG_MPDU_Q */ { sscop_mpduq, NULL }, 4639121326Sharti /* SIG_RETRIEVE */ { sscop_retrieve, NULL }, 4640121326Sharti }, 4641121326Sharti /* SSCOP_OUT_REC_PEND */ { 4642121326Sharti /* SIG_BGN */ { sscop_outrec_bgn, NULL }, 4643121326Sharti /* SIG_BGAK */ { sscop_outrec_bgak, NULL }, 4644121326Sharti /* SIG_END */ { sscop_outrec_end, NULL }, 4645121326Sharti /* SIG_ENDAK */ { sscop_outrec_endak, NULL }, 4646121326Sharti /* SIG_RS */ { sscop_outrec_rs, NULL }, 4647121326Sharti /* SIG_RSAK */ { sscop_outrec_rsak, NULL }, 4648121326Sharti /* SIG_BGREJ */ { sscop_outrec_bgrej, NULL }, 4649121326Sharti /* SIG_SD */ { sscop_ignore_pdu, NULL }, 4650121326Sharti /* SIG_ER */ { sscop_outrec_er, NULL }, 4651121326Sharti /* SIG_POLL */ { sscop_ignore_pdu, NULL }, 4652121326Sharti /* SIG_STAT */ { sscop_ignore_pdu, NULL }, 4653121326Sharti /* SIG_USTAT */ { sscop_ignore_pdu, NULL }, 4654121326Sharti /* SIG_UD */ { sscop_ud, NULL }, 4655121326Sharti /* SIG_MD */ { sscop_md, NULL }, 4656121326Sharti /* SIG_ERAK */ { sscop_outrec_erak, NULL }, 4657121326Sharti /* SIG_T_CC */ { sscop_outrec_cc, NULL }, 4658121326Sharti /* SIG_T_POLL */ { NULL, NULL }, 4659121326Sharti /* SIG_T_KA */ { NULL, NULL }, 4660121326Sharti /* SIG_T_NR */ { NULL, NULL }, 4661121326Sharti /* SIG_T_IDLE */ { NULL, NULL }, 4662121326Sharti /* SIG_PDU_Q */ { sscop_outrec_pduq, NULL }, 4663121326Sharti /* SIG_USER_DATA */ { sscop_outrec_userdata, NULL }, 4664121326Sharti /* SIG_ESTAB_REQ */ { NULL, NULL }, 4665121326Sharti /* SIG_ESTAB_RESP */ { NULL, NULL }, 4666121326Sharti /* SIG_RELEASE_REQ */ { sscop_outrec_release_req, NULL }, 4667121326Sharti /* SIG_RECOVER */ { NULL, NULL }, 4668121326Sharti /* SIG_SYNC_REQ */ { sscop_outrec_sync_req, NULL }, 4669121326Sharti /* SIG_SYNC_RESP */ { NULL, NULL }, 4670121326Sharti /* SIG_UDATA */ { sscop_udata_req, NULL }, 4671121326Sharti /* SIG_MDATA */ { sscop_mdata_req, NULL }, 4672121326Sharti /* SIG_UPDU_Q */ { sscop_upduq, NULL }, 4673121326Sharti /* SIG_MPDU_Q */ { sscop_mpduq, NULL }, 4674121326Sharti /* SIG_RETRIEVE */ { NULL, NULL }, 4675121326Sharti }, 4676121326Sharti /* SSCOP_REC_PEND */ { 4677121326Sharti /* SIG_BGN */ { sscop_rec_bgn, NULL }, 4678121326Sharti /* SIG_BGAK */ { sscop_rec_bgak, NULL }, 4679121326Sharti /* SIG_END */ { sscop_rec_end, NULL }, 4680121326Sharti /* SIG_ENDAK */ { sscop_rec_endak, NULL }, 4681121326Sharti /* SIG_RS */ { sscop_rec_rs, NULL }, 4682121326Sharti /* SIG_RSAK */ { sscop_rec_rsak, NULL }, 4683121326Sharti /* SIG_BGREJ */ { sscop_rec_bgrej, NULL }, 4684121326Sharti /* SIG_SD */ { sscop_ignore_pdu, NULL }, 4685121326Sharti /* SIG_ER */ { sscop_rec_er, NULL }, 4686121326Sharti /* SIG_POLL */ { sscop_ignore_pdu, NULL }, 4687121326Sharti /* SIG_STAT */ { sscop_rec_stat, NULL }, 4688121326Sharti /* SIG_USTAT */ { sscop_rec_ustat, NULL }, 4689121326Sharti /* SIG_UD */ { sscop_ud, NULL }, 4690121326Sharti /* SIG_MD */ { sscop_md, NULL }, 4691121326Sharti /* SIG_ERAK */ { sscop_ignore_pdu, NULL }, 4692121326Sharti /* SIG_T_CC */ { NULL, NULL }, 4693121326Sharti /* SIG_T_POLL */ { NULL, NULL }, 4694121326Sharti /* SIG_T_KA */ { NULL, NULL }, 4695121326Sharti /* SIG_T_NR */ { NULL, NULL }, 4696121326Sharti /* SIG_T_IDLE */ { NULL, NULL }, 4697121326Sharti /* SIG_PDU_Q */ { sscop_rec_pduq, NULL }, 4698121326Sharti /* SIG_USER_DATA */ { NULL, NULL }, 4699121326Sharti /* SIG_ESTAB_REQ */ { NULL, NULL }, 4700121326Sharti /* SIG_ESTAB_RESP */ { NULL, NULL }, 4701121326Sharti /* SIG_RELEASE_REQ */ { sscop_rec_release_req, NULL }, 4702121326Sharti /* SIG_RECOVER */ { sscop_rec_recover, NULL }, 4703121326Sharti /* SIG_SYNC_REQ */ { sscop_rec_sync_req, NULL }, 4704121326Sharti /* SIG_SYNC_RESP */ { NULL, NULL }, 4705121326Sharti /* SIG_UDATA */ { sscop_udata_req, NULL }, 4706121326Sharti /* SIG_MDATA */ { sscop_mdata_req, NULL }, 4707121326Sharti /* SIG_UPDU_Q */ { sscop_upduq, NULL }, 4708121326Sharti /* SIG_MPDU_Q */ { sscop_mpduq, NULL }, 4709121326Sharti /* SIG_RETRIEVE */ { sscop_retrieve, NULL }, 4710121326Sharti }, 4711121326Sharti /* SSCOP_IN_REC_PEND */ { 4712121326Sharti /* SIG_BGN */ { sscop_inrec_bgn, NULL }, 4713121326Sharti /* SIG_BGAK */ { sscop_inrec_bgak, NULL }, 4714121326Sharti /* SIG_END */ { sscop_inrec_end, NULL }, 4715121326Sharti /* SIG_ENDAK */ { sscop_inrec_endak, NULL }, 4716121326Sharti /* SIG_RS */ { sscop_inrec_rs, NULL }, 4717121326Sharti /* SIG_RSAK */ { sscop_inrec_rsak, NULL }, 4718121326Sharti /* SIG_BGREJ */ { sscop_inrec_bgrej, NULL }, 4719121326Sharti /* SIG_SD */ { sscop_inrec_sd, NULL }, 4720121326Sharti /* SIG_ER */ { sscop_inrec_er, NULL }, 4721121326Sharti /* SIG_POLL */ { sscop_inrec_poll, NULL }, 4722121326Sharti /* SIG_STAT */ { sscop_inrec_stat, NULL }, 4723121326Sharti /* SIG_USTAT */ { sscop_inrec_ustat, NULL }, 4724121326Sharti /* SIG_UD */ { sscop_ud, NULL }, 4725121326Sharti /* SIG_MD */ { sscop_md, NULL }, 4726121326Sharti /* SIG_ERAK */ { sscop_inrec_erak, NULL }, 4727121326Sharti /* SIG_T_CC */ { NULL, NULL }, 4728121326Sharti /* SIG_T_POLL */ { NULL, NULL }, 4729121326Sharti /* SIG_T_KA */ { NULL, NULL }, 4730121326Sharti /* SIG_T_NR */ { NULL, NULL }, 4731121326Sharti /* SIG_T_IDLE */ { NULL, NULL }, 4732121326Sharti /* SIG_PDU_Q */ { sscop_inrec_pduq, NULL }, 4733121326Sharti /* SIG_USER_DATA */ { NULL, NULL }, 4734121326Sharti /* SIG_ESTAB_REQ */ { NULL, NULL }, 4735121326Sharti /* SIG_ESTAB_RESP */ { NULL, NULL }, 4736121326Sharti /* SIG_RELEASE_REQ */ { sscop_inrec_release_req, NULL }, 4737121326Sharti /* SIG_RECOVER */ { sscop_inrec_recover, NULL }, 4738121326Sharti /* SIG_SYNC_REQ */ { sscop_inrec_sync_req, NULL }, 4739121326Sharti /* SIG_SYNC_RESP */ { NULL, NULL }, 4740121326Sharti /* SIG_UDATA */ { sscop_udata_req, NULL }, 4741121326Sharti /* SIG_MDATA */ { sscop_mdata_req, NULL }, 4742121326Sharti /* SIG_UPDU_Q */ { sscop_upduq, NULL }, 4743121326Sharti /* SIG_MPDU_Q */ { sscop_mpduq, NULL }, 4744121326Sharti /* SIG_RETRIEVE */ { sscop_retrieve, NULL }, 4745121326Sharti }, 4746121326Sharti /* SSCOP_READY */ { 4747121326Sharti /* SIG_BGN */ { sscop_ready_bgn, NULL }, 4748121326Sharti /* SIG_BGAK */ { sscop_ignore_pdu, NULL }, 4749121326Sharti /* SIG_END */ { sscop_ready_end, NULL }, 4750121326Sharti /* SIG_ENDAK */ { sscop_ready_endak, NULL }, 4751121326Sharti /* SIG_RS */ { sscop_ready_rs, NULL }, 4752121326Sharti /* SIG_RSAK */ { sscop_ignore_pdu, NULL }, 4753121326Sharti /* SIG_BGREJ */ { sscop_ready_bgrej, NULL }, 4754121326Sharti /* SIG_SD */ { sscop_ready_sd, NULL }, 4755121326Sharti /* SIG_ER */ { sscop_ready_er, NULL }, 4756121326Sharti /* SIG_POLL */ { sscop_ready_poll, NULL }, 4757121326Sharti /* SIG_STAT */ { sscop_ready_stat, NULL }, 4758121326Sharti /* SIG_USTAT */ { sscop_ready_ustat, NULL }, 4759121326Sharti /* SIG_UD */ { sscop_ud, NULL }, 4760121326Sharti /* SIG_MD */ { sscop_md, NULL }, 4761121326Sharti /* SIG_ERAK */ { sscop_ignore_pdu, NULL }, 4762121326Sharti /* SIG_T_CC */ { NULL, NULL }, 4763121326Sharti /* SIG_T_POLL */ { sscop_ready_tpoll, NULL }, 4764121326Sharti /* SIG_T_KA */ { sscop_ready_tka, NULL }, 4765121326Sharti /* SIG_T_NR */ { sscop_ready_nr, NULL }, 4766121326Sharti /* SIG_T_IDLE */ { sscop_ready_tidle, NULL }, 4767121326Sharti /* SIG_PDU_Q */ { sscop_ready_pduq, c_ready_pduq }, 4768121326Sharti /* SIG_USER_DATA */ { sscop_ready_userdata, NULL }, 4769121326Sharti /* SIG_ESTAB_REQ */ { NULL, NULL }, 4770121326Sharti /* SIG_ESTAB_RESP */ { NULL, NULL }, 4771121326Sharti /* SIG_RELEASE_REQ */ { sscop_ready_release_req, NULL }, 4772121326Sharti /* SIG_RECOVER */ { NULL, NULL }, 4773121326Sharti /* SIG_SYNC_REQ */ { sscop_ready_sync_req, NULL }, 4774121326Sharti /* SIG_SYNC_RESP */ { NULL, NULL }, 4775121326Sharti /* SIG_UDATA */ { sscop_udata_req, NULL }, 4776121326Sharti /* SIG_MDATA */ { sscop_mdata_req, NULL }, 4777121326Sharti /* SIG_UPDU_Q */ { sscop_upduq, NULL }, 4778121326Sharti /* SIG_MPDU_Q */ { sscop_mpduq, NULL }, 4779121326Sharti /* SIG_RETRIEVE */ { NULL, NULL }, 4780121326Sharti } 4781121326Sharti}; 4782121326Sharti 4783121326Sharti/* 4784121326Sharti * Try to execute a signal. It is executed if 4785121326Sharti * - it is illegal (in this case it is effectively ignored) 4786121326Sharti * - it has no condition 4787121326Sharti * - its condition is true 4788121326Sharti * If it has a condition and that is false, the function does nothing and 4789121326Sharti * returns 0. 4790121326Sharti * If the signal gets executed, the signal function is responsible to release 4791121326Sharti * the message (if any). 4792121326Sharti */ 4793121326Shartistatic int 4794121326Shartisig_exec(struct sscop *sscop, u_int sig, struct sscop_msg *msg) 4795121326Sharti{ 4796121326Sharti void (*func)(struct sscop *, struct sscop_msg *); 4797121326Sharti int (*cond)(struct sscop *); 4798121326Sharti 4799121326Sharti func = state_matrix[sscop->state][sig].func; 4800121326Sharti cond = state_matrix[sscop->state][sig].cond; 4801121326Sharti 4802121326Sharti if(func == NULL) { 4803121326Sharti VERBOSE(sscop, SSCOP_DBG_BUG, (sscop, sscop->aarg, 4804121326Sharti "no handler for %s in state %s - ignored", 4805121326Sharti events[sig], states[sscop->state])); 4806121326Sharti SSCOP_MSG_FREE(msg); 4807121326Sharti return 1; 4808121326Sharti } 4809121326Sharti if(cond == NULL || (*cond)(sscop)) { 4810121326Sharti VERBOSE(sscop, SSCOP_DBG_EXEC, (sscop, sscop->aarg, 4811121326Sharti "executing %s in %s", events[sig], 4812121326Sharti states[sscop->state])); 4813121326Sharti (*func)(sscop, msg); 4814121326Sharti return 1; 4815121326Sharti } 4816121326Sharti VERBOSE(sscop, SSCOP_DBG_EXEC, (sscop, sscop->aarg, 4817121326Sharti "delaying %s in %s", events[sig], 4818121326Sharti states[sscop->state])); 4819121326Sharti 4820121326Sharti return 0; 4821121326Sharti} 4822121326Sharti 4823121326Sharti/* 4824121326Sharti * Deliver a signal to the given sscop 4825121326Sharti * If it is delivered from inside a signal handler - queue it. If not, 4826121326Sharti * execute it. After execution loop through the queue and execute all 4827121326Sharti * pending signals. Signals, that cannot be executed because of entry 4828121326Sharti * conditions are skipped. 4829121326Sharti */ 4830121326Shartistatic void 4831121326Shartisscop_signal(struct sscop *sscop, u_int sig, struct sscop_msg *msg) 4832121326Sharti{ 4833121326Sharti struct sscop_sig *s; 4834121326Sharti 4835121326Sharti VERBOSE(sscop, SSCOP_DBG_INSIG, (sscop, sscop->aarg, 4836121326Sharti "got signal %s in state %s%s", events[sig], 4837121326Sharti states[sscop->state], sscop->in_sig ? " -- queuing" : "")); 4838121326Sharti 4839121326Sharti SIG_ALLOC(s); 4840121326Sharti if(s == NULL) { 4841121326Sharti FAILURE("sscop: cannot allocate signal"); 4842121326Sharti SSCOP_MSG_FREE(msg); 4843121326Sharti return; 4844121326Sharti } 4845121326Sharti s->sig = sig; 4846121326Sharti s->msg = msg; 4847121326Sharti SIGQ_APPEND(&sscop->sigs, s); 4848121326Sharti 4849121326Sharti if(!sscop->in_sig) 4850121326Sharti handle_sigs(sscop); 4851121326Sharti} 4852121326Sharti 4853121326Sharti/* 4854121326Sharti * Loop through the signal queue until we can't execute any signals. 4855121326Sharti */ 4856121326Shartistatic void 4857121326Shartihandle_sigs(struct sscop *sscop) 4858121326Sharti{ 4859121326Sharti struct sscop_sig *s; 4860121326Sharti sscop_sigq_head_t dsigs, q; 4861121326Sharti int exec; 4862121326Sharti 4863121326Sharti sscop->in_sig++; 4864121326Sharti 4865121326Sharti /* 4866121326Sharti * Copy the current signal queue to the local one and empty 4867121326Sharti * the signal queue. Then loop through the signals. After one 4868121326Sharti * pass we have a list of delayed signals because of entry 4869121326Sharti * conditions and a new list of signals. Merge them. Repeat until 4870121326Sharti * the signal queue is either empty or contains only delayed signals. 4871121326Sharti */ 4872121326Sharti SIGQ_INIT(&q); 4873121326Sharti SIGQ_INIT(&dsigs); 4874121326Sharti do { 4875121326Sharti exec = 0; 4876121326Sharti 4877121326Sharti /* 4878121326Sharti * Copy signal list and make sscop list empty 4879121326Sharti */ 4880121326Sharti SIGQ_MOVE(&sscop->sigs, &q); 4881121326Sharti 4882121326Sharti /* 4883121326Sharti * Loop through the list 4884121326Sharti */ 4885121326Sharti while((s = SIGQ_GET(&q)) != NULL) { 4886121326Sharti if(sig_exec(sscop, s->sig, s->msg)) { 4887121326Sharti exec = 1; 4888121326Sharti SIG_FREE(s); 4889121326Sharti } else { 4890121326Sharti SIGQ_APPEND(&dsigs, s); 4891121326Sharti } 4892121326Sharti } 4893121326Sharti 4894121326Sharti /* 4895121326Sharti * Merge lists by inserting delayed signals in front of 4896121326Sharti * the signal list. preserving the order. 4897121326Sharti */ 4898121326Sharti SIGQ_PREPEND(&dsigs, &sscop->sigs); 4899121326Sharti } while(exec); 4900121326Sharti sscop->in_sig--; 4901121326Sharti} 4902121326Sharti 4903121326Sharti/* 4904121326Sharti * Save a signal that should be executed only if state changes. 4905121326Sharti */ 4906121326Shartistatic void 4907121326Shartisscop_save_signal(struct sscop *sscop, u_int sig, struct sscop_msg *msg) 4908121326Sharti{ 4909121326Sharti struct sscop_sig *s; 4910121326Sharti 4911121326Sharti SIG_ALLOC(s); 4912121326Sharti if(s == NULL) { 4913121326Sharti FAILURE("sscop: cannot allocate signal"); 4914121326Sharti SSCOP_MSG_FREE(msg); 4915121326Sharti return; 4916121326Sharti } 4917121326Sharti s->sig = sig; 4918121326Sharti s->msg = msg; 4919121326Sharti SIGQ_APPEND(&sscop->saved_sigs, s); 4920121326Sharti} 4921121326Sharti 4922121326Sharti/* 4923121326Sharti * Set a new state. If signals are waiting for a state change - append them to 4924121326Sharti * the signal queue, so they get executed. 4925121326Sharti */ 4926121326Shartistatic void 4927121326Shartisscop_set_state(struct sscop *sscop, u_int nstate) 4928121326Sharti{ 4929121326Sharti VERBOSE(sscop, SSCOP_DBG_STATE, (sscop, sscop->aarg, 4930121326Sharti "changing state from %s to %s", 4931121326Sharti states[sscop->state], states[nstate])); 4932121326Sharti 4933121326Sharti sscop->state = nstate; 4934121326Sharti SIGQ_MOVE(&sscop->saved_sigs, &sscop->sigs); 4935121326Sharti} 4936121326Sharti 4937121326Shartivoid 4938121326Shartisscop_setdebug(struct sscop *sscop, u_int n) 4939121326Sharti{ 4940121326Sharti sscop->debug = n; 4941121326Sharti} 4942121326Sharti 4943121326Shartiu_int 4944121326Shartisscop_getdebug(const struct sscop *sscop) 4945121326Sharti{ 4946121326Sharti return (sscop->debug); 4947121326Sharti} 4948