📄 isdnl2.c
字号:
discard_queue(&st->l2.i_queue); est = 1; } else est = 0; } clear_exception(&st->l2); st->l2.vs = 0; st->l2.va = 0; st->l2.vr = 0; st->l2.sow = 0; FsmChangeState(fi, ST_L2_7); if (test_and_clear_bit(FLG_T200_RUN, &st->l2.flag)) FsmDelTimer(&st->l2.t200, 2); FsmRestartTimer(&st->l2.t203, st->l2.T203, EV_L2_T203, NULL, 3); if (est) st->l2.l2l3(st, DL_ESTABLISH | INDICATION, NULL); if (ST_L2_8 == state) if (skb_queue_len(&st->l2.i_queue) && cansend(st)) st->l2.l2l1(st, PH_PULL | REQUEST, NULL);}static voidl2_got_disconn(struct FsmInst *fi, int event, void *arg){ struct PStack *st = fi->userdata; struct sk_buff *skb = arg; u_char PollFlag, cmd = UA; int state, rel = 1, cst = 1, rsp; state = fi->state; rsp = *skb->data & 0x2; if (test_bit(FLG_ORIG, &st->l2.flag)) rsp = !rsp; if (rsp) { st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'L'); FreeSkb(skb); if ((state == ST_L2_7) || (state == ST_L2_8)) establishlink(fi); return; } if (skb->len != (l2addrsize(&st->l2) + 1)) { st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'N'); FreeSkb(skb); if ((state == ST_L2_7) || (state == ST_L2_8)) establishlink(fi); return; } PollFlag = get_PollFlagFree(st, skb); if ((state == ST_L2_4) || (state == ST_L2_5)) { rel = 0; cst = 0; cmd = DM; } else if (state == ST_L2_6) { rel = 0; cst = 0; } if (cst) { FsmChangeState(fi, ST_L2_4); FsmDelTimer(&st->l2.t203, 3); if (test_and_clear_bit(FLG_T200_RUN, &st->l2.flag)) FsmDelTimer(&st->l2.t200, 2); } send_uframe(st, cmd | PollFlag, RSP); if (rel) { if (test_bit(FLG_LAPB, &st->l2.flag)) st->l2.l2l1(st, PH_DEACTIVATE | REQUEST, NULL); st->l2.l2l3(st, DL_RELEASE | INDICATION, NULL); }}static voidl2_got_ua(struct FsmInst *fi, int event, void *arg){ struct PStack *st = fi->userdata; struct sk_buff *skb = arg; int pr=-1; u_char PollFlag; int state,rsp; state = fi->state; rsp = *skb->data & 0x2; if (test_bit(FLG_ORIG, &st->l2.flag)) rsp = !rsp; if (!rsp) { st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'L'); FreeSkb(skb); if ((state == ST_L2_7) || (state == ST_L2_8)) establishlink(fi); return; } if (skb->len != (l2addrsize(&st->l2) + 1)) { st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'N'); FreeSkb(skb); if ((fi->state == ST_L2_7) || (fi->state == ST_L2_8)) establishlink(fi); return; } PollFlag = get_PollFlag(st, skb); if (!PollFlag) { l2_mdl_error(fi, event, arg); return; } FreeSkb(skb); if (test_and_clear_bit(FLG_T200_RUN, &st->l2.flag)) FsmDelTimer(&st->l2.t200, 2); if (fi->state == ST_L2_5) { if (test_and_clear_bit(FLG_PEND_REL, &st->l2.flag)) { discard_queue(&st->l2.i_queue); st->l2.rc = 0; send_uframe(st, DISC | 0x10, CMD); FsmChangeState(fi, ST_L2_6); FsmAddTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, 4); test_and_set_bit(FLG_T200_RUN, &st->l2.flag); } else { if (test_and_clear_bit(FLG_L3_INIT, &st->l2.flag)) { pr = DL_ESTABLISH | CONFIRM; } else if (st->l2.vs != st->l2.va) { discard_queue(&st->l2.i_queue); pr = DL_ESTABLISH | INDICATION; } st->l2.vs = 0; st->l2.va = 0; st->l2.vr = 0; st->l2.sow = 0; FsmChangeState(fi, ST_L2_7); if (pr > -1) st->l2.l2l3(st, pr, NULL); } } else { /* ST_L2_6 */ if (test_bit(FLG_LAPB, &st->l2.flag)) st->l2.l2l1(st, PH_DEACTIVATE | REQUEST, NULL); st->l2.l2l3(st, DL_RELEASE | CONFIRM, NULL); FsmChangeState(fi, ST_L2_4); }}static voidl2_got_dm(struct FsmInst *fi, int event, void *arg){ struct PStack *st = fi->userdata; struct sk_buff *skb = arg; u_char PollFlag; int state,rsp; state = fi->state; rsp = *skb->data & 0x2; if (test_bit(FLG_ORIG, &st->l2.flag)) rsp = !rsp; if (!rsp) { st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'L'); FreeSkb(skb); if ((state == ST_L2_7) || (state == ST_L2_8)) establishlink(fi); return; } if (skb->len != (l2addrsize(&st->l2) + 1)) { st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'N'); FreeSkb(skb); if ((fi->state == ST_L2_7) || (fi->state == ST_L2_8)) establishlink(fi); return; } PollFlag = get_PollFlagFree(st, skb); if (!PollFlag) { if (fi->state == ST_L2_4) { establishlink(fi); test_and_clear_bit(FLG_L3_INIT, &st->l2.flag); FsmChangeState(fi, ST_L2_5); } else if ((fi->state == ST_L2_7) || (fi->state == ST_L2_8)) { st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'E'); establishlink(fi); } } else { switch (fi->state) { case ST_L2_8: establishlink(fi); case ST_L2_7: st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'B'); break; case ST_L2_4: break; case ST_L2_5: if (test_and_clear_bit(FLG_T200_RUN, &st->l2.flag)) FsmDelTimer(&st->l2.t200, 2); discard_queue(&st->l2.i_queue); if (test_bit(FLG_LAPB, &st->l2.flag)) st->l2.l2l1(st, PH_DEACTIVATE | REQUEST, NULL); st->l2.l2l3(st, DL_RELEASE | INDICATION, NULL); FsmChangeState(fi, ST_L2_4); break; case ST_L2_6: if (test_and_clear_bit(FLG_T200_RUN, &st->l2.flag)) FsmDelTimer(&st->l2.t200, 2); if (test_bit(FLG_LAPB, &st->l2.flag)) st->l2.l2l1(st, PH_DEACTIVATE | REQUEST, NULL); st->l2.l2l3(st, DL_RELEASE | CONFIRM, NULL); FsmChangeState(fi, ST_L2_4); break; } }}inline voidenquiry_cr(struct PStack *st, u_char typ, u_char cr, u_char pf){ struct sk_buff *skb; struct Layer2 *l2; u_char tmp[MAX_HEADER_LEN]; int i; l2 = &st->l2; i = sethdraddr(l2, tmp, cr); if (test_bit(FLG_MOD128, &l2->flag)) { tmp[i++] = typ; tmp[i++] = (l2->vr << 1) | (pf ? 1 : 0); } else tmp[i++] = (l2->vr << 5) | typ | (pf ? 0x10 : 0); if (!(skb = alloc_skb(i, GFP_ATOMIC))) { printk(KERN_WARNING "isdl2 can't alloc sbbuff for enquiry_cr\n"); return; } SET_SKB_FREE(skb); memcpy(skb_put(skb, i), tmp, i); enqueue_super(st, skb);}inline voidenquiry_response(struct PStack *st){ if (test_bit(FLG_OWN_BUSY, &st->l2.flag)) enquiry_cr(st, RNR, RSP, 1); else enquiry_cr(st, RR, RSP, 1); test_and_clear_bit(FLG_ACK_PEND, &st->l2.flag);}inline voidtransmit_enquiry(struct PStack *st){ if (test_bit(FLG_OWN_BUSY, &st->l2.flag)) enquiry_cr(st, RNR, CMD, 1); else enquiry_cr(st, RR, CMD, 1); test_and_clear_bit(FLG_ACK_PEND, &st->l2.flag); FsmAddTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, 12); test_and_set_bit(FLG_T200_RUN, &st->l2.flag);}static voidnrerrorrecovery(struct FsmInst *fi){ struct PStack *st = fi->userdata; st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'J'); establishlink(fi);}static voidinvoke_retransmission(struct PStack *st, int nr){ struct Layer2 *l2 = &st->l2; int p1; long flags; if (l2->vs != nr) { save_flags(flags); cli(); while (l2->vs != nr) { l2->vs = l2->vs - 1; if (l2->vs < 0) l2->vs += (test_bit(FLG_MOD128, &l2->flag) ? 128 : 8); p1 = l2->vs - l2->va; if (p1 < 0) p1 += (test_bit(FLG_MOD128, &l2->flag) ? 128 : 8); p1 = (p1 + l2->sow) % l2->window; if (test_bit(FLG_LAPB, &l2->flag)) st->l1.bcs->tx_cnt += l2->windowar[p1]->len + l2headersize(l2, 0); skb_queue_head(&l2->i_queue, l2->windowar[p1]); l2->windowar[p1] = NULL; } restore_flags(flags); st->l2.l2l1(st, PH_PULL | REQUEST, NULL); }}static voidl2_got_st7_super(struct FsmInst *fi, int event, void *arg){ struct PStack *st = fi->userdata; struct sk_buff *skb = arg; int PollFlag, nr, rsp, typ = RR; struct Layer2 *l2 = &st->l2; rsp = *skb->data & 0x2; if (test_bit(FLG_ORIG, &l2->flag)) rsp = !rsp; skb_pull(skb, l2addrsize(l2)); if (IsRNR(skb->data, test_bit(FLG_MOD128, &l2->flag))) { test_and_set_bit(FLG_PEER_BUSY, &l2->flag); typ = RNR; } else test_and_clear_bit(FLG_PEER_BUSY, &l2->flag); if (IsREJ(skb->data, test_bit(FLG_MOD128, &l2->flag))) typ = REJ; if (test_bit(FLG_MOD128, &l2->flag)) { if (skb->len == 2) { PollFlag = (skb->data[1] & 0x1) == 0x1; nr = skb->data[1] >> 1; } else { if (skb->len >2) { st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'N'); establishlink(fi); } FreeSkb(skb); return; } } else { if (skb->len == 1) { PollFlag = (skb->data[0] & 0x10); nr = (skb->data[0] >> 5) & 0x7; } else { st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'N'); FreeSkb(skb); establishlink(fi); return; } } FreeSkb(skb); if ((!rsp) && PollFlag) enquiry_response(st); if (rsp && PollFlag) st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'A'); if (legalnr(st, nr)) { if (typ == REJ) { setva(st, nr); invoke_retransmission(st, nr); if (test_and_clear_bit(FLG_T200_RUN, &st->l2.flag)) FsmDelTimer(&st->l2.t200, 9); if (FsmAddTimer(&st->l2.t203, st->l2.T203, EV_L2_T203, NULL, 6)) l2m_debug(&st->l2.l2m, "Restart T203 ST7 REJ"); } else if ((nr == l2->vs) && (typ == RR)) { setva(st, nr); if (test_and_clear_bit(FLG_T200_RUN, &st->l2.flag)) FsmDelTimer(&st->l2.t200, 9); FsmRestartTimer(&st->l2.t203, st->l2.T203, EV_L2_T203, NULL, 7); } else if ((l2->va != nr) || (typ == RNR)) { setva(st, nr); FsmDelTimer(&st->l2.t203, 9); FsmRestartTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, 6); test_and_set_bit(FLG_T200_RUN, &st->l2.flag); } if (skb_queue_len(&st->l2.i_queue) && (typ == RR)) st->l2.l2l1(st, PH_PULL | REQUEST, NULL); } else nrerrorrecovery(fi); if ((fi->userint & LC_FLUSH_WAIT) && rsp && !(skb_queue_len(&st->l2.i_queue))) { fi->userint &= ~LC_FLUSH_WAIT; st->l2.l2l3(st, DL_FLUSH | INDICATION, NULL); }}static voidl2_feed_iqueue(struct FsmInst *fi, int event, void *arg){ struct PStack *st = fi->userdata; struct sk_buff *skb = arg; if (test_bit(FLG_LAPB, &st->l2.flag)) st->l1.bcs->tx_cnt += skb->len + l2headersize(&st->l2, 0); if (!((fi->state == ST_L2_5) && test_bit(FLG_L3_INIT, &st->l2.flag))) skb_queue_tail(&st->l2.i_queue, skb); if (fi->state == ST_L2_7) st->l2.l2l1(st, PH_PULL | REQUEST, NULL);}static voidl2_got_iframe(struct FsmInst *fi, int event, void *arg){ struct PStack *st = fi->userdata; struct sk_buff *skb = arg; struct Layer2 *l2 = &(st->l2); int PollFlag, ns, nr, i, rsp; rsp = *skb->data & 0x2; if (test_bit(FLG_ORIG, &l2->flag)) rsp = !rsp; if (rsp) { st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'L'); FreeSkb(skb); establishlink(fi); return; } i = l2addrsize(l2); if (test_bit(FLG_MOD128, &l2->flag)) { if (skb->len <= (i + 1)) { FreeSkb(skb); return; } else if ((skb->len - i - 1) > l2->maxlen) { st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'O'); FreeSkb(skb); establishlink(fi); return; } PollFlag = ((skb->data[i + 1] & 0x1) == 0x1); ns = skb->data[i] >> 1; nr = (skb->data[i + 1] >> 1) & 0x7f; } else { if (skb->len <= i) { st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'N'); FreeSkb(skb); establishlink(fi); return; } else if ((skb->len - i) > l2->maxlen) { st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'O'); FreeSkb(skb); establishlink(fi); return; } PollFlag = (skb->data[i] & 0x10); ns = (skb->data[i] >> 1) & 0x7; nr = (skb->data[i] >> 5) & 0x7; } if (test_bit(FLG_OWN_BUSY, &l2->flag)) { FreeSkb(skb); enquiry_response(st); } else if (l2->vr == ns) { l2->vr = (l2->vr + 1) % (test_bit(FLG_MOD128, &l2->flag) ? 128 : 8); test_and_clear_bit(FLG_REJEXC, &l2->flag); if (PollFlag) enquiry_response(st); else test_and_set_bit(FLG_ACK_PEND, &l2->flag); skb_pull(skb, l2headersize(l2, 0)); st->l2.l2l3(st, DL_DATA | INDICATION, skb); } else { /* n(s)!=v(r) */ FreeSkb(skb); if (test_and_set_bit(FLG_REJEXC, &l2->flag)) { if (PollFlag) enquiry_response(st); } else { enquiry_cr(st, REJ, RSP, PollFlag); test_and_clear_bit(FLG_ACK_PEND, &l2->flag); } } if (legalnr(st, nr)) { setva(st, nr); if (!test_bit(FLG_PEER_BUSY, &st->l2.flag) && (fi->state == ST_L2_7)) { if (nr == st->l2.vs) { if (test_and_clear_bit(FLG_T200_RUN, &st->l2.flag)) FsmDelTimer(&st->l2.t200, 10); FsmRestartTimer(&st->l2.t203, st->l2.T203, EV_L2_T203, NULL, 7); } else if (nr != st->l2.va) { FsmRestartTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, 8); test_and_set_bit(FLG_T200_RUN, &st->l2.flag); } } } else { nrerrorrecovery(fi); return; } if (skb_queue_len(&st->l2.i_queue) && (fi->state == ST_L2_7)) st->l2.l2l1(st, PH_PULL | REQUEST, NULL); if (test_and_clear_bit(FLG_ACK_PEND, &st->l2.flag)) enquiry_cr(st, RR, RSP, 0);}static voidl2_got_tei(struct FsmInst *fi, int event, void *arg){ struct PStack *st = fi->userdata; st->l2.tei = (long) arg; if (fi->state == ST_L2_3) { establishlink(fi); test_and_set_bit(FLG_L3_INIT, &st->l2.flag); } else FsmChangeState(fi, ST_L2_4); if (skb_queue_len(&st->l2.ui_queue)) l2_send_ui(st);}static voidl2_st5_tout_200(struct FsmInst *fi, int event, void *arg){ struct PStack *st = fi->userdata; if (test_bit(FLG_LAPD, &st->l2.flag) && test_bit(FLG_DCHAN_BUSY, &st->l2.flag)) { FsmAddTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, 9); } else if (st->l2.rc == st->l2.N200) { FsmChangeState(fi, ST_L2_4); test_and_clear_bit(FLG_T200_RUN, &st->l2.flag); discard_queue(&st->l2.i_queue); st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'G'); if (test_bit(FLG_LAPB, &st->l2.flag)) st->l2.l2l1(st, PH_DEACTIVATE | REQUEST, NULL); st->l2.l2l3(st, DL_RELEASE | INDICATION, NULL); } else { st->l2.rc++; FsmAddTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, 9); send_uframe(st, (test_bit(FLG_MOD128, &st->l2.flag) ? SABME : SABM) | 0x10, CMD); }}static voidl2_st6_tout_200(struct FsmInst *fi, int event, void *arg){ struct PStack *st = fi->userdata; if (test_bit(FLG_LAPD, &st->l2.flag) && test_bit(FLG_DCHAN_BUSY, &st->l2.flag)) { FsmAddTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, 9); } else if (st->l2.rc == st->l2.N200) { FsmChangeState(fi, ST_L2_4); st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'H'); if (test_bit(FLG_LAPB, &st->l2.flag)) st->l2.l2l1(st, PH_DEACTIVATE | REQUEST, NULL); st->l2.l2l3(st, DL_RELEASE | INDICATION, NULL); } else { st->l2.rc++; FsmAddTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, 9); send_uframe(st, DISC | 0x10, CMD); }}static voidl2_st78_tout_200(struct FsmInst *fi, int event, void *arg){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -