⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 callc.c

📁 是关于linux2.5.1的完全源码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* $Id: callc.c,v 2.51.6.6 2001/09/23 22:24:46 kai Exp $ * * Author       Karsten Keil * Copyright    by Karsten Keil      <keil@isdn4linux.de> *  * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. * * For changes and modifications please read * ../../../Documentation/isdn/HiSax.cert * * based on the teles driver from Jan den Ouden * * Thanks to    Jan den Ouden *              Fritz Elfert * */#define __NO_VERSION__#include <linux/module.h>#include <linux/init.h>#include "hisax.h"#include <linux/isdn/capicmd.h>#ifdef MODULE#define MOD_USE_COUNT ( GET_USE_COUNT (&__this_module))#endif	/* MODULE */const char *lli_revision = "$Revision: 2.51.6.6 $";extern struct IsdnCard cards[];extern int nrcards;extern void HiSax_mod_dec_use_count(struct IsdnCardState *cs);extern void HiSax_mod_inc_use_count(struct IsdnCardState *cs);static int init_b_st(struct Channel *chanp, int incoming);static void release_b_st(struct Channel *chanp);static struct Fsm callcfsm;static int chancount;/* experimental REJECT after ALERTING for CALLBACK to beat the 4s delay */#define ALERT_REJECT 0/* Value to delay the sending of the first B-channel paket after CONNECT * here is no value given by ITU, but experience shows that 300 ms will * work on many networks, if you or your other side is behind local exchanges * a greater value may be recommented. If the delay is to short the first paket * will be lost and autodetect on many comercial routers goes wrong ! * You can adjust this value on runtime with * hisaxctrl <id> 2 <value> * value is in milliseconds */#define DEFAULT_B_DELAY	300/* Flags for remembering action done in lli */#define  FLG_START_B	0/* * Find card with given driverId */static inline struct IsdnCardState *hisax_findcard(int driverid){	int i;	for (i = 0; i < nrcards; i++)		if (cards[i].cs)			if (cards[i].cs->myid == driverid)				return (cards[i].cs);	return (struct IsdnCardState *) 0;}static voidlink_debug(struct Channel *chanp, int direction, char *fmt, ...){	va_list args;	char tmp[16];	va_start(args, fmt);	sprintf(tmp, "Ch%d %s ", chanp->chan,		direction ? "LL->HL" : "HL->LL");	VHiSax_putstatus(chanp->cs, tmp, fmt, args);	va_end(args);}enum {	ST_NULL,		/*  0 inactive */	ST_OUT_DIAL,		/*  1 outgoing, SETUP send; awaiting confirm */	ST_IN_WAIT_LL,		/*  2 incoming call received; wait for LL confirm */	ST_IN_ALERT_SENT,	/*  3 incoming call received; ALERT send */	ST_IN_WAIT_CONN_ACK,	/*  4 incoming CONNECT send; awaiting CONN_ACK */	ST_WAIT_BCONN,		/*  5 CONNECT/CONN_ACK received, awaiting b-channel prot. estbl. */	ST_ACTIVE,		/*  6 active, b channel prot. established */	ST_WAIT_BRELEASE,	/*  7 call clear. (initiator), awaiting b channel prot. rel. */	ST_WAIT_BREL_DISC,	/*  8 call clear. (receiver), DISCONNECT req. received */	ST_WAIT_DCOMMAND,	/*  9 call clear. (receiver), awaiting DCHANNEL message */	ST_WAIT_DRELEASE,	/* 10 DISCONNECT sent, awaiting RELEASE */	ST_WAIT_D_REL_CNF,	/* 11 RELEASE sent, awaiting RELEASE confirm */	ST_IN_PROCEED_SEND,	/* 12 incoming call, proceeding send */ };  #define STATE_COUNT (ST_IN_PROCEED_SEND + 1)static char *strState[] ={	"ST_NULL",	"ST_OUT_DIAL",	"ST_IN_WAIT_LL",	"ST_IN_ALERT_SENT",	"ST_IN_WAIT_CONN_ACK",	"ST_WAIT_BCONN",	"ST_ACTIVE",	"ST_WAIT_BRELEASE",	"ST_WAIT_BREL_DISC",	"ST_WAIT_DCOMMAND",	"ST_WAIT_DRELEASE",	"ST_WAIT_D_REL_CNF",	"ST_IN_PROCEED_SEND",};enum {	EV_DIAL,		/*  0 */	EV_SETUP_CNF,		/*  1 */	EV_ACCEPTB,		/*  2 */	EV_DISCONNECT_IND,	/*  3 */	EV_RELEASE, 		/*  4 */	EV_LEASED,		/*  5 */	EV_LEASED_REL,		/*  6 */	EV_SETUP_IND,		/*  7 */	EV_ACCEPTD,		/*  8 */	EV_SETUP_CMPL_IND,	/*  9 */	EV_BC_EST,		/* 10 */	EV_WRITEBUF,		/* 11 */	EV_HANGUP,		/* 12 */	EV_BC_REL,		/* 13 */	EV_CINF,		/* 14 */	EV_SUSPEND,		/* 15 */	EV_RESUME,		/* 16 */	EV_NOSETUP_RSP,		/* 17 */	EV_SETUP_ERR,		/* 18 */	EV_CONNECT_ERR,		/* 19 */	EV_PROCEED,		/* 20 */	EV_ALERT,		/* 21 */ 	EV_REDIR,		/* 22 */ };#define EVENT_COUNT (EV_REDIR + 1)static char *strEvent[] ={	"EV_DIAL",	"EV_SETUP_CNF",	"EV_ACCEPTB",	"EV_DISCONNECT_IND",	"EV_RELEASE",	"EV_LEASED",	"EV_LEASED_REL",	"EV_SETUP_IND",	"EV_ACCEPTD",	"EV_SETUP_CMPL_IND",	"EV_BC_EST",	"EV_WRITEBUF",	"EV_HANGUP",	"EV_BC_REL",	"EV_CINF",	"EV_SUSPEND",	"EV_RESUME",	"EV_NOSETUP_RSP",	"EV_SETUP_ERR",	"EV_CONNECT_ERR",	"EV_PROCEED",	"EV_ALERT",	"EV_REDIR",};static inline voidHL_LL(struct Channel *chanp, int command){	isdn_ctrl ic;	ic.driver = chanp->cs->myid;	ic.command = command;	ic.arg = chanp->chan;	chanp->cs->iif.statcallb(&ic);}static inline voidlli_deliver_cause(struct Channel *chanp){	isdn_ctrl ic;	if (!chanp->proc)		return;	if (chanp->proc->para.cause == NO_CAUSE)		return;	ic.driver = chanp->cs->myid;	ic.command = ISDN_STAT_CAUSE;	ic.arg = chanp->chan;	if (chanp->cs->protocol == ISDN_PTYPE_EURO)		sprintf(ic.parm.num, "E%02X%02X", chanp->proc->para.loc & 0x7f,			chanp->proc->para.cause & 0x7f);	else		sprintf(ic.parm.num, "%02X%02X", chanp->proc->para.loc & 0x7f,			chanp->proc->para.cause & 0x7f);	chanp->cs->iif.statcallb(&ic);}static inline voidlli_close(struct FsmInst *fi){	struct Channel *chanp = fi->userdata;	FsmChangeState(fi, ST_NULL);	chanp->Flags = 0;	chanp->cs->cardmsg(chanp->cs, MDL_INFO_REL, (void *) (long)chanp->chan);}static voidlli_leased_in(struct FsmInst *fi, int event, void *arg){	struct Channel *chanp = fi->userdata;	isdn_ctrl ic;	int ret;	if (!chanp->leased)		return;	chanp->cs->cardmsg(chanp->cs, MDL_INFO_SETUP, (void *) (long)chanp->chan);	FsmChangeState(fi, ST_IN_WAIT_LL);	if (chanp->debug & 1)		link_debug(chanp, 0, "STAT_ICALL_LEASED");	ic.driver = chanp->cs->myid;	ic.command = ((chanp->chan < 2) ? ISDN_STAT_ICALL : ISDN_STAT_ICALLW);	ic.arg = chanp->chan;	ic.parm.setup.si1 = 7;	ic.parm.setup.si2 = 0;	ic.parm.setup.plan = 0;	ic.parm.setup.screen = 0;	sprintf(ic.parm.setup.eazmsn,"%d", chanp->chan + 1);	sprintf(ic.parm.setup.phone,"LEASED%d", chanp->cs->myid);	ret = chanp->cs->iif.statcallb(&ic);	if (chanp->debug & 1)		link_debug(chanp, 1, "statcallb ret=%d", ret);	if (!ret) {		chanp->cs->cardmsg(chanp->cs, MDL_INFO_REL, (void *) (long)chanp->chan);		FsmChangeState(fi, ST_NULL);	}}/* * Dial out */static voidlli_init_bchan_out(struct FsmInst *fi, int event, void *arg){	struct Channel *chanp = fi->userdata;	FsmChangeState(fi, ST_WAIT_BCONN);	if (chanp->debug & 1)		link_debug(chanp, 0, "STAT_DCONN");	HL_LL(chanp, ISDN_STAT_DCONN);	init_b_st(chanp, 0);	L4L3(chanp->b_st, DL_ESTABLISH | REQUEST, NULL);}static voidlli_prep_dialout(struct FsmInst *fi, int event, void *arg){	struct Channel *chanp = fi->userdata;	FsmDelTimer(&chanp->drel_timer, 60);	FsmDelTimer(&chanp->dial_timer, 73);	chanp->l2_active_protocol = chanp->l2_protocol;	chanp->incoming = 0;	chanp->cs->cardmsg(chanp->cs, MDL_INFO_SETUP, (void *) (long)chanp->chan);	if (chanp->leased) {		lli_init_bchan_out(fi, event, arg);	} else {		FsmChangeState(fi, ST_OUT_DIAL);		L4L3(chanp->d_st, CC_SETUP | REQUEST, chanp);	}}static voidlli_resume(struct FsmInst *fi, int event, void *arg){	struct Channel *chanp = fi->userdata;	FsmDelTimer(&chanp->drel_timer, 60);	FsmDelTimer(&chanp->dial_timer, 73);	chanp->l2_active_protocol = chanp->l2_protocol;	chanp->incoming = 0;	chanp->cs->cardmsg(chanp->cs, MDL_INFO_SETUP, (void *) (long)chanp->chan);	if (chanp->leased) {		lli_init_bchan_out(fi, event, arg);	} else {		FsmChangeState(fi, ST_OUT_DIAL);		L4L3(chanp->d_st, CC_RESUME | REQUEST, chanp);	}}static voidlli_go_active(struct FsmInst *fi, int event, void *arg){	struct Channel *chanp = fi->userdata;	isdn_ctrl ic;	FsmChangeState(fi, ST_ACTIVE);	chanp->data_open = !0;	if (chanp->bcs->conmsg)		strcpy(ic.parm.num, chanp->bcs->conmsg);	else		ic.parm.num[0] = 0;	if (chanp->debug & 1)		link_debug(chanp, 0, "STAT_BCONN %s", ic.parm.num);	ic.driver = chanp->cs->myid;	ic.command = ISDN_STAT_BCONN;	ic.arg = chanp->chan;	chanp->cs->iif.statcallb(&ic);	chanp->cs->cardmsg(chanp->cs, MDL_INFO_CONN, (void *) (long)chanp->chan);}/* * RESUME *//* incoming call */static voidlli_deliver_call(struct FsmInst *fi, int event, void *arg){	struct Channel *chanp = fi->userdata;	isdn_ctrl ic;	int ret;	chanp->cs->cardmsg(chanp->cs, MDL_INFO_SETUP, (void *) (long)chanp->chan);	/*	 * Report incoming calls only once to linklevel, use CallFlags	 * which is set to 3 with each broadcast message in isdnl1.c	 * and resetted if a interface  answered the STAT_ICALL.	 */	if (1) { /* for only one TEI */		FsmChangeState(fi, ST_IN_WAIT_LL);		if (chanp->debug & 1)			link_debug(chanp, 0, (chanp->chan < 2) ? "STAT_ICALL" : "STAT_ICALLW");		ic.driver = chanp->cs->myid;		ic.command = ((chanp->chan < 2) ? ISDN_STAT_ICALL : ISDN_STAT_ICALLW);		ic.arg = chanp->chan;		/*		 * No need to return "unknown" for calls without OAD,		 * cause that's handled in linklevel now (replaced by '0')		 */		memcpy(&ic.parm.setup, &chanp->proc->para.setup, sizeof(setup_parm));		ret = chanp->cs->iif.statcallb(&ic);		if (chanp->debug & 1)			link_debug(chanp, 1, "statcallb ret=%d", ret);		switch (ret) {			case 1:	/* OK, someone likes this call */				FsmDelTimer(&chanp->drel_timer, 61);				FsmChangeState(fi, ST_IN_ALERT_SENT);				L4L3(chanp->d_st, CC_ALERTING | REQUEST, chanp->proc);				break;			case 5: /* direct redirect */			case 4: /* Proceeding desired */				FsmDelTimer(&chanp->drel_timer, 61);				FsmChangeState(fi, ST_IN_PROCEED_SEND);				L4L3(chanp->d_st, CC_PROCEED_SEND | REQUEST, chanp->proc);				if (ret == 5) {					memcpy(&chanp->setup, &ic.parm.setup, sizeof(setup_parm));					L4L3(chanp->d_st, CC_REDIR | REQUEST, chanp->proc);				}				break;			case 2:	/* Rejecting Call */				break;			case 3:	/* incomplete number */				FsmDelTimer(&chanp->drel_timer, 61);				L4L3(chanp->d_st, CC_MORE_INFO | REQUEST, chanp->proc);				break;			case 0:	/* OK, nobody likes this call */			default:	/* statcallb problems */				L4L3(chanp->d_st, CC_IGNORE | REQUEST, chanp->proc);				chanp->cs->cardmsg(chanp->cs, MDL_INFO_REL, (void *) (long)chanp->chan);				FsmChangeState(fi, ST_NULL);				break;		}	} else {		L4L3(chanp->d_st, CC_IGNORE | REQUEST, chanp->proc);		chanp->cs->cardmsg(chanp->cs, MDL_INFO_REL, (void *) (long)chanp->chan);	}}static voidlli_send_dconnect(struct FsmInst *fi, int event, void *arg){	struct Channel *chanp = fi->userdata;	FsmChangeState(fi, ST_IN_WAIT_CONN_ACK);	L4L3(chanp->d_st, CC_SETUP | RESPONSE, chanp->proc);}static voidlli_send_alert(struct FsmInst *fi, int event, void *arg){	struct Channel *chanp = fi->userdata;	FsmChangeState(fi, ST_IN_ALERT_SENT);	L4L3(chanp->d_st, CC_ALERTING | REQUEST, chanp->proc);}static voidlli_send_redir(struct FsmInst *fi, int event, void *arg){	struct Channel *chanp = fi->userdata;	L4L3(chanp->d_st, CC_REDIR | REQUEST, chanp->proc);}static voidlli_init_bchan_in(struct FsmInst *fi, int event, void *arg){	struct Channel *chanp = fi->userdata;	FsmChangeState(fi, ST_WAIT_BCONN);	if (chanp->debug & 1)		link_debug(chanp, 0, "STAT_DCONN");	HL_LL(chanp, ISDN_STAT_DCONN);	chanp->l2_active_protocol = chanp->l2_protocol;	chanp->incoming = !0;	init_b_st(chanp, !0);	L4L3(chanp->b_st, DL_ESTABLISH | REQUEST, NULL);}static voidlli_setup_rsp(struct FsmInst *fi, int event, void *arg){	struct Channel *chanp = fi->userdata;	if (chanp->leased) {		lli_init_bchan_in(fi, event, arg);	} else {		FsmChangeState(fi, ST_IN_WAIT_CONN_ACK);#ifdef WANT_ALERT		L4L3(chanp->d_st, CC_ALERTING | REQUEST, chanp->proc);#endif		L4L3(chanp->d_st, CC_SETUP | RESPONSE, chanp->proc);	}}/* Call suspend */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -