📄 callc.c
字号:
event = EV_LEASED; 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 voiddistr_debug(struct IsdnCardState *csta, int debugflags){ int i; struct Channel *chanp = csta->channel; for (i = 0; i < (2 + MAX_WAITING_CALLS) ; 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;}static char tmpbuf[256];static voidcapi_debug(struct Channel *chanp, capi_msg *cm){ char *t = tmpbuf; 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 */ strncpy(chanp->setup.phone, &cm->para[5], cm->para[5] +1); FsmEvent(&chanp->fi, EV_SUSPEND, cm); break; case 5: /* Resume */ 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); } }}/***************************************************************//* Limit the available number of channels for the current card *//***************************************************************/static int set_channel_limit(struct IsdnCardState *cs, int chanmax){ isdn_ctrl ic; int i, ii; if ((chanmax < 0) || (chanmax > 2)) return(-EINVAL); cs->chanlimit = 0; for (ii = 0; ii < 2; ii++) { ic.driver = cs->myid; ic.command = ISDN_STAT_DISCH; ic.arg = ii; if (ii >= chanmax) ic.parm.num[0] = 0; /* disabled */ else ic.parm.num[0] = 1; /* enabled */ i = cs->iif.statcallb(&ic); if (i) return(-EINVAL); if (ii < chanmax) cs->chanlimit++; } return(0);} /* set_channel_limit */intHiSax_command(isdn_ctrl * ic){ struct IsdnCardState *csta = hisax_findcard(ic->driver); struct PStack *st; struct Channel *chanp; int i; u_int num; 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); memcpy(&chanp->setup, &ic->parm.setup, sizeof(setup_parm)); 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; memcpy(&chanp->setup, &ic->parm.setup, sizeof(setup_parm)); 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; 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; 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): num = *(unsigned int *) ic->parm.num; HiSax_reportcard(csta->cardnr, num); 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"); 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; if (num == 127) { test_and_clear_bit(FLG_FIXED_TEI, &chanp->d_st->l2.flag); chanp->d_st->l2.tei = -1; HiSax_putstatus(csta, "set card ", "in VAR TEI mode"); printk(KERN_DEBUG "HiSax: set card in VAR TEI mode\n"); } else { 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); } chanp->d_st->lli.l4l3(chanp->d_st, DL_ESTABLISH | REQUEST, NULL); 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; case (10): i = *(unsigned int *) ic->parm.num; return(set_channel_limit(csta, i)); default: if (csta->auxcmd) return(csta->auxcmd(csta, ic)); printk(KERN_DEBUG "HiSax: invalid ioclt %d\n", (int) ic->arg); return (-EINVAL); } break; case (ISDN_CMD_PROCEED): chanp = csta->channel + ic->arg; if (chanp->debug & 1) link_debug(chanp, 1, "PROCEED"); FsmEvent(&chanp->fi, EV_PROCEED, NULL); break; case (ISDN_CMD_ALERT): chanp = csta->channel + ic->arg; if (chanp->debug & 1) link_debug(chanp, 1, "ALERT"); FsmEvent(&chanp->fi, EV_ALERT, NULL); break; case (ISDN_CMD_REDIR): chanp = csta->channel + ic->arg; if (chanp->debug & 1) link_debug(chanp, 1, "REDIR"); memcpy(&chanp->setup, &ic->parm.setup, sizeof(setup_parm)); FsmEvent(&chanp->fi, EV_REDIR, NULL); break; /* protocol specific io commands */ case (ISDN_CMD_PROT_IO): for (st = csta->stlist; st; st = st->next) if (st->protocol == (ic->arg & 0xFF)) return(st->lli.l4l3_proto(st, ic)); return(-EINVAL); break; default: if (csta->auxcmd) return(csta->auxcmd(csta, ic)); return(-EINVAL); } return (0);}intHiSax_writebuf_skb(int id, int chan, int ack, 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; } else if (chanp->debug & 0x800) link_debug(chanp, 1, "writebuf %d/%d/%d", len, chanp->bcs->tx_cnt,MAX_DATA_MEM); 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); } else len = 0; restore_flags(flags); } return (len);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -