root/drivers/isdn/teles/isdnl2.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ph_r1
  2. ph_r2
  3. ph_r3
  4. ph_r4
  5. cansend
  6. discard_i_queue
  7. discard_window
  8. l2headersize
  9. l2addrsize
  10. sethdraddr
  11. enqueue_ui
  12. enqueue_super
  13. legalnr
  14. setva
  15. l2s1
  16. l2s2
  17. l2s3
  18. establishlink
  19. l2s11
  20. l2s13
  21. l2s12
  22. l2s14
  23. l2s5
  24. l2s15
  25. l2s6
  26. l2s7
  27. l2s8
  28. l2s17
  29. enquiry_response
  30. invoke_retransmission
  31. l2s16
  32. l2s19
  33. l2s20
  34. l2s21
  35. l2s22
  36. transmit_enquiry
  37. l2s23
  38. l2s24
  39. l2s25
  40. l2s26
  41. l2s27
  42. l2s28
  43. IsUI
  44. IsUA
  45. IsDISC
  46. IsRR
  47. IsI
  48. IsSABMX
  49. IsREJ
  50. IsFRMR
  51. IsRNR
  52. isdnl2_l1l2
  53. isdnl2_l3l2
  54. isdnl2_manl2
  55. isdnl2_teil2
  56. releasestack_isdnl2
  57. l2m_debug
  58. setstack_isdnl2
  59. trans_acceptph
  60. transdown
  61. setstack_transl2
  62. releasestack_transl2
  63. Isdnl2New
  64. Isdnl2Free

   1 #define __NO_VERSION__
   2 #include "teles.h"
   3 
   4 #define TIMER_1 2000
   5 
   6 static void     l2m_debug(struct FsmInst *fi, char *s);
   7 
   8 struct Fsm      l2fsm =
   9 {NULL, 0, 0};
  10 
  11 #if 0
  12 
  13 
  14 enum {
  15         ST_PH_NULL,
  16         ST_PH_ACTIVATED,
  17         ST_PH_ACTIVE,
  18 };
  19 
  20 #define PH_STATE_COUNT (ST_PH_ACTIVE+1)
  21 
  22 static char    *strPhState[] =
  23 {
  24         "ST_PH_NULL",
  25         "ST_PH_ACTIVATED",
  26         "ST_PH_ACTIVE",
  27 };
  28 
  29 enum {
  30         EV_PH_ACTIVATE_REQ,
  31         EV_PH_ACTIVATE,
  32         EV_PH_DEACTIVATE_REQ,
  33         EV_PH_DEACTIVATE,
  34 };
  35 
  36 #define PH_EVENT_COUNT (EV_PH_DEACTIVATE+1)
  37 
  38 static char    *strPhEvent[] =
  39 {
  40         "EV_PH_ACTIVATE_REQ",
  41         "EV_PH_ACTIVATE",
  42         "EV_PH_DEACTIVATE_REQ",
  43         "EV_PH_DEACTIVATE",
  44 };
  45 
  46 #endif
  47 
  48 enum {
  49         ST_L2_1,
  50         ST_L2_3,
  51         ST_L2_4,
  52         ST_L2_5,
  53         ST_L2_6,
  54         ST_L2_7,
  55         ST_L2_8,
  56 };
  57 
  58 #define L2_STATE_COUNT (ST_L2_8+1)
  59 
  60 static char    *strL2State[] =
  61 {
  62         "ST_L2_1",
  63         "ST_L2_3",
  64         "ST_L2_4",
  65         "ST_L2_5",
  66         "ST_L2_6",
  67         "ST_L2_7",
  68         "ST_L2_8",
  69 };
  70 
  71 enum {
  72         EV_L2_UI,
  73         EV_L2_SABMX,
  74         EV_L2_UA,
  75         EV_L2_DISC,
  76         EV_L2_I,
  77         EV_L2_RR,
  78         EV_L2_REJ,
  79         EV_L2_FRMR,
  80         EV_L2_DL_DATA,
  81         EV_L2_DL_ESTABLISH,
  82         EV_L2_MDL_ASSIGN,
  83         EV_L2_DL_UNIT_DATA,
  84         EV_L2_DL_RELEASE,
  85         EV_L2_MDL_NOTEIPROC,
  86         EV_L2_T200,
  87         EV_L2_ACK_PULL,
  88         EV_L2_T203,
  89         EV_L2_RNR,
  90 };
  91 
  92 #define L2_EVENT_COUNT (EV_L2_RNR+1)
  93 
  94 static char    *strL2Event[] =
  95 {
  96         "EV_L2_UI",
  97         "EV_L2_SABMX",
  98         "EV_L2_UA",
  99         "EV_L2_DISC",
 100         "EV_L2_I",
 101         "EV_L2_RR",
 102         "EV_L2_REJ",
 103         "EV_L2_FRMR",
 104         "EV_L2_DL_DATA",
 105         "EV_L2_DL_ESTABLISH",
 106         "EV_L2_MDL_ASSIGN",
 107         "EV_L2_DL_UNIT_DATA",
 108         "EV_L2_DL_RELEASE",
 109         "EV_L2_MDL_NOTEIPROC",
 110         "EV_L2_T200",
 111         "EV_L2_ACK_PULL",
 112         "EV_L2_T203",
 113         "EV_L2_RNR",
 114 };
 115 
 116 #if 0
 117 static void
 118 ph_r1(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 119 {
 120         struct PStack  *st = fi->userdata;
 121 
 122         FsmChangeState(fi, ST_PH_ACTIVATED);
 123         st->l1.service_down(st, PH_ACTIVATE, NULL);
 124 }
 125 
 126 static void
 127 ph_r2(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 128 {
 129         struct PStack  *st = fi->userdata;
 130 
 131         FsmChangeState(fi, ST_PH_ACTIVE);
 132         st->l3.service_up(st, DL_ACTIVATE_CNF, NULL);
 133 }
 134 
 135 static void
 136 ph_r3(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 137 {
 138         struct PStack  *st = fi->userdata;
 139 
 140         FsmChangeState(fi, ST_PH_NULL);
 141         st->l1.service_down(st, PH_DEACTIVATE, NULL);
 142 }
 143 
 144 static void
 145 ph_r4(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 146 {
 147         struct PStack  *st = fi->userdata;
 148 
 149         FsmChangeState(fi, ST_PH_NULL);
 150         st->l3.service_up(st, DL_DEACTIVATE_IND, NULL);
 151 }
 152 
 153 static struct FsmNode PhFnList[] =
 154 {
 155         {ST_PH_NULL, EV_PH_ACTIVATE_REQ, ph_r1},
 156         {ST_PH_ACTIVATED, EV_PH_ACTIVATE, ph_r2},
 157         {ST_PH_ACTIVATED, EV_PH_DEACTIVATE, ph_r4},
 158         {ST_PH_ACTIVE, EV_PH_DEACTIVATE_REQ, ph_r3},
 159 };
 160 
 161 #define PH_FN_COUNT (sizeof(PhFnList)/sizeof(struct FsmNode))
 162 #endif
 163 
 164 int             errcount = 0;
 165 
 166 static int      l2addrsize(struct Layer2 *tsp);
 167 
 168 static int
 169 cansend(struct PStack *st)
     /* [previous][next][first][last][top][bottom][index][help] */
 170 {
 171         int             p1;
 172 
 173         p1 = (st->l2.va + st->l2.window) % (st->l2.extended ? 128 : 8);
 174         return (st->l2.vs != p1);
 175 }
 176 
 177 static void
 178 discard_i_queue(struct PStack *st)
     /* [previous][next][first][last][top][bottom][index][help] */
 179 {
 180         struct BufHeader *ibh;
 181 
 182         while (!BufQueueUnlink(&ibh, &st->l2.i_queue))
 183                 BufPoolRelease(ibh);
 184 }
 185 
 186 #ifdef DEFINED_BUT_NOT_USED
 187 static void
 188 discard_window(struct PStack *st)
     /* [previous][next][first][last][top][bottom][index][help] */
 189 {
 190         struct BufHeader *ibh;
 191         struct Layer2  *l2;
 192         int             i, p1, p2;
 193 
 194         l2 = &st->l2;
 195         p1 = l2->vs - l2->va;
 196         if (p1 < 0)
 197                 p1 += l2->extended ? 128 : 8;
 198 
 199         for (i = 0; i < p1; i++) {
 200                 p2 = (i + l2->sow) % l2->window;
 201                 ibh = l2->windowar[p2];
 202                 BufPoolRelease(ibh);
 203         }
 204 }
 205 #endif
 206 
 207 int
 208 l2headersize(struct Layer2 *tsp, int UI)
     /* [previous][next][first][last][top][bottom][index][help] */
 209 {
 210         return ((tsp->extended && (!UI) ? 2 : 1) + (tsp->laptype == LAPD ? 2 : 1));
 211 }
 212 
 213 int
 214 l2addrsize(struct Layer2 *tsp)
     /* [previous][next][first][last][top][bottom][index][help] */
 215 {
 216         return (tsp->laptype == LAPD ? 2 : 1);
 217 }
 218 
 219 static int
 220 sethdraddr(struct Layer2 *tsp,
     /* [previous][next][first][last][top][bottom][index][help] */
 221            struct BufHeader *ibh, int rsp)
 222 {
 223         byte           *ptr = DATAPTR(ibh);
 224         int             crbit;
 225 
 226         if (tsp->laptype == LAPD) {
 227                 crbit = rsp;
 228                 if (!tsp->orig)
 229                         crbit = !crbit;
 230                 *ptr++ = (tsp->sap << 2) | (crbit ? 2 : 0);
 231                 *ptr++ = (tsp->tei << 1) | 1;
 232                 return (2);
 233         } else {
 234                 crbit = rsp;
 235                 if (tsp->orig)
 236                         crbit = !crbit;
 237                 if (crbit)
 238                         *ptr++ = 1;
 239                 else
 240                         *ptr++ = 3;
 241                 return (1);
 242         }
 243 }
 244 
 245 static void
 246 enqueue_ui(struct PStack *st,
     /* [previous][next][first][last][top][bottom][index][help] */
 247            struct BufHeader *ibh)
 248 {
 249 #ifdef FRITZDEBUG
 250         static char     tmp[100];
 251 
 252         sprintf(tmp, "enqueue_ui: %d bytes\n", ibh->datasize);
 253         teles_putstatus(tmp);
 254 #endif
 255         st->l2.l2l1(st, PH_DATA, ibh);
 256 }
 257 
 258 static void
 259 enqueue_super(struct PStack *st,
     /* [previous][next][first][last][top][bottom][index][help] */
 260               struct BufHeader *ibh)
 261 {
 262 #ifdef FRITZDEBUG
 263         static char     tmp[100];
 264 
 265         sprintf(tmp, "enqueue_super: %d bytes\n", ibh->datasize);
 266         teles_putstatus(tmp);
 267 #endif
 268         st->l2.l2l1(st, PH_DATA, ibh);
 269 }
 270 
 271 static int
 272 legalnr(struct PStack *st, int nr)
     /* [previous][next][first][last][top][bottom][index][help] */
 273 {
 274         struct Layer2  *l2 = &st->l2;
 275         int             lnr, lvs;
 276 
 277         lvs = (l2->vs >= l2->va) ? l2->vs : (l2->vs + l2->extended ? 128 : 8);
 278         lnr = (nr >= l2->va) ? nr : (nr + l2->extended ? 128 : 8);
 279         return (lnr <= lvs);
 280 }
 281 
 282 static void
 283 setva(struct PStack *st, int nr)
     /* [previous][next][first][last][top][bottom][index][help] */
 284 {
 285         struct Layer2  *l2 = &st->l2;
 286 
 287         if (l2->va != nr) {
 288                 while (l2->va != nr) {
 289                         l2->va = (l2->va + 1) % (l2->extended ? 128 : 8);
 290                         BufPoolRelease(l2->windowar[l2->sow]);
 291                         l2->sow = (l2->sow + 1) % l2->window;
 292                 }
 293                 if (st->l4.l2writewakeup)
 294                         st->l4.l2writewakeup(st);
 295         }
 296 }
 297 
 298 static void
 299 l2s1(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 300 {
 301         struct PStack  *st = fi->userdata;
 302 
 303         st->l2.l2tei(st, MDL_ASSIGN, (void *)st->l2.ces);
 304         FsmChangeState(fi, ST_L2_3);
 305 }
 306 
 307 static void
 308 l2s2(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 309 {
 310         struct PStack  *st = fi->userdata;
 311         struct BufHeader *ibh = arg;
 312 
 313         byte           *ptr;
 314         int             i;
 315 
 316         i = sethdraddr(&(st->l2), ibh, 0);
 317         ptr = DATAPTR(ibh);
 318         ptr += i;
 319         *ptr = 0x3;
 320 
 321         enqueue_ui(st, ibh);
 322 }
 323 
 324 static void
 325 l2s3(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 326 {
 327         struct PStack  *st = fi->userdata;
 328         struct BufHeader *ibh = arg;
 329 
 330         st->l2.l2l3(st, DL_UNIT_DATA, ibh);
 331 }
 332 
 333 static void
 334 establishlink(struct FsmInst *fi)
     /* [previous][next][first][last][top][bottom][index][help] */
 335 {
 336         struct PStack  *st = fi->userdata;
 337         struct BufHeader *ibh;
 338         int             i;
 339         byte           *ptr;
 340 
 341         FsmChangeState(fi, ST_L2_5);
 342         st->l2.rc = 0;
 343 
 344         if (FsmAddTimer(&st->l2.t200_timer, st->l2.t200, EV_L2_T200, NULL, 1))
 345                 if (st->l2.l2m.debug)
 346                         l2m_debug(&st->l2.l2m, "FAT 1");
 347 
 348 
 349         if (BufPoolGet(&ibh, st->l1.smallpool, GFP_ATOMIC, (void *) st, 15))
 350                 return;
 351         i = sethdraddr(&st->l2, ibh, 0);
 352         ptr = DATAPTR(ibh);
 353         ptr += i;
 354         if (st->l2.extended)
 355                 *ptr = 0x7f;
 356         else
 357                 *ptr = 0x3f;
 358         ibh->datasize = i + 1;
 359 
 360         enqueue_super(st, ibh);
 361 }
 362 
 363 static void
 364 l2s11(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 365 {
 366         establishlink(fi);
 367 }
 368 
 369 static void
 370 l2s13(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 371 {
 372         struct PStack  *st = fi->userdata;
 373         struct Channel *chanp = st->l4.userdata;
 374         byte           *ptr;
 375         struct BufHeader *ibh;
 376         int             i;
 377 
 378         FsmChangeState(fi, ST_L2_6);
 379 
 380         FsmDelTimer(&st->l2.t203_timer, 1);
 381         if (st->l2.t200_running) {
 382                 FsmDelTimer(&st->l2.t200_timer, 2);
 383                 st->l2.t200_running = 0;
 384         }
 385         st->l2.rc = 0;
 386         if (FsmAddTimer(&st->l2.t200_timer, st->l2.t200, EV_L2_T200, NULL, 2))
 387                 if (st->l2.l2m.debug)
 388                         l2m_debug(&st->l2.l2m, "FAT 2");
 389 
 390 
 391         if ((chanp->impair == 2) && (st->l2.laptype == LAPB))
 392                 goto nodisc;
 393 
 394         if (BufPoolGet(&ibh, st->l1.smallpool, GFP_ATOMIC, (void *) st, 9))
 395                 return;
 396         i = sethdraddr(&(st->l2), ibh, 0);
 397         ptr = DATAPTR(ibh);
 398         ptr += i;
 399         *ptr = 0x53;
 400         ibh->datasize = i + 1;
 401         enqueue_super(st, ibh);
 402 
 403       nodisc:
 404         discard_i_queue(st);
 405 }
 406 
 407 static void
 408 l2s12(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 409 {
 410         struct PStack  *st = fi->userdata;
 411         struct BufHeader *ibh = arg;
 412         byte           *ptr;
 413         int             i;
 414 
 415         BufPoolRelease(ibh);
 416         st->l2.vs = 0;
 417         st->l2.va = 0;
 418         st->l2.vr = 0;
 419         st->l2.sow = 0;
 420         FsmChangeState(fi, ST_L2_7);
 421         if (FsmAddTimer(&st->l2.t203_timer, st->l2.t203, EV_L2_T203, NULL, 3))
 422                 if (st->l2.l2m.debug)
 423                         l2m_debug(&st->l2.l2m, "FAT 3");
 424 
 425         st->l2.l2man(st, DL_ESTABLISH, NULL);
 426 
 427         if (BufPoolGet(&ibh, st->l1.smallpool, GFP_ATOMIC, (void *) st, 10))
 428                 return;
 429         i = sethdraddr(&(st->l2), ibh, 0);
 430         ptr = DATAPTR(ibh);
 431         ptr += i;
 432         *ptr = 0x73;
 433         ibh->datasize = i + 1;
 434         enqueue_super(st, ibh);
 435 
 436 }
 437 
 438 static void
 439 l2s14(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 440 {
 441         struct PStack  *st = fi->userdata;
 442         struct BufHeader *ibh = arg;
 443         struct Channel *chanp = st->l4.userdata;
 444         byte           *ptr;
 445         int             i, p;
 446 
 447         ptr = DATAPTR(ibh);
 448         ptr += l2addrsize(&(st->l2));
 449         p = (*ptr) & 0x10;
 450         BufPoolRelease(ibh);
 451 
 452         FsmChangeState(fi, ST_L2_4);
 453 
 454         FsmDelTimer(&st->l2.t203_timer, 3);
 455         if (st->l2.t200_running) {
 456                 FsmDelTimer(&st->l2.t200_timer, 4);
 457                 st->l2.t200_running = 0;
 458         }
 459         if ((chanp->impair == 1) && (st->l2.laptype == LAPB))
 460                 goto noresponse;
 461 
 462         if (BufPoolGet(&ibh, st->l1.smallpool, GFP_ATOMIC, (void *) st, 11))
 463                 return;
 464         i = sethdraddr(&(st->l2), ibh, 0);
 465         ptr = DATAPTR(ibh);
 466         ptr += i;
 467         *ptr = 0x63 | (p ? 0x10 : 0x0);
 468         ibh->datasize = i + 1;
 469         enqueue_super(st, ibh);
 470 
 471       noresponse:
 472         st->l2.l2man(st, DL_RELEASE, NULL);
 473 
 474 }
 475 
 476 static void
 477 l2s5(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 478 {
 479         struct PStack  *st = fi->userdata;
 480         struct BufHeader *ibh = arg;
 481         int             f;
 482         byte           *data;
 483 
 484         data = DATAPTR(ibh);
 485         data += l2addrsize(&(st->l2));
 486 
 487         f = *data & 0x10;
 488         BufPoolRelease(ibh);
 489 
 490         if (f) {
 491                 st->l2.vs = 0;
 492                 st->l2.va = 0;
 493                 st->l2.vr = 0;
 494                 st->l2.sow = 0;
 495                 FsmChangeState(fi, ST_L2_7);
 496 
 497                 FsmDelTimer(&st->l2.t200_timer, 5);
 498                 if (FsmAddTimer(&st->l2.t203_timer, st->l2.t203, EV_L2_T203, NULL, 4))
 499                         if (st->l2.l2m.debug)
 500                                 l2m_debug(&st->l2.l2m, "FAT 4");
 501 
 502 
 503                 st->l2.l2man(st, DL_ESTABLISH, NULL);
 504         }
 505 }
 506 
 507 static void
 508 l2s15(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 509 {
 510         struct PStack  *st = fi->userdata;
 511         struct BufHeader *ibh = arg;
 512         int             f;
 513         byte           *data;
 514 
 515         data = DATAPTR(ibh);
 516         data += l2addrsize(&st->l2);
 517 
 518         f = *data & 0x10;
 519         BufPoolRelease(ibh);
 520 
 521         if (f) {
 522                 FsmDelTimer(&st->l2.t200_timer, 6);
 523                 FsmChangeState(fi, ST_L2_4);
 524                 st->l2.l2man(st, DL_RELEASE, NULL);
 525         }
 526 }
 527 
 528 static void
 529 l2s6(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 530 {
 531         struct PStack  *st = fi->userdata;
 532         struct Channel *chanp = st->l4.userdata;
 533         struct BufHeader *ibh = arg;
 534         int             p, i, seq, rsp;
 535         byte           *ptr;
 536         struct Layer2  *l2;
 537 
 538         l2 = &st->l2;
 539         ptr = DATAPTR(ibh);
 540 
 541         if (l2->laptype == LAPD) {
 542                 rsp = ptr[0] & 0x2;
 543                 if (l2->orig)
 544                         rsp = !rsp;
 545         } else {
 546                 rsp = ptr[0] == 0x3;
 547                 if (l2->orig)
 548                         rsp = !rsp;
 549         }
 550 
 551         ptr += l2addrsize(l2);
 552 
 553         if (l2->extended) {
 554                 p = (ptr[1] & 0x1) == 0x1;
 555                 seq = ptr[1] >> 1;
 556         } else {
 557                 p = (ptr[0] & 0x10);
 558                 seq = (ptr[0] >> 5) & 0x7;
 559         }
 560         BufPoolRelease(ibh);
 561 
 562         if ((chanp->impair == 4) && (st->l2.laptype == LAPB))
 563                 goto noresp;
 564 
 565         if ((!rsp) && p) {
 566                 if (!BufPoolGet(&ibh, st->l1.smallpool, GFP_ATOMIC, (void *) st, 12)) {
 567                         i = sethdraddr(l2, ibh, !0);
 568                         ptr = DATAPTR(ibh);
 569                         ptr += i;
 570 
 571                         if (l2->extended) {
 572                                 *ptr++ = 0x1;
 573                                 *ptr++ = (l2->vr << 1) | (p ? 1 : 0);
 574                                 i += 2;
 575                         } else {
 576                                 *ptr++ = (l2->vr << 5) | 0x1 | (p ? 0x10 : 0x0);
 577                                 i += 1;
 578                         }
 579                         ibh->datasize = i;
 580                         enqueue_super(st, ibh);
 581                 }
 582         }
 583       noresp:
 584         if (legalnr(st, seq))
 585                 if (seq == st->l2.vs) {
 586                         setva(st, seq);
 587                         FsmDelTimer(&st->l2.t200_timer, 7);
 588                         st->l2.t200_running = 0;
 589                         FsmDelTimer(&st->l2.t203_timer, 8);
 590                         if (FsmAddTimer(&st->l2.t203_timer, st->l2.t203, EV_L2_T203, NULL, 5))
 591                                 if (st->l2.l2m.debug)
 592                                         l2m_debug(&st->l2.l2m, "FAT 5");
 593 
 594                         if (st->l2.i_queue.head)
 595                                 st->l2.l2l1(st, PH_REQUEST_PULL, NULL);
 596                 } else if (st->l2.va != seq) {
 597                         setva(st, seq);
 598                         FsmDelTimer(&st->l2.t200_timer, 9);
 599                         if (FsmAddTimer(&st->l2.t200_timer, st->l2.t200, EV_L2_T200, NULL, 6))
 600                                 if (st->l2.l2m.debug)
 601                                         l2m_debug(&st->l2.l2m, "FAT 6");
 602 
 603                         if (st->l2.i_queue.head)
 604                                 st->l2.l2l1(st, PH_REQUEST_PULL, NULL);
 605                 }
 606 }
 607 
 608 static void
 609 l2s7(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 610 {
 611         struct PStack  *st = fi->userdata;
 612         struct BufHeader *ibh = arg;
 613         int             i;
 614         byte           *ptr;
 615         struct IsdnCardState *sp = st->l1.hardware;
 616         char            str[64];
 617 
 618         i = sethdraddr(&st->l2, ibh, 0);
 619         ptr = DATAPTR(ibh);
 620 
 621         if (st->l2.laptype == LAPD)
 622                 if (sp->dlogflag) {
 623                         sprintf(str, "Q.931 frame user->network tei %d", st->l2.tei);
 624                         dlogframe(sp, ptr + st->l2.ihsize, ibh->datasize - st->l2.ihsize,
 625                                   str);
 626                 }
 627         BufQueueLink(&st->l2.i_queue, ibh);
 628 
 629         st->l2.l2l1(st, PH_REQUEST_PULL, NULL);
 630 }
 631 
 632 static void
 633 l2s8(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 634 {
 635         struct PStack  *st = fi->userdata;
 636         struct Channel *chanp = st->l4.userdata;
 637         struct BufHeader *ibh = arg;
 638         byte           *ptr;
 639         struct BufHeader *ibh2;
 640         struct IsdnCardState *sp = st->l1.hardware;
 641         struct Layer2  *l2 = &(st->l2);
 642         int             i, p, seq, nr, wasok;
 643         char            str[64];
 644 
 645         ptr = DATAPTR(ibh);
 646         ptr += l2addrsize(l2);
 647         if (l2->extended) {
 648                 p = (ptr[1] & 0x1) == 0x1;
 649                 seq = ptr[0] >> 1;
 650                 nr = (ptr[1] >> 1) & 0x7f;
 651         } else {
 652                 p = (ptr[0] & 0x10);
 653                 seq = (ptr[0] >> 1) & 0x7;
 654                 nr = (ptr[0] >> 5) & 0x7;
 655         }
 656 
 657         if (l2->vr == seq) {
 658                 wasok = !0;
 659 
 660                 l2->vr = (l2->vr + 1) % (l2->extended ? 128 : 8);
 661                 l2->rejexp = 0;
 662 
 663                 ptr = DATAPTR(ibh);
 664                 if (st->l2.laptype == LAPD)
 665                         if (sp->dlogflag) {
 666                                 sprintf(str, "Q.931 frame network->user tei %d", st->l2.tei);
 667                                 dlogframe(st->l1.hardware, ptr + l2->ihsize,
 668                                         ibh->datasize - l2->ihsize, str);
 669                         }
 670               label8_1:
 671                 if ((chanp->impair == 3) && (st->l2.laptype == LAPB))
 672                         goto noRR;
 673 
 674                 if (!BufPoolGet(&ibh2, st->l1.smallpool, GFP_ATOMIC, (void *) st, 13)) {
 675                         i = sethdraddr(&(st->l2), ibh2, p);
 676                         ptr = DATAPTR(ibh2);
 677                         ptr += i;
 678 
 679                         if (l2->extended) {
 680                                 *ptr++ = 0x1;
 681                                 *ptr++ = (l2->vr << 1) | (p ? 1 : 0);
 682                                 i += 2;
 683                         } else {
 684                                 *ptr++ = (l2->vr << 5) | 0x1 | (p ? 0x10 : 0x0);
 685                                 i += 1;
 686                         }
 687                         ibh2->datasize = i;
 688                         enqueue_super(st, ibh2);
 689                       noRR:
 690                 }
 691         } else {
 692                 /* n(s)!=v(r) */
 693                 wasok = 0;
 694                 BufPoolRelease(ibh);
 695                 if (st->l2.rejexp) {
 696                         if (p)
 697                                 goto label8_1;
 698                 } else {
 699                         st->l2.rejexp = !0;
 700                         if (!BufPoolGet(&ibh2, st->l1.smallpool, GFP_ATOMIC, (void *) st, 14)) {
 701                                 i = sethdraddr(&(st->l2), ibh2, p);
 702                                 ptr = DATAPTR(ibh2);
 703                                 ptr += i;
 704 
 705                                 if (l2->extended) {
 706                                         *ptr++ = 0x9;
 707                                         *ptr++ = (l2->vr << 1) | (p ? 1 : 0);
 708                                         i += 2;
 709                                 } else {
 710                                         *ptr++ = (l2->vr << 5) | 0x9 | (p ? 0x10 : 0x0);
 711                                         i += 1;
 712                                 }
 713                                 ibh2->datasize = i;
 714                                 enqueue_super(st, ibh2);
 715                         }
 716                 }
 717         }
 718 
 719         if (legalnr(st, nr))
 720                 if (nr == st->l2.vs) {
 721                         setva(st, nr);
 722                         FsmDelTimer(&st->l2.t200_timer, 10);
 723                         st->l2.t200_running = 0;
 724                         FsmDelTimer(&st->l2.t203_timer, 11);
 725                         if (FsmAddTimer(&st->l2.t203_timer, st->l2.t203, EV_L2_T203, NULL, 7))
 726                                 if (st->l2.l2m.debug)
 727                                         l2m_debug(&st->l2.l2m, "FAT 5");
 728 
 729                         if (st->l2.i_queue.head)
 730                                 st->l2.l2l1(st, PH_REQUEST_PULL, NULL);
 731                 } else if (nr != st->l2.va) {
 732                         setva(st, nr);
 733                         FsmDelTimer(&st->l2.t200_timer, 12);
 734                         if (FsmAddTimer(&st->l2.t200_timer, st->l2.t200, EV_L2_T200, NULL, 8))
 735                                 if (st->l2.l2m.debug)
 736                                         l2m_debug(&st->l2.l2m, "FAT 6");
 737 
 738                         if (st->l2.i_queue.head)
 739                                 st->l2.l2l1(st, PH_REQUEST_PULL, NULL);
 740                 }
 741         if (wasok)
 742                 st->l2.l2l3(st, DL_DATA, ibh);
 743 
 744 }
 745 
 746 static void
 747 l2s17(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 748 {
 749         struct PStack  *st = fi->userdata;
 750 
 751         st->l2.tei = (int) arg;
 752         establishlink(fi);
 753 }
 754 
 755 static void
 756 enquiry_response(struct PStack *st)
     /* [previous][next][first][last][top][bottom][index][help] */
 757 {
 758         struct BufHeader *ibh2;
 759         int             i;
 760         byte           *ptr;
 761         struct Layer2  *l2;
 762 
 763         l2 = &st->l2;
 764         if (!BufPoolGet(&ibh2, st->l1.smallpool, GFP_ATOMIC, (void *) st, 16)) {
 765                 i = sethdraddr(&(st->l2), ibh2, !0);
 766                 ptr = DATAPTR(ibh2);
 767                 ptr += i;
 768 
 769                 if (l2->extended) {
 770                         *ptr++ = 0x1;
 771                         *ptr++ = (l2->vr << 1) | 0x1;
 772                         i += 2;
 773                 } else {
 774                         *ptr++ = (l2->vr << 5) | 0x1 | 0x10;
 775                         i += 1;
 776                 }
 777                 ibh2->datasize = i;
 778                 enqueue_super(st, ibh2);
 779         }
 780 }
 781 
 782 static void
 783 invoke_retransmission(struct PStack *st, int nr)
     /* [previous][next][first][last][top][bottom][index][help] */
 784 {
 785         struct Layer2  *l2 = &st->l2;
 786         int             p1;
 787 
 788         if (l2->vs != nr) {
 789                 while (l2->vs != nr) {
 790 
 791                         l2->vs = l2->vs - 1;
 792                         if (l2->vs < 0)
 793                                 l2->vs += l2->extended ? 128 : 8;
 794 
 795                         p1 = l2->vs - l2->va;
 796                         if (p1 < 0)
 797                                 p1 += l2->extended ? 128 : 8;
 798                         p1 = (p1 + l2->sow) % l2->window;
 799 
 800                         BufQueueLinkFront(&l2->i_queue, l2->windowar[p1]);
 801                 }
 802                 st->l2.l2l1(st, PH_REQUEST_PULL, NULL);
 803         }
 804 }
 805 
 806 static void
 807 l2s16(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 808 {
 809         struct PStack  *st = fi->userdata;
 810         struct BufHeader *ibh = arg;
 811         int             p, seq, rsp;
 812         byte           *ptr;
 813         struct Layer2  *l2;
 814 
 815         l2 = &(st->l2);
 816         ptr = DATAPTR(ibh);
 817 
 818         if (l2->laptype == LAPD) {
 819                 rsp = ptr[0] & 0x2;
 820                 if (l2->orig)
 821                         rsp = !rsp;
 822         } else {
 823                 rsp = ptr[0] == 0x3;
 824                 if (l2->orig)
 825                         rsp = !rsp;
 826         }
 827 
 828 
 829         ptr += l2addrsize(l2);
 830 
 831         if (l2->extended) {
 832                 p = (ptr[1] & 0x1) == 0x1;
 833                 seq = ptr[1] >> 1;
 834         } else {
 835                 p = (ptr[0] & 0x10);
 836                 seq = (ptr[0] >> 5) & 0x7;
 837         }
 838         BufPoolRelease(ibh);
 839 
 840         if ((!rsp) && p)
 841                 enquiry_response(st);
 842 
 843         if (!legalnr(st, seq))
 844                 return;
 845 
 846         setva(st, seq);
 847         invoke_retransmission(st, seq);
 848 
 849 }
 850 
 851 static void
 852 l2s19(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 853 {
 854         FsmChangeState(fi, ST_L2_4);
 855 }
 856 
 857 static void
 858 l2s20(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 859 {
 860         struct PStack  *st = fi->userdata;
 861         int             i;
 862         struct BufHeader *ibh;
 863         byte           *ptr;
 864 
 865         if (st->l2.rc == st->l2.n200) {
 866                 FsmChangeState(fi, ST_L2_4);
 867                 st->l2.l2man(st, DL_RELEASE, NULL);
 868         } else {
 869                 st->l2.rc++;
 870 
 871                 if (FsmAddTimer(&st->l2.t200_timer, st->l2.t200, EV_L2_T200, NULL, 9))
 872                         if (st->l2.l2m.debug)
 873                                 l2m_debug(&st->l2.l2m, "FAT 7");
 874 
 875                 if (BufPoolGet(&ibh, st->l1.smallpool, GFP_ATOMIC, (void *) st, 15))
 876                         return;
 877 
 878                 i = sethdraddr(&st->l2, ibh, 0);
 879                 ptr = DATAPTR(ibh);
 880                 ptr += i;
 881                 if (st->l2.extended)
 882                         *ptr = 0x7f;
 883                 else
 884                         *ptr = 0x3f;
 885                 ibh->datasize = i + 1;
 886                 enqueue_super(st, ibh);
 887         }
 888 }
 889 
 890 static void
 891 l2s21(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 892 {
 893         struct PStack  *st = fi->userdata;
 894         struct Channel *chanp = st->l4.userdata;
 895         int             i;
 896         struct BufHeader *ibh;
 897         byte           *ptr;
 898 
 899         if (st->l2.rc == st->l2.n200) {
 900                 FsmChangeState(fi, ST_L2_4);
 901                 st->l2.l2man(st, DL_RELEASE, NULL);
 902         } else {
 903                 st->l2.rc++;
 904 
 905                 if (FsmAddTimer(&st->l2.t200_timer, st->l2.t200, EV_L2_T200, NULL, 10))
 906                         if (st->l2.l2m.debug)
 907                                 l2m_debug(&st->l2.l2m, "FAT 8");
 908 
 909 
 910                 if ((chanp->impair == 2) && (st->l2.laptype == LAPB))
 911                         goto nodisc;
 912 
 913                 if (BufPoolGet(&ibh, st->l1.smallpool, GFP_ATOMIC, (void *) st, 15))
 914                         return;
 915 
 916                 i = sethdraddr(&st->l2, ibh, 0);
 917                 ptr = DATAPTR(ibh);
 918                 ptr += i;
 919                 *ptr = 0x53;
 920                 ibh->datasize = i + 1;
 921                 enqueue_super(st, ibh);
 922               nodisc:
 923 
 924         }
 925 }
 926 
 927 static void
 928 l2s22(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 929 {
 930         struct PStack  *st = fi->userdata;
 931         struct BufHeader *ibh;
 932         struct Layer2  *l2 = &st->l2;
 933         byte           *ptr;
 934         int             p1;
 935 
 936         if (!cansend(st))
 937                 return;
 938 
 939         if (BufQueueUnlink(&ibh, &l2->i_queue))
 940                 return;
 941 
 942 
 943         p1 = l2->vs - l2->va;
 944         if (p1 < 0)
 945                 p1 += l2->extended ? 128 : 8;
 946         p1 = (p1 + l2->sow) % l2->window;
 947         l2->windowar[p1] = ibh;
 948 
 949         ptr = DATAPTR(ibh);
 950         ptr += l2addrsize(l2);
 951 
 952         if (l2->extended) {
 953                 *ptr++ = l2->vs << 1;
 954                 *ptr++ = (l2->vr << 1) | 0x1;
 955                 l2->vs = (l2->vs + 1) % 128;
 956         } else {
 957                 *ptr++ = (l2->vr << 5) | (l2->vs << 1) | 0x10;
 958                 l2->vs = (l2->vs + 1) % 8;
 959         }
 960 
 961         st->l2.l2l1(st, PH_DATA_PULLED, ibh);
 962 
 963         if (!st->l2.t200_running) {
 964                 FsmDelTimer(&st->l2.t203_timer, 13);
 965                 if (FsmAddTimer(&st->l2.t200_timer, st->l2.t200, EV_L2_T200, NULL, 11))
 966                         if (st->l2.l2m.debug)
 967                                 l2m_debug(&st->l2.l2m, "FAT 9");
 968 
 969                 st->l2.t200_running = !0;
 970         }
 971         if (l2->i_queue.head && cansend(st))
 972                 st->l2.l2l1(st, PH_REQUEST_PULL, NULL);
 973 
 974 }
 975 
 976 static void
 977 transmit_enquiry(struct PStack *st)
     /* [previous][next][first][last][top][bottom][index][help] */
 978 {
 979         struct BufHeader *ibh;
 980         byte           *ptr;
 981 
 982         if (!BufPoolGet(&ibh, st->l1.smallpool, GFP_ATOMIC, (void *) st, 12)) {
 983                 ptr = DATAPTR(ibh);
 984                 ptr += sethdraddr(&st->l2, ibh, 0);
 985 
 986                 if (st->l2.extended) {
 987                         *ptr++ = 0x1;
 988                         *ptr++ = (st->l2.vr << 1) | 1;
 989                 } else {
 990                         *ptr++ = (st->l2.vr << 5) | 0x11;
 991                 }
 992                 ibh->datasize = ptr - DATAPTR(ibh);
 993                 enqueue_super(st, ibh);
 994                 if (FsmAddTimer(&st->l2.t200_timer, st->l2.t200, EV_L2_T200, NULL, 12))
 995                         if (st->l2.l2m.debug)
 996                                 l2m_debug(&st->l2.l2m, "FAT 10");
 997 
 998                 st->l2.t200_running = !0;
 999         }
1000 }
1001 
1002 static void
1003 l2s23(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
1004 {
1005         struct PStack  *st = fi->userdata;
1006 
1007         st->l2.t200_running = 0;
1008 
1009         st->l2.rc = 1;
1010         FsmChangeState(fi, ST_L2_8);
1011         transmit_enquiry(st);
1012 }
1013 
1014 static void
1015 l2s24(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
1016 {
1017         struct PStack  *st = fi->userdata;
1018         struct BufHeader *ibh = arg;
1019         int             p, seq, rsp;
1020         byte           *ptr;
1021         struct Layer2  *l2;
1022 
1023         l2 = &st->l2;
1024         ptr = DATAPTR(ibh);
1025 
1026         if (l2->laptype == LAPD) {
1027                 rsp = ptr[0] & 0x2;
1028                 if (l2->orig)
1029                         rsp = !rsp;
1030         } else {
1031                 rsp = ptr[0] == 0x3;
1032                 if (l2->orig)
1033                         rsp = !rsp;
1034         }
1035 
1036 
1037         ptr += l2addrsize(l2);
1038 
1039         if (l2->extended) {
1040                 p = (ptr[1] & 0x1) == 0x1;
1041                 seq = ptr[1] >> 1;
1042         } else {
1043                 p = (ptr[0] & 0x10);
1044                 seq = (ptr[0] >> 5) & 0x7;
1045         }
1046         BufPoolRelease(ibh);
1047 
1048         if (rsp && p) {
1049                 if (legalnr(st, seq)) {
1050                         FsmChangeState(fi, ST_L2_7);
1051                         setva(st, seq);
1052                         if (st->l2.t200_running) {
1053                                 FsmDelTimer(&st->l2.t200_timer, 14);
1054                                 st->l2.t200_running = 0;
1055                         }
1056                         if (FsmAddTimer(&st->l2.t203_timer, st->l2.t203, EV_L2_T203, NULL, 13))
1057                                 if (st->l2.l2m.debug)
1058                                         l2m_debug(&st->l2.l2m, "FAT 11");
1059 
1060                         invoke_retransmission(st, seq);
1061                 }
1062         } else {
1063                 if (!rsp && p)
1064                         enquiry_response(st);
1065                 if (legalnr(st, seq)) {
1066                         setva(st, seq);
1067                 }
1068         }
1069 }
1070 
1071 static void
1072 l2s25(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
1073 {
1074         struct PStack  *st = fi->userdata;
1075 
1076         st->l2.rc = 0;
1077         FsmChangeState(fi, ST_L2_8);
1078         transmit_enquiry(st);
1079 }
1080 
1081 static void
1082 l2s26(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
1083 {
1084         struct PStack  *st = fi->userdata;
1085 
1086         if (st->l2.rc == st->l2.n200) {
1087                 l2s13(fi, event, NULL);
1088         } else {
1089                 st->l2.rc++;
1090                 transmit_enquiry(st);
1091         }
1092 }
1093 
1094 static void
1095 l2s27(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
1096 {
1097         struct PStack  *st = fi->userdata;
1098         struct BufHeader *ibh = arg;
1099         byte           *ptr;
1100         int             i, p, est;
1101 
1102         ptr = DATAPTR(ibh);
1103         ptr += l2addrsize(&st->l2);
1104 
1105         if (st->l2.extended)
1106                 p = ptr[1] & 0x1;
1107         else
1108                 p = ptr[0] & 0x10;
1109 
1110         BufPoolRelease(ibh);
1111 
1112         if (BufPoolGet(&ibh, st->l1.smallpool, GFP_ATOMIC, (void *) st, 10))
1113                 return;
1114         i = sethdraddr(&st->l2, ibh, 0);
1115         ptr = DATAPTR(ibh);
1116         ptr += i;
1117         *ptr = 0x63 | p;
1118         ibh->datasize = i + 1;
1119         enqueue_super(st, ibh);
1120 
1121         if (st->l2.vs != st->l2.va) {
1122                 discard_i_queue(st);
1123                 est = !0;
1124         } else
1125                 est = 0;
1126 
1127         FsmDelTimer(&st->l2.t200_timer, 15);
1128         st->l2.t200_running = 0;
1129 
1130         if (FsmAddTimer(&st->l2.t203_timer, st->l2.t203, EV_L2_T203, NULL, 3))
1131                 if (st->l2.l2m.debug)
1132                         l2m_debug(&st->l2.l2m, "FAT 12");
1133 
1134         st->l2.vs = 0;
1135         st->l2.va = 0;
1136         st->l2.vr = 0;
1137         st->l2.sow = 0;
1138 
1139 
1140         if (est)
1141                 st->l2.l2man(st, DL_ESTABLISH, NULL);
1142 
1143 }
1144 
1145 static void
1146 l2s28(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
1147 {
1148         struct PStack  *st = fi->userdata;
1149         struct BufHeader *ibh = arg;
1150         byte           *ptr;
1151         char            tmp[64];
1152 
1153         ptr = DATAPTR(ibh);
1154         ptr += l2addrsize(&st->l2);
1155         ptr++;
1156 
1157         if (st->l2.l2m.debug) {
1158                 if (st->l2.extended)
1159                         sprintf(tmp, "FRMR information %2x %2x %2x %2x %2x",
1160                                 ptr[0], ptr[1], ptr[2], ptr[3], ptr[4]);
1161                 else
1162                         sprintf(tmp, "FRMR information %2x %2x %2x",
1163                                 ptr[0], ptr[1], ptr[2]);
1164 
1165                 l2m_debug(&st->l2.l2m, tmp);
1166         }
1167         BufPoolRelease(ibh);
1168 }
1169 
1170 static int
1171 IsUI(byte * data, int ext)
     /* [previous][next][first][last][top][bottom][index][help] */
1172 {
1173         return ((data[0] & 0xef) == 0x3);
1174 }
1175 
1176 static int
1177 IsUA(byte * data, int ext)
     /* [previous][next][first][last][top][bottom][index][help] */
1178 {
1179         return ((data[0] & 0xef) == 0x63);
1180 }
1181 
1182 static int
1183 IsDISC(byte * data, int ext)
     /* [previous][next][first][last][top][bottom][index][help] */
1184 {
1185         return ((data[0] & 0xef) == 0x43);
1186 }
1187 
1188 static int
1189 IsRR(byte * data, int ext)
     /* [previous][next][first][last][top][bottom][index][help] */
1190 {
1191         if (ext)
1192                 return (data[0] == 0x1);
1193         else
1194                 return ((data[0] & 0xf) == 1);
1195 }
1196 
1197 static int
1198 IsI(byte * data, int ext)
     /* [previous][next][first][last][top][bottom][index][help] */
1199 {
1200         return ((data[0] & 0x1) == 0x0);
1201 }
1202 
1203 static int
1204 IsSABMX(byte * data, int ext)
     /* [previous][next][first][last][top][bottom][index][help] */
1205 {
1206         return (ext ? data[0] == 0x7f : data[0] == 0x3f);
1207 }
1208 
1209 static int
1210 IsREJ(byte * data, int ext)
     /* [previous][next][first][last][top][bottom][index][help] */
1211 {
1212         return (ext ? data[0] == 0x9 : (data[0] & 0xf) == 0x9);
1213 }
1214 
1215 static int
1216 IsFRMR(byte * data, int ext)
     /* [previous][next][first][last][top][bottom][index][help] */
1217 {
1218         return ((data[0] & 0xef) == 0x87);
1219 }
1220 
1221 static int
1222 IsRNR(byte * data, int ext)
     /* [previous][next][first][last][top][bottom][index][help] */
1223 {
1224         if (ext)
1225                 return (data[0] == 0x5);
1226         else
1227                 return ((data[0] & 0xf) == 5);
1228 }
1229 
1230 static struct FsmNode L2FnList[] =
1231 {
1232         {ST_L2_1, EV_L2_DL_ESTABLISH, l2s1},
1233         {ST_L2_1, EV_L2_MDL_NOTEIPROC, l2s19},
1234         {ST_L2_3, EV_L2_MDL_ASSIGN, l2s17},
1235         {ST_L2_4, EV_L2_DL_UNIT_DATA, l2s2},
1236         {ST_L2_4, EV_L2_DL_ESTABLISH, l2s11},
1237         {ST_L2_7, EV_L2_DL_UNIT_DATA, l2s2},
1238         {ST_L2_7, EV_L2_DL_DATA, l2s7},
1239         {ST_L2_7, EV_L2_DL_RELEASE, l2s13},
1240         {ST_L2_7, EV_L2_ACK_PULL, l2s22},
1241         {ST_L2_8, EV_L2_DL_RELEASE, l2s13},
1242 
1243         {ST_L2_1, EV_L2_UI, l2s3},
1244         {ST_L2_4, EV_L2_UI, l2s3},
1245         {ST_L2_4, EV_L2_SABMX, l2s12},
1246         {ST_L2_5, EV_L2_UA, l2s5},
1247         {ST_L2_6, EV_L2_UA, l2s15},
1248         {ST_L2_7, EV_L2_UI, l2s3},
1249         {ST_L2_7, EV_L2_DISC, l2s14},
1250         {ST_L2_7, EV_L2_I, l2s8},
1251         {ST_L2_7, EV_L2_RR, l2s6},
1252         {ST_L2_7, EV_L2_REJ, l2s16},
1253         {ST_L2_7, EV_L2_SABMX, l2s27},
1254         {ST_L2_7, EV_L2_FRMR, l2s28},
1255         {ST_L2_8, EV_L2_RR, l2s24},
1256         {ST_L2_8, EV_L2_DISC, l2s14},
1257         {ST_L2_8, EV_L2_FRMR, l2s28},
1258 
1259         {ST_L2_5, EV_L2_T200, l2s20},
1260         {ST_L2_6, EV_L2_T200, l2s21},
1261         {ST_L2_7, EV_L2_T200, l2s23},
1262         {ST_L2_7, EV_L2_T203, l2s25},
1263         {ST_L2_8, EV_L2_T200, l2s26},
1264 };
1265 
1266 #define L2_FN_COUNT (sizeof(L2FnList)/sizeof(struct FsmNode))
1267 
1268 static void
1269 isdnl2_l1l2(struct PStack *st, int pr, struct BufHeader *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
1270 {
1271         struct BufHeader *ibh;
1272         byte           *datap;
1273         int             ret = !0;
1274 
1275         switch (pr) {
1276           case (PH_DATA):
1277 
1278                   ibh = arg;
1279                   datap = DATAPTR(ibh);
1280                   datap += l2addrsize(&st->l2);
1281 
1282                   if (IsI(datap, st->l2.extended))
1283                           ret = FsmEvent(&st->l2.l2m, EV_L2_I, ibh);
1284                   else if (IsRR(datap, st->l2.extended))
1285                           ret = FsmEvent(&st->l2.l2m, EV_L2_RR, ibh);
1286                   else if (IsUI(datap, st->l2.extended))
1287                           ret = FsmEvent(&st->l2.l2m, EV_L2_UI, ibh);
1288                   else if (IsSABMX(datap, st->l2.extended))
1289                           ret = FsmEvent(&st->l2.l2m, EV_L2_SABMX, ibh);
1290                   else if (IsUA(datap, st->l2.extended))
1291                           ret = FsmEvent(&st->l2.l2m, EV_L2_UA, ibh);
1292                   else if (IsDISC(datap, st->l2.extended))
1293                           ret = FsmEvent(&st->l2.l2m, EV_L2_DISC, ibh);
1294                   else if (IsREJ(datap, st->l2.extended))
1295                           ret = FsmEvent(&st->l2.l2m, EV_L2_REJ, ibh);
1296                   else if (IsFRMR(datap, st->l2.extended))
1297                           ret = FsmEvent(&st->l2.l2m, EV_L2_FRMR, ibh);
1298                   else if (IsRNR(datap, st->l2.extended))
1299                           ret = FsmEvent(&st->l2.l2m, EV_L2_RNR, ibh);
1300 
1301                   if (ret)
1302                           BufPoolRelease(ibh);
1303 
1304                   break;
1305           case (PH_PULL_ACK):
1306                   FsmEvent(&st->l2.l2m, EV_L2_ACK_PULL, arg);
1307                   break;
1308         }
1309 }
1310 
1311 static void
1312 isdnl2_l3l2(struct PStack *st, int pr,
     /* [previous][next][first][last][top][bottom][index][help] */
1313             void *arg)
1314 {
1315         switch (pr) {
1316           case (DL_DATA):
1317                   if (FsmEvent(&st->l2.l2m, EV_L2_DL_DATA, arg))
1318                           BufPoolRelease((struct BufHeader *) arg);
1319                   break;
1320           case (DL_UNIT_DATA):
1321                   if (FsmEvent(&st->l2.l2m, EV_L2_DL_UNIT_DATA, arg))
1322                           BufPoolRelease((struct BufHeader *) arg);
1323                   break;
1324         }
1325 }
1326 
1327 static void
1328 isdnl2_manl2(struct PStack *st, int pr,
     /* [previous][next][first][last][top][bottom][index][help] */
1329              void *arg)
1330 {
1331         switch (pr) {
1332           case (DL_ESTABLISH):
1333                   FsmEvent(&st->l2.l2m, EV_L2_DL_ESTABLISH, arg);
1334                   break;
1335           case (DL_RELEASE):
1336                   FsmEvent(&st->l2.l2m, EV_L2_DL_RELEASE, arg);
1337                   break;
1338           case (MDL_NOTEIPROC):
1339                   FsmEvent(&st->l2.l2m, EV_L2_MDL_NOTEIPROC, NULL);
1340                   break;
1341         }
1342 }
1343 
1344 static void
1345 isdnl2_teil2(struct PStack *st, int pr,
     /* [previous][next][first][last][top][bottom][index][help] */
1346              void *arg)
1347 {
1348         switch (pr) {
1349           case (MDL_ASSIGN):
1350                   FsmEvent(&st->l2.l2m, EV_L2_MDL_ASSIGN, arg);
1351                   break;
1352         }
1353 }
1354 
1355 void
1356 releasestack_isdnl2(struct PStack *st)
     /* [previous][next][first][last][top][bottom][index][help] */
1357 {
1358         FsmDelTimer(&st->l2.t200_timer, 15);
1359         FsmDelTimer(&st->l2.t203_timer, 16);
1360 }
1361 
1362 static void
1363 l2m_debug(struct FsmInst *fi, char *s)
     /* [previous][next][first][last][top][bottom][index][help] */
1364 {
1365         struct PStack  *st = fi->userdata;
1366         char            tm[32], str[256];
1367 
1368         jiftime(tm, jiffies);
1369         sprintf(str, "%s %s %s\n", tm, st->l2.debug_id, s);
1370         teles_putstatus(str);
1371 }
1372 
1373 
1374 void
1375 setstack_isdnl2(struct PStack *st, char *debug_id)
     /* [previous][next][first][last][top][bottom][index][help] */
1376 {
1377         st->l1.l1l2 = isdnl2_l1l2;
1378         st->l3.l3l2 = isdnl2_l3l2;
1379         st->ma.manl2 = isdnl2_manl2;
1380         st->ma.teil2 = isdnl2_teil2;
1381 
1382         st->l2.uihsize = l2headersize(&st->l2, !0);
1383         st->l2.ihsize = l2headersize(&st->l2, 0);
1384         BufQueueInit(&(st->l2.i_queue));
1385         st->l2.rejexp = 0;
1386         st->l2.debug = 1;
1387 
1388         st->l2.l2m.fsm = &l2fsm;
1389         st->l2.l2m.state = ST_L2_1;
1390         st->l2.l2m.debug = 0;
1391         st->l2.l2m.userdata = st;
1392         st->l2.l2m.printdebug = l2m_debug;
1393         strcpy(st->l2.debug_id, debug_id);
1394 
1395         FsmInitTimer(&st->l2.l2m, &st->l2.t200_timer);
1396         FsmInitTimer(&st->l2.l2m, &st->l2.t203_timer);
1397         st->l2.t200_running = 0;
1398 }
1399 
1400 #ifdef DEFINED_BUT_NOT_USED
1401 static void
1402 trans_acceptph(struct PStack *st, struct BufHeader *ibh)
     /* [previous][next][first][last][top][bottom][index][help] */
1403 {
1404 #if 0
1405         st->l3.service_up(st, DL_DATA, ibh);
1406 #endif
1407 }
1408 
1409 
1410 static void
1411 transdown(struct PStack *st, int pr,
     /* [previous][next][first][last][top][bottom][index][help] */
1412           struct BufHeader *ibh)
1413 {
1414         if (pr == DL_DATA) {
1415                 ibh->primitive = !0;
1416                 st->l2.l2l1(st, PH_DATA, ibh);
1417         }
1418 }
1419 #endif
1420 
1421 void
1422 setstack_transl2(struct PStack *st)
     /* [previous][next][first][last][top][bottom][index][help] */
1423 {
1424 #if 0
1425         st->l2.phdata_up = trans_acceptph;
1426         st->l2.service_down = (void *) transdown;
1427         st->l2.ihsize = 0;
1428         st->l2.debug = 0;
1429 #endif
1430 }
1431 
1432 void
1433 releasestack_transl2(struct PStack *st)
     /* [previous][next][first][last][top][bottom][index][help] */
1434 {
1435 }
1436 
1437 void
1438 Isdnl2New(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1439 {
1440         l2fsm.state_count = L2_STATE_COUNT;
1441         l2fsm.event_count = L2_EVENT_COUNT;
1442         l2fsm.strEvent = strL2Event;
1443         l2fsm.strState = strL2State;
1444         FsmNew(&l2fsm, L2FnList, L2_FN_COUNT);
1445 }
1446 
1447 void
1448 Isdnl2Free(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1449 {
1450         FsmFree(&l2fsm);
1451 }

/* [previous][next][first][last][top][bottom][index][help] */