📄 isdnl2.c
字号:
l2_got_ui(struct FsmInst *fi, int event, void *arg){ struct PStack *st = fi->userdata; struct sk_buff *skb = arg; skb_pull(skb, l2headersize(&st->l2, 1)); st->l2.l2l3(st, DL_UNIT_DATA | INDICATION, skb);/* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ * in states 1-3 for broadcast */}static voidl2_establish(struct FsmInst *fi, int event, void *arg){ struct PStack *st = fi->userdata; establishlink(fi); test_and_set_bit(FLG_L3_INIT, &st->l2.flag);}static voidl2_discard_i_setl3(struct FsmInst *fi, int event, void *arg){ struct PStack *st = fi->userdata; skb_queue_purge(&st->l2.i_queue); test_and_set_bit(FLG_L3_INIT, &st->l2.flag); test_and_clear_bit(FLG_PEND_REL, &st->l2.flag);}static voidl2_l3_reestablish(struct FsmInst *fi, int event, void *arg){ struct PStack *st = fi->userdata; skb_queue_purge(&st->l2.i_queue); establishlink(fi); test_and_set_bit(FLG_L3_INIT, &st->l2.flag);}static voidl2_release(struct FsmInst *fi, int event, void *arg){ struct PStack *st = fi->userdata; st->l2.l2l3(st, DL_RELEASE | CONFIRM, NULL);}static voidl2_pend_rel(struct FsmInst *fi, int event, void *arg){ struct PStack *st = fi->userdata; test_and_set_bit(FLG_PEND_REL, &st->l2.flag);}static voidl2_disconnect(struct FsmInst *fi, int event, void *arg){ struct PStack *st = fi->userdata; skb_queue_purge(&st->l2.i_queue); freewin(st); FsmChangeState(fi, ST_L2_6); st->l2.rc = 0; send_uframe(st, DISC | 0x10, CMD); FsmDelTimer(&st->l2.t203, 1); restart_t200(st, 2);}static voidl2_start_multi(struct FsmInst *fi, int event, void *arg){ struct PStack *st = fi->userdata; struct sk_buff *skb = arg; send_uframe(st, UA | get_PollFlagFree(st, skb), RSP); 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); FsmAddTimer(&st->l2.t203, st->l2.T203, EV_L2_T203, NULL, 3); st->l2.l2l3(st, DL_ESTABLISH | INDICATION, NULL);}static voidl2_send_UA(struct FsmInst *fi, int event, void *arg){ struct PStack *st = fi->userdata; struct sk_buff *skb = arg; send_uframe(st, UA | get_PollFlagFree(st, skb), RSP);}static voidl2_send_DM(struct FsmInst *fi, int event, void *arg){ struct PStack *st = fi->userdata; struct sk_buff *skb = arg; send_uframe(st, DM | get_PollFlagFree(st, skb), RSP);}static voidl2_restart_multi(struct FsmInst *fi, int event, void *arg){ struct PStack *st = fi->userdata; struct sk_buff *skb = arg; int est = 0, state; state = fi->state; send_uframe(st, UA | get_PollFlagFree(st, skb), RSP); st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'F'); if (st->l2.vs != st->l2.va) { skb_queue_purge(&st->l2.i_queue); est = 1; } 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); stop_t200(st, 3); 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_7==state) || (ST_L2_8 == state)) if (!skb_queue_empty(&st->l2.i_queue) && cansend(st)) st->l2.l2l1(st, PH_PULL | REQUEST, NULL);}static voidl2_stop_multi(struct FsmInst *fi, int event, void *arg){ struct PStack *st = fi->userdata; struct sk_buff *skb = arg; FsmChangeState(fi, ST_L2_4); FsmDelTimer(&st->l2.t203, 3); stop_t200(st, 4); send_uframe(st, UA | get_PollFlagFree(st, skb), RSP); skb_queue_purge(&st->l2.i_queue); freewin(st); lapb_dl_release_l2l3(st, INDICATION);}static voidl2_connected(struct FsmInst *fi, int event, void *arg){ struct PStack *st = fi->userdata; struct sk_buff *skb = arg; int pr=-1; if (!get_PollFlag(st, skb)) { l2_mdl_error_ua(fi, event, arg); return; } dev_kfree_skb(skb); if (test_and_clear_bit(FLG_PEND_REL, &st->l2.flag)) l2_disconnect(fi, event, arg); if (test_and_clear_bit(FLG_L3_INIT, &st->l2.flag)) { pr = DL_ESTABLISH | CONFIRM; } else if (st->l2.vs != st->l2.va) { skb_queue_purge(&st->l2.i_queue); pr = DL_ESTABLISH | INDICATION; } stop_t200(st, 5); st->l2.vr = 0; st->l2.vs = 0; st->l2.va = 0; st->l2.sow = 0; FsmChangeState(fi, ST_L2_7); FsmAddTimer(&st->l2.t203, st->l2.T203, EV_L2_T203, NULL, 4); if (pr != -1) st->l2.l2l3(st, pr, NULL); if (!skb_queue_empty(&st->l2.i_queue) && cansend(st)) st->l2.l2l1(st, PH_PULL | REQUEST, NULL);}static voidl2_released(struct FsmInst *fi, int event, void *arg){ struct PStack *st = fi->userdata; struct sk_buff *skb = arg; if (!get_PollFlag(st, skb)) { l2_mdl_error_ua(fi, event, arg); return; } dev_kfree_skb(skb); stop_t200(st, 6); lapb_dl_release_l2l3(st, CONFIRM); FsmChangeState(fi, ST_L2_4);}static voidl2_reestablish(struct FsmInst *fi, int event, void *arg){ struct PStack *st = fi->userdata; struct sk_buff *skb = arg; if (!get_PollFlagFree(st, skb)) { establishlink(fi); test_and_set_bit(FLG_L3_INIT, &st->l2.flag); }}static voidl2_st5_dm_release(struct FsmInst *fi, int event, void *arg){ struct PStack *st = fi->userdata; struct sk_buff *skb = arg; if (get_PollFlagFree(st, skb)) { stop_t200(st, 7); if (!test_bit(FLG_L3_INIT, &st->l2.flag)) skb_queue_purge(&st->l2.i_queue); if (test_bit(FLG_LAPB, &st->l2.flag)) st->l2.l2l1(st, PH_DEACTIVATE | REQUEST, NULL); st5_dl_release_l2l3(st); FsmChangeState(fi, ST_L2_4); }}static voidl2_st6_dm_release(struct FsmInst *fi, int event, void *arg){ struct PStack *st = fi->userdata; struct sk_buff *skb = arg; if (get_PollFlagFree(st, skb)) { stop_t200(st, 8); lapb_dl_release_l2l3(st, CONFIRM); FsmChangeState(fi, ST_L2_4); }}static 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; } memcpy(skb_put(skb, i), tmp, i); enqueue_super(st, skb);}static 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);}static 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); start_t200(st, 9);}static voidnrerrorrecovery(struct FsmInst *fi){ struct PStack *st = fi->userdata; st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'J'); establishlink(fi); test_and_clear_bit(FLG_L3_INIT, &st->l2.flag);}static voidinvoke_retransmission(struct PStack *st, unsigned int nr){ struct Layer2 *l2 = &st->l2; u_int p1; u_long flags; spin_lock_irqsave(&l2->lock, flags); if (l2->vs != nr) { while (l2->vs != nr) { (l2->vs)--; if(test_bit(FLG_MOD128, &l2->flag)) { l2->vs %= 128; p1 = (l2->vs - l2->va) % 128; } else { l2->vs %= 8; p1 = (l2->vs - l2->va) % 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; } spin_unlock_irqrestore(&l2->lock, flags); st->l2.l2l1(st, PH_PULL | REQUEST, NULL); return; } spin_unlock_irqrestore(&l2->lock, flags);}static voidl2_st7_got_super(struct FsmInst *fi, int event, void *arg){ struct PStack *st = fi->userdata; struct sk_buff *skb = arg; int PollFlag, rsp, typ = RR; unsigned int nr; 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, st)) { set_peer_busy(l2); typ = RNR; } else clear_peer_busy(l2); if (IsREJ(skb->data, st)) typ = REJ; if (test_bit(FLG_MOD128, &l2->flag)) { PollFlag = (skb->data[1] & 0x1) == 0x1; nr = skb->data[1] >> 1; } else { PollFlag = (skb->data[0] & 0x10); nr = (skb->data[0] >> 5) & 0x7; } dev_kfree_skb(skb); if (PollFlag) { if (rsp) st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'A'); else enquiry_response(st); } if (legalnr(st, nr)) { if (typ == REJ) { setva(st, nr); invoke_retransmission(st, nr); stop_t200(st, 10); 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); stop_t200(st, 11); FsmRestartTimer(&st->l2.t203, st->l2.T203, EV_L2_T203, NULL, 7); } else if ((l2->va != nr) || (typ == RNR)) { setva(st, nr); if(typ != RR) FsmDelTimer(&st->l2.t203, 9); restart_t200(st, 12); } if (!skb_queue_empty(&st->l2.i_queue) && (typ == RR)) st->l2.l2l1(st, PH_PULL | REQUEST, NULL); } else nrerrorrecovery(fi);}static voidl2_feed_i_if_reest(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 (!test_bit(FLG_L3_INIT, &st->l2.flag)) skb_queue_tail(&st->l2.i_queue, skb); else dev_kfree_skb(skb);}static voidl2_feed_i_pull(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); skb_queue_tail(&st->l2.i_queue, skb); st->l2.l2l1(st, PH_PULL | REQUEST, 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); skb_queue_tail(&st->l2.i_queue, skb);}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, i; unsigned int nr; i = l2addrsize(l2); if (test_bit(FLG_MOD128, &l2->flag)) { PollFlag = ((skb->data[i + 1] & 0x1) == 0x1); ns = skb->data[i] >> 1; nr = (skb->data[i + 1] >> 1) & 0x7f; } else { 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)) { dev_kfree_skb(skb); if(PollFlag) enquiry_response(st); } else if (l2->vr == ns) { (l2->vr)++; if(test_bit(FLG_MOD128, &l2->flag)) l2->vr %= 128; else l2->vr %= 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) */ dev_kfree_skb(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)) { if (!test_bit(FLG_PEER_BUSY, &st->l2.flag) && (fi->state == ST_L2_7)) { if (nr == st->l2.vs) { stop_t200(st, 13); FsmRestartTimer(&st->l2.t203, st->l2.T203, EV_L2_T203, NULL, 7); } else if (nr != st->l2.va) restart_t200(st, 14); } setva(st, nr); } else { nrerrorrecovery(fi); return; } if (!skb_queue_empty(&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_empty(&st->l2.ui_queue)) tx_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); skb_queue_purge(&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); st5_dl_release_l2l3(st); } 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); test_and_clear_bit(FLG_T200_RUN, &st->l2.flag); st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'H'); lapb_dl_release_l2l3(st, CONFIRM); } else { st->l2.rc++; FsmAddTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, 9); send_uframe(st, DISC | 0x10, CMD); }}static voidl2_st7_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); return; } test_and_clear_bit(FLG_T200_RUN, &st->l2.flag); st->l2.rc = 0; FsmChangeState(fi, ST_L2_8); transmit_enquiry(st); st->l2.rc++;}static voidl2_st8_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); return; } test_and_clear_bit(FLG_T200_RUN, &st->l2.flag); if (st->l2.rc == st->l2.N200) { st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'I'); establishlink(fi); test_and_clear_bit(FLG_L3_INIT, &st->l2.flag); } else { transmit_enquiry(st); st->l2.rc++; }}static voidl2_st7_tout_203(struct FsmInst *fi, int event, void *arg){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -