📄 capidrv.c
字号:
cmd.parm.setup.phone, cmd.parm.setup.si1, cmd.parm.setup.si2, cmd.parm.setup.eazmsn); break; case 1: /* At least one device matching this call (RING on ttyI) * HL-driver may send ALERTING on the D-channel in this * case. * really means: RING on ttyI or a net interface * accepted this call already. * * If the call was accepted, state has already changed, * and CONNECT_RESP already sent. */ if (plcip->state == ST_PLCI_INCOMING) { printk(KERN_INFO "capidrv-%d: incoming call %s,%d,%d,%s tty alerting\n", card->contrnr, cmd.parm.setup.phone, cmd.parm.setup.si1, cmd.parm.setup.si2, cmd.parm.setup.eazmsn); capi_fill_ALERT_REQ(cmsg, global.ap.applid, card->msgid++, plcip->plci, /* adr */ NULL,/* BChannelinformation */ NULL,/* Keypadfacility */ NULL,/* Useruserdata */ NULL /* Facilitydataarray */ ); plcip->msgid = cmsg->Messagenumber; send_message(card, cmsg); } else { printk(KERN_INFO "capidrv-%d: incoming call %s,%d,%d,%s on netdev\n", card->contrnr, cmd.parm.setup.phone, cmd.parm.setup.si1, cmd.parm.setup.si2, cmd.parm.setup.eazmsn); } break; case 2: /* Call will be rejected. */ capi_cmsg_answer(cmsg); cmsg->Reject = 2; /* reject call, normal call clearing */ send_message(card, cmsg); plci_change_state(card, plcip, EV_PLCI_CONNECT_REJECT); break; default: /* An error happened. (Invalid parameters for example.) */ capi_cmsg_answer(cmsg); cmsg->Reject = 8; /* reject call, destination out of order */ send_message(card, cmsg); plci_change_state(card, plcip, EV_PLCI_CONNECT_REJECT); break; } return;}static void handle_plci(_cmsg * cmsg){ capidrv_contr *card = findcontrbynumber(cmsg->adr.adrController & 0x7f); capidrv_plci *plcip; isdn_ctrl cmd; if (!card) { printk(KERN_ERR "capidrv: %s from unknown controller 0x%x\n", capi_cmd2str(cmsg->Command, cmsg->Subcommand), cmsg->adr.adrController & 0x7f); return; } switch (CAPICMD(cmsg->Command, cmsg->Subcommand)) { case CAPI_DISCONNECT_IND: /* plci */ if (cmsg->Reason) { printk(KERN_INFO "capidrv-%d: %s reason 0x%x (%s) for plci 0x%x\n", card->contrnr, capi_cmd2str(cmsg->Command, cmsg->Subcommand), cmsg->Reason, capi_info2str(cmsg->Reason), cmsg->adr.adrPLCI); } if (!(plcip = find_plci_by_plci(card, cmsg->adr.adrPLCI))) { capi_cmsg_answer(cmsg); send_message(card, cmsg); goto notfound; } card->bchans[plcip->chan].disconnecting = 1; plci_change_state(card, plcip, EV_PLCI_DISCONNECT_IND); capi_cmsg_answer(cmsg); send_message(card, cmsg); plci_change_state(card, plcip, EV_PLCI_DISCONNECT_RESP); break; case CAPI_DISCONNECT_CONF: /* plci */ if (cmsg->Info) { printk(KERN_INFO "capidrv-%d: %s info 0x%x (%s) for plci 0x%x\n", card->contrnr, capi_cmd2str(cmsg->Command, cmsg->Subcommand), cmsg->Info, capi_info2str(cmsg->Info), cmsg->adr.adrPLCI); } if (!(plcip = find_plci_by_plci(card, cmsg->adr.adrPLCI))) goto notfound; card->bchans[plcip->chan].disconnecting = 1; break; case CAPI_ALERT_CONF: /* plci */ if (cmsg->Info) { printk(KERN_INFO "capidrv-%d: %s info 0x%x (%s) for plci 0x%x\n", card->contrnr, capi_cmd2str(cmsg->Command, cmsg->Subcommand), cmsg->Info, capi_info2str(cmsg->Info), cmsg->adr.adrPLCI); } break; case CAPI_CONNECT_IND: /* plci */ handle_incoming_call(card, cmsg); break; case CAPI_CONNECT_CONF: /* plci */ if (cmsg->Info) { printk(KERN_INFO "capidrv-%d: %s info 0x%x (%s) for plci 0x%x\n", card->contrnr, capi_cmd2str(cmsg->Command, cmsg->Subcommand), cmsg->Info, capi_info2str(cmsg->Info), cmsg->adr.adrPLCI); } if (!(plcip = find_plci_by_msgid(card, cmsg->Messagenumber))) goto notfound; plcip->plci = cmsg->adr.adrPLCI; if (cmsg->Info) { plci_change_state(card, plcip, EV_PLCI_CONNECT_CONF_ERROR); } else { plci_change_state(card, plcip, EV_PLCI_CONNECT_CONF_OK); } break; case CAPI_CONNECT_ACTIVE_IND: /* plci */ if (!(plcip = find_plci_by_plci(card, cmsg->adr.adrPLCI))) goto notfound; if (card->bchans[plcip->chan].incoming) { capi_cmsg_answer(cmsg); send_message(card, cmsg); plci_change_state(card, plcip, EV_PLCI_CONNECT_ACTIVE_IND); } else { capidrv_ncci *nccip; capi_cmsg_answer(cmsg); send_message(card, cmsg); nccip = new_ncci(card, plcip, cmsg->adr.adrPLCI); if (!nccip) { printk(KERN_ERR "capidrv-%d: no mem for ncci, sorry\n", card->contrnr); break; /* $$$$ */ } capi_fill_CONNECT_B3_REQ(cmsg, global.ap.applid, card->msgid++, plcip->plci, /* adr */ NULL /* NCPI */ ); nccip->msgid = cmsg->Messagenumber; send_message(card, cmsg); cmd.command = ISDN_STAT_DCONN; cmd.driver = card->myid; cmd.arg = plcip->chan; card->interface.statcallb(&cmd); plci_change_state(card, plcip, EV_PLCI_CONNECT_ACTIVE_IND); ncci_change_state(card, nccip, EV_NCCI_CONNECT_B3_REQ); } break; case CAPI_INFO_IND: /* Controller/plci */ if (!(plcip = find_plci_by_plci(card, cmsg->adr.adrPLCI))) goto notfound; if (cmsg->InfoNumber == 0x4000) { if (cmsg->InfoElement[0] == 4) { cmd.command = ISDN_STAT_CINF; cmd.driver = card->myid; cmd.arg = plcip->chan; sprintf(cmd.parm.num, "%lu", (unsigned long) ((u32) cmsg->InfoElement[1] | ((u32) (cmsg->InfoElement[2]) << 8) | ((u32) (cmsg->InfoElement[3]) << 16) | ((u32) (cmsg->InfoElement[4]) << 24))); card->interface.statcallb(&cmd); break; } } printk(KERN_ERR "capidrv-%d: %s\n", card->contrnr, capi_cmsg2str(cmsg)); break; case CAPI_CONNECT_ACTIVE_CONF: /* plci */ goto ignored; case CAPI_SELECT_B_PROTOCOL_CONF: /* plci */ goto ignored; case CAPI_FACILITY_IND: /* Controller/plci/ncci */ goto ignored; case CAPI_FACILITY_CONF: /* Controller/plci/ncci */ goto ignored; case CAPI_INFO_CONF: /* Controller/plci */ goto ignored; default: printk(KERN_ERR "capidrv-%d: got %s for plci 0x%x ???", card->contrnr, capi_cmd2str(cmsg->Command, cmsg->Subcommand), cmsg->adr.adrPLCI); } return; ignored: printk(KERN_INFO "capidrv-%d: %s for plci 0x%x ignored\n", card->contrnr, capi_cmd2str(cmsg->Command, cmsg->Subcommand), cmsg->adr.adrPLCI); return; notfound: printk(KERN_ERR "capidrv-%d: %s: plci 0x%x not found\n", card->contrnr, capi_cmd2str(cmsg->Command, cmsg->Subcommand), cmsg->adr.adrPLCI); return;}static void handle_ncci(_cmsg * cmsg){ capidrv_contr *card = findcontrbynumber(cmsg->adr.adrController & 0x7f); capidrv_plci *plcip; capidrv_ncci *nccip; isdn_ctrl cmd; int len; if (!card) { printk(KERN_ERR "capidrv: %s from unknown controller 0x%x\n", capi_cmd2str(cmsg->Command, cmsg->Subcommand), cmsg->adr.adrController & 0x7f); return; } switch (CAPICMD(cmsg->Command, cmsg->Subcommand)) { case CAPI_CONNECT_B3_ACTIVE_IND: /* ncci */ if (!(nccip = find_ncci(card, cmsg->adr.adrNCCI))) goto notfound; capi_cmsg_answer(cmsg); send_message(card, cmsg); ncci_change_state(card, nccip, EV_NCCI_CONNECT_B3_ACTIVE_IND); cmd.command = ISDN_STAT_BCONN; cmd.driver = card->myid; cmd.arg = nccip->chan; card->interface.statcallb(&cmd); printk(KERN_INFO "capidrv-%d: chan %d up with ncci 0x%x\n", card->contrnr, nccip->chan, nccip->ncci); break; case CAPI_CONNECT_B3_ACTIVE_CONF: /* ncci */ goto ignored; case CAPI_CONNECT_B3_IND: /* ncci */ plcip = find_plci_by_ncci(card, cmsg->adr.adrNCCI); if (plcip) { nccip = new_ncci(card, plcip, cmsg->adr.adrNCCI); if (nccip) { ncci_change_state(card, nccip, EV_NCCI_CONNECT_B3_IND); capi_fill_CONNECT_B3_RESP(cmsg, global.ap.applid, card->msgid++, nccip->ncci, /* adr */ 0, /* Reject */ NULL /* NCPI */ ); send_message(card, cmsg); ncci_change_state(card, nccip, EV_NCCI_CONNECT_B3_RESP); break; } printk(KERN_ERR "capidrv-%d: no mem for ncci, sorry\n", card->contrnr); } else { printk(KERN_ERR "capidrv-%d: %s: plci for ncci 0x%x not found\n", card->contrnr, capi_cmd2str(cmsg->Command, cmsg->Subcommand), cmsg->adr.adrNCCI); } capi_fill_CONNECT_B3_RESP(cmsg, global.ap.applid, card->msgid++, cmsg->adr.adrNCCI, 2, /* Reject */ NULL /* NCPI */ ); send_message(card, cmsg); break; case CAPI_CONNECT_B3_CONF: /* ncci */ if (!(nccip = find_ncci_by_msgid(card, cmsg->adr.adrNCCI, cmsg->Messagenumber))) goto notfound; nccip->ncci = cmsg->adr.adrNCCI; if (cmsg->Info) { printk(KERN_INFO "capidrv-%d: %s info 0x%x (%s) for ncci 0x%x\n", card->contrnr, capi_cmd2str(cmsg->Command, cmsg->Subcommand), cmsg->Info, capi_info2str(cmsg->Info), cmsg->adr.adrNCCI); } if (cmsg->Info) ncci_change_state(card, nccip, EV_NCCI_CONNECT_B3_CONF_ERROR); else ncci_change_state(card, nccip, EV_NCCI_CONNECT_B3_CONF_OK); break; case CAPI_CONNECT_B3_T90_ACTIVE_IND: /* ncci */ capi_cmsg_answer(cmsg); send_message(card, cmsg); break; case CAPI_DATA_B3_IND: /* ncci */ /* handled in handle_data() */ goto ignored; case CAPI_DATA_B3_CONF: /* ncci */ if (cmsg->Info) { printk(KERN_WARNING "CAPI_DATA_B3_CONF: Info %x - %s\n", cmsg->Info, capi_info2str(cmsg->Info)); } if (!(nccip = find_ncci(card, cmsg->adr.adrNCCI))) goto notfound; len = capidrv_del_ack(nccip, cmsg->DataHandle); if (len < 0) break; cmd.command = ISDN_STAT_BSENT; cmd.driver = card->myid; cmd.arg = nccip->chan; cmd.parm.length = len; card->interface.statcallb(&cmd); break; case CAPI_DISCONNECT_B3_IND: /* ncci */ if (!(nccip = find_ncci(card, cmsg->adr.adrNCCI))) goto notfound; card->bchans[nccip->chan].disconnecting = 1; ncci_change_state(card, nccip, EV_NCCI_DISCONNECT_B3_IND); capi_cmsg_answer(cmsg); send_message(card, cmsg); ncci_change_state(card, nccip, EV_NCCI_DISCONNECT_B3_RESP); break; case CAPI_DISCONNECT_B3_CONF: /* ncci */ if (!(nccip = find_ncci(card, cmsg->adr.adrNCCI))) goto notfound; if (cmsg->Info) { printk(KERN_INFO "capidrv-%d: %s info 0x%x (%s) for ncci 0x%x\n", card->contrnr, capi_cmd2str(cmsg->Command, cmsg->Subcommand), cmsg->Info, capi_info2str(cmsg->Info), cmsg->adr.adrNCCI); ncci_change_state(card, nccip, EV_NCCI_DISCONNECT_B3_CONF_ERROR); } break; case CAPI_RESET_B3_IND: /* ncci */ if (!(nccip = find_ncci(card, cmsg->adr.adrNCCI))) goto notfound; ncci_change_state(card, nccip, EV_NCCI_RESET_B3_IND); capi_cmsg_answer(cmsg); send_message(card, cmsg); break; case CAPI_RESET_B3_CONF: /* ncci */ goto ignored; /* $$$$ */ case CAPI_FACILITY_IND: /* Controller/plci/ncci */ goto ignored; case CAPI_FACILITY_CONF: /* Controller/plci/ncci */ goto ignored; default: printk(KERN_ERR "capidrv-%d: got %s for ncci 0x%x ???", card->contrnr, capi_cmd2str(cmsg->Command, cmsg->Subcommand), cmsg->adr.adrNCCI); } return; ignored: printk(KERN_INFO "capidrv-%d: %s for ncci 0x%x ignored\n", card->contrnr, capi_cmd2str(cmsg->Command, cmsg->Subcommand), cmsg->adr.adrNCCI); return; notfound: printk(KERN_ERR "capidrv-%d: %s: ncci 0x%x not found\n", card->contrnr, capi_cmd2str(cmsg->Command, cmsg->Subcommand), cmsg->adr.adrNCCI);}static void handle_data(_cmsg * cmsg, struct sk_buff *skb){ capidrv_contr *card = findcontrbynumber(cmsg->adr.adrController & 0x7f); capidrv_ncci *nccip; if (!card) { printk(KERN_ERR "capidrv: %s from unknown controller 0x%x\n", capi_cmd2str(cmsg->Command, cmsg->Subcommand), cmsg->adr.adrController & 0x7f); kfree_skb(skb); return; } if (!(nccip = find_ncci(card, cmsg->adr.adrNCCI))) { printk(KERN_ERR "capidrv-%d: %s: ncci 0x%x not found\n", card->contrnr, capi_cmd2str(cmsg->Command, cmsg->Subcommand), cmsg->adr.adrNCCI); kfree_skb(skb); return; } (void) skb_pull(skb, CAPIMSG_LEN(skb->data)); card->interface.rcvcallb_skb(card->myid, nccip->chan, skb); capi_cmsg_answer(cmsg); send_message(card, cmsg);}static _cmsg s_cmsg;static void capidrv_recv_message(struct capi20_appl *ap, struct sk_buff *skb){ capi_message2cmsg(&s_cmsg, skb->data); if (debugmode > 3) printk(KERN_DEBUG "capidrv_signal: applid=%d %s\n", ap->applid, capi_cmsg2str(&s_cmsg)); if (s_cmsg.Command == CAPI_DATA_B3 && s_cmsg.Subcommand == CAPI_IND) { handle_data(&s_cmsg, skb); return; } if ((s_cmsg.adr.adrController & 0xffffff00) == 0) handle_controller(&s_cmsg); else if ((s_cmsg.adr.adrPLCI & 0xffff0000) == 0) handle_plci(&s_cmsg); else handle_ncci(&s_cmsg); /*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -