📄 callc.c
字号:
isdn_ctrl ic; ic.driver = chanp->cs->myid; ic.command = ISDN_STAT_BSENT; ic.arg = chanp->chan;// ic.parm.length = len; chanp->cs->iif.statcallb(&ic);}static intinit_b_st(struct Channel *chanp, int incoming){ struct PStack *st = chanp->b_st; struct IsdnCardState *cs = chanp->cs; char tmp[16]; st->l1.hardware = cs; if (chanp->leased) st->l1.bc = chanp->chan & 1; else st->l1.bc = chanp->proc->para.bchannel - 1; switch (chanp->l2_active_protocol) { case (ISDN_PROTO_L2_X75I): case (ISDN_PROTO_L2_HDLC): st->l1.mode = L1_MODE_HDLC; break; case (ISDN_PROTO_L2_TRANS): st->l1.mode = L1_MODE_TRANS; break;#if 0 case (ISDN_PROTO_L2_MODEM): st->l1.mode = L1_MODE_MODEM; break;#endif } if (chanp->bcs->BC_SetStack(st, chanp->bcs)) return (-1); st->l2.flag = 0; test_and_set_bit(FLG_LAPB, &st->l2.flag); st->l2.maxlen = MAX_DATA_SIZE; if (!incoming) test_and_set_bit(FLG_ORIG, &st->l2.flag); st->l2.T200 = 1000; /* 1000 milliseconds */ st->l2.window = 7; st->l2.N200 = 4; /* try 4 times */ st->l2.T203 = 5000; /* 5000 milliseconds */ st->l3.debug = 0; switch (chanp->l2_active_protocol) { case (ISDN_PROTO_L2_X75I): sprintf(tmp, "Ch%d X.75", chanp->chan); setstack_isdnl2(st, tmp); setstack_l3bc(st, chanp); st->l2.l2l3 = lldata_handler; st->lli.userdata = chanp; st->lli.l1writewakeup = NULL; st->lli.l2writewakeup = ll_writewakeup; st->l2.l2m.debug = chanp->debug & 16; st->l2.debug = chanp->debug & 64; break; case (ISDN_PROTO_L2_HDLC): case (ISDN_PROTO_L2_TRANS):// case (ISDN_PROTO_L2_MODEM): st->l1.l1l2 = lltrans_handler; st->lli.userdata = chanp; st->lli.l1writewakeup = ll_writewakeup; setstack_transl2(st); setstack_l3bc(st, chanp); break; } return (0);}static voidleased_l4l3(struct PStack *st, int pr, void *arg){ struct Channel *chanp = (struct Channel *) st->lli.userdata; struct sk_buff *skb = arg; switch (pr) { case (DL_DATA | REQUEST): link_debug(chanp, 0, "leased line d-channel DATA"); dev_kfree_skb(skb, FREE_READ); break; case (DL_ESTABLISH | REQUEST): st->l2.l2l1(st, PH_ACTIVATE | REQUEST, NULL); break; case (DL_RELEASE | REQUEST): break; default: printk(KERN_WARNING "transd_l4l3 unknown primitive %x\n", pr); break; }}static voidleased_l1l2(struct PStack *st, int pr, void *arg){ struct Channel *chanp = (struct Channel *) st->lli.userdata; struct sk_buff *skb = arg; int i,event = EV_DLRL; switch (pr) { case (PH_DATA | INDICATION): link_debug(chanp, 0, "leased line d-channel DATA"); dev_kfree_skb(skb, FREE_READ); break; case (PH_ACTIVATE | INDICATION): case (PH_ACTIVATE | CONFIRM): event = EV_DLEST; case (PH_DEACTIVATE | INDICATION): case (PH_DEACTIVATE | CONFIRM): if (test_bit(FLG_TWO_DCHAN, &chanp->cs->HW_Flags)) i = 1; else i = 0; while (i < 2) { FsmEvent(&chanp->fi, event, NULL); chanp++; i++; } break; default: printk(KERN_WARNING "transd_l1l2 unknown primitive %x\n", pr); break; }}static voidchannel_report(struct Channel *chanp){}static voiddistr_debug(struct IsdnCardState *csta, int debugflags){ int i; struct Channel *chanp = csta->channel; for (i = 0; i < 2; i++) { chanp[i].debug = debugflags; chanp[i].fi.debug = debugflags & 2; chanp[i].d_st->l2.l2m.debug = debugflags & 8; chanp[i].b_st->l2.l2m.debug = debugflags & 0x10; chanp[i].d_st->l2.debug = debugflags & 0x20; chanp[i].b_st->l2.debug = debugflags & 0x40; chanp[i].d_st->l3.l3m.debug = debugflags & 0x80; chanp[i].b_st->l3.l3m.debug = debugflags & 0x100; chanp[i].b_st->ma.tei_m.debug = debugflags & 0x200; chanp[i].b_st->ma.debug = debugflags & 0x200; chanp[i].d_st->l1.l1m.debug = debugflags & 0x1000; chanp[i].b_st->l1.l1m.debug = debugflags & 0x2000; } if (debugflags & 4) csta->debug |= DEB_DLOG_HEX; else csta->debug &= ~DEB_DLOG_HEX;}#if 0static char tmpbuf[256];static voidcapi_debug(struct Channel *chanp, capi_msg *cm){ char *t = tmpbuf; t += sprintf(tmpbuf, "%d CAPIMSG", chanp->chan); t += QuickHex(t, (u_char *)cm, (cm->Length>50)? 50: cm->Length); t--; *t= 0; HiSax_putstatus(chanp->cs, "Ch", "%d CAPIMSG %s", chanp->chan, tmpbuf);}voidlli_got_fac_req(struct Channel *chanp, capi_msg *cm) { if ((cm->para[0] != 3) || (cm->para[1] != 0)) return; if (cm->para[2]<3) return; if (cm->para[4] != 0) return; switch(cm->para[3]) { case 4: /* Suspend */ if (cm->para[5]) { strncpy(chanp->setup.phone, &cm->para[5], cm->para[5] +1); FsmEvent(&chanp->fi, EV_SUSPEND, cm); } break; case 5: /* Resume */ if (cm->para[5]) { strncpy(chanp->setup.phone, &cm->para[5], cm->para[5] +1); if (chanp->fi.state == ST_NULL) { FsmEvent(&chanp->fi, EV_RESUME, cm); } else { FsmDelTimer(&chanp->dial_timer, 72); FsmAddTimer(&chanp->dial_timer, 80, EV_RESUME, cm, 73); } } break; }}voidlli_got_manufacturer(struct Channel *chanp, struct IsdnCardState *cs, capi_msg *cm) { if ((cs->typ == ISDN_CTYPE_ELSA) || (cs->typ == ISDN_CTYPE_ELSA_PNP) || (cs->typ == ISDN_CTYPE_ELSA_PCI)) { if (cs->hw.elsa.MFlag) { cs->cardmsg(cs, CARD_AUX_IND, cm->para); } }}#endifintHiSax_command(isdn_ctrl * ic){ struct IsdnCardState *csta = hisax_findcard(ic->driver); struct Channel *chanp; int i; u_int num; u_long adr; if (!csta) { printk(KERN_ERR "HiSax: if_command %d called with invalid driverId %d!\n", ic->command, ic->driver); return -ENODEV; } switch (ic->command) { case (ISDN_CMD_SETEAZ): chanp = csta->channel + ic->arg; break; case (ISDN_CMD_SETL2): chanp = csta->channel + (ic->arg & 0xff); if (chanp->debug & 1) link_debug(chanp, 1, "SETL2 card %d %ld", csta->cardnr + 1, ic->arg >> 8); chanp->l2_protocol = ic->arg >> 8; break; case (ISDN_CMD_SETL3): chanp = csta->channel + (ic->arg & 0xff); if (chanp->debug & 1) link_debug(chanp, 1, "SETL3 card %d %ld", csta->cardnr + 1, ic->arg >> 8); chanp->l3_protocol = ic->arg >> 8; break; case (ISDN_CMD_DIAL): chanp = csta->channel + (ic->arg & 0xff); if (chanp->debug & 1) link_debug(chanp, 1, "DIAL %s -> %s (%d,%d)", ic->parm.setup.eazmsn, ic->parm.setup.phone, ic->parm.setup.si1, ic->parm.setup.si2); chanp->setup = ic->parm.setup; if (!strcmp(chanp->setup.eazmsn, "0")) chanp->setup.eazmsn[0] = '\0'; /* this solution is dirty and may be change, if * we make a callreference based callmanager */ if (chanp->fi.state == ST_NULL) { FsmEvent(&chanp->fi, EV_DIAL, NULL); } else { FsmDelTimer(&chanp->dial_timer, 70); FsmAddTimer(&chanp->dial_timer, 50, EV_DIAL, NULL, 71); } break; case (ISDN_CMD_ACCEPTB): chanp = csta->channel + ic->arg; if (chanp->debug & 1) link_debug(chanp, 1, "ACCEPTB"); FsmEvent(&chanp->fi, EV_ACCEPTB, NULL); break; case (ISDN_CMD_ACCEPTD): chanp = csta->channel + ic->arg; if (chanp->debug & 1) link_debug(chanp, 1, "ACCEPTD"); FsmEvent(&chanp->fi, EV_ACCEPTD, NULL); break; case (ISDN_CMD_HANGUP): chanp = csta->channel + ic->arg; if (chanp->debug & 1) link_debug(chanp, 1, "HANGUP"); FsmEvent(&chanp->fi, EV_HANGUP, NULL); break;#if 0 case (CAPI_PUT_MESSAGE): chanp = csta->channel + ic->arg; if (chanp->debug & 1) capi_debug(chanp, &ic->parm.cmsg); if (ic->parm.cmsg.Length < 8) break; switch(ic->parm.cmsg.Command) { case CAPI_FACILITY: if (ic->parm.cmsg.Subcommand == CAPI_REQ) lli_got_fac_req(chanp, &ic->parm.cmsg); break; case CAPI_MANUFACTURER: if (ic->parm.cmsg.Subcommand == CAPI_REQ) lli_got_manufacturer(chanp, csta, &ic->parm.cmsg); break; default: break; } break;#endif case (ISDN_CMD_LOCK): HiSax_mod_inc_use_count();#ifdef MODULE if (csta->channel[0].debug & 0x400) HiSax_putstatus(csta, " LOCK ", "modcnt %lx", MOD_USE_COUNT);#endif /* MODULE */ break; case (ISDN_CMD_UNLOCK): HiSax_mod_dec_use_count();#ifdef MODULE if (csta->channel[0].debug & 0x400) HiSax_putstatus(csta, " UNLOCK ", "modcnt %lx", MOD_USE_COUNT);#endif /* MODULE */ break; case (ISDN_CMD_IOCTL): switch (ic->arg) { case (0): HiSax_reportcard(csta->cardnr); for (i = 0; i < 2; i++) channel_report(&csta->channel[i]); break; case (1): num = *(unsigned int *) ic->parm.num; distr_debug(csta, num); printk(KERN_DEBUG "HiSax: debugging flags card %d set to %x\n", csta->cardnr + 1, num); HiSax_putstatus(csta, "debugging flags ", "card %d set to %x", csta->cardnr + 1, num); break; case (2): num = *(unsigned int *) ic->parm.num; csta->channel[0].b_st->l1.delay = num; csta->channel[1].b_st->l1.delay = num; HiSax_putstatus(csta, "delay ", "card %d set to %d ms", csta->cardnr + 1, num); printk(KERN_DEBUG "HiSax: delay card %d set to %d ms\n", csta->cardnr + 1, num); break; case (3): for (i = 0; i < *(unsigned int *) ic->parm.num; i++) HiSax_mod_dec_use_count(); break; case (4): for (i = 0; i < *(unsigned int *) ic->parm.num; i++) HiSax_mod_inc_use_count(); break; case (5): /* set card in leased mode */ num = *(unsigned int *) ic->parm.num; if ((num <1) || (num > 2)) { HiSax_putstatus(csta, "Set LEASED ", "wrong channel %d", num); printk(KERN_WARNING "HiSax: Set LEASED wrong channel %d\n", num); } else { num--; chanp = csta->channel +num; chanp->leased = 1; HiSax_putstatus(csta, "Card", "%d channel %d set leased mode\n", csta->cardnr + 1, num + 1); chanp->d_st->l1.l1l2 = leased_l1l2; chanp->d_st->lli.l4l3 = leased_l4l3; chanp->d_st->lli.l4l3(chanp->d_st, DL_ESTABLISH | REQUEST, NULL); } break; case (6): /* set B-channel test loop */ num = *(unsigned int *) ic->parm.num; if (csta->stlist) csta->stlist->l2.l2l1(csta->stlist, PH_TESTLOOP | REQUEST, (void *) (long)num); break; case (7): /* set card in PTP mode */ num = *(unsigned int *) ic->parm.num; if (test_bit(FLG_TWO_DCHAN, &csta->HW_Flags)) { printk(KERN_ERR "HiSax PTP mode only with one TEI possible\n"); } else if (num) { test_and_set_bit(FLG_PTP, &csta->channel[0].d_st->l2.flag); test_and_set_bit(FLG_FIXED_TEI, &csta->channel[0].d_st->l2.flag); csta->channel[0].d_st->l2.tei = 0; HiSax_putstatus(csta, "set card ", "in PTP mode"); printk(KERN_DEBUG "HiSax: set card in PTP mode\n"); printk(KERN_INFO "LAYER2 WATCHING ESTABLISH\n"); test_and_set_bit(FLG_START_D, &csta->channel[0].Flags); test_and_set_bit(FLG_START_D, &csta->channel[1].Flags); csta->channel[0].d_st->lli.l4l3(csta->channel[0].d_st, DL_ESTABLISH | REQUEST, NULL); } else { test_and_clear_bit(FLG_PTP, &csta->channel[0].d_st->l2.flag); test_and_clear_bit(FLG_FIXED_TEI, &csta->channel[0].d_st->l2.flag); HiSax_putstatus(csta, "set card ", "in PTMP mode"); printk(KERN_DEBUG "HiSax: set card in PTMP mode\n"); } break; case (8): /* set card in FIXED TEI mode */ num = *(unsigned int *) ic->parm.num; chanp = csta->channel + (num & 1); num = num >>1; test_and_set_bit(FLG_FIXED_TEI, &chanp->d_st->l2.flag); chanp->d_st->l2.tei = num; HiSax_putstatus(csta, "set card ", "in FIXED TEI (%d) mode", num); printk(KERN_DEBUG "HiSax: set card in FIXED TEI (%d) mode\n", num); break; case (9): /* load firmware */ memcpy(&adr, ic->parm.num, sizeof(ulong)); csta->cardmsg(csta, CARD_LOAD_FIRM, (void *) adr); break;#ifdef MODULE case (55): MOD_USE_COUNT = 0; HiSax_mod_inc_use_count(); break;#endif /* MODULE */ case (11): num = csta->debug & DEB_DLOG_HEX; csta->debug = *(unsigned int *) ic->parm.num; csta->debug |= num; HiSax_putstatus(cards[0].cs, "l1 debugging ", "flags card %d set to %x", csta->cardnr + 1, csta->debug); printk(KERN_DEBUG "HiSax: l1 debugging flags card %d set to %x\n", csta->cardnr + 1, csta->debug); break; case (13): csta->channel[0].d_st->l3.debug = *(unsigned int *) ic->parm.num; csta->channel[1].d_st->l3.debug = *(unsigned int *) ic->parm.num; HiSax_putstatus(cards[0].cs, "l3 debugging ", "flags card %d set to %x\n", csta->cardnr + 1, *(unsigned int *) ic->parm.num); printk(KERN_DEBUG "HiSax: l3 debugging flags card %d set to %x\n", csta->cardnr + 1, *(unsigned int *) ic->parm.num); break; default: printk(KERN_DEBUG "HiSax: invalid ioclt %d\n", (int) ic->arg); return (-EINVAL); } break; default: break; } return (0);}intHiSax_writebuf_skb(int id, int chan, struct sk_buff *skb){ struct IsdnCardState *csta = hisax_findcard(id); struct Channel *chanp; struct PStack *st; int len = skb->len; unsigned long flags; struct sk_buff *nskb; if (!csta) { printk(KERN_ERR "HiSax: if_sendbuf called with invalid driverId!\n"); return -ENODEV; } chanp = csta->channel + chan; st = chanp->b_st; if (!chanp->data_open) { link_debug(chanp, 1, "writebuf: channel not open"); return -EIO; } if (len > MAX_DATA_SIZE) { link_debug(chanp, 1, "writebuf: packet too large (%d bytes)", len); printk(KERN_WARNING "HiSax_writebuf: packet too large (%d bytes) !\n", len); return -EINVAL; } if (len) { if ((len + chanp->bcs->tx_cnt) > MAX_DATA_MEM) { /* Must return 0 here, since this is not an error * but a temporary lack of resources. */ if (chanp->debug & 0x800) link_debug(chanp, 1, "writebuf: no buffers for %d bytes", len); return 0; } save_flags(flags); cli(); nskb = skb_clone(skb, GFP_ATOMIC); if (nskb) {// if (!ack)// nskb->pkt_type = PACKET_NOACK; if (chanp->l2_active_protocol == ISDN_PROTO_L2_X75I) st->l3.l3l2(st, DL_DATA | REQUEST, nskb); else { chanp->bcs->tx_cnt += len; st->l2.l2l1(st, PH_DATA | REQUEST, nskb); } dev_kfree_skb(skb, FREE_WRITE); } else len = 0; restore_flags(flags); } return (len);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -