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

📄 chan_dahdi.c

📁 Asterisk中信道部分的源码 。。。。
💻 C
📖 第 1 页 / 共 5 页
字号:
	unsigned int ignoredtmf:1;	unsigned int immediate:1;			/*!< Answer before getting digits? */	unsigned int inalarm:1;	unsigned int unknown_alarm:1;	unsigned int mate:1;				/*!< flag to say its in MATE mode */	unsigned int outgoing:1;	unsigned int overlapdial:1;	unsigned int permcallwaiting:1;	unsigned int permhidecallerid:1;		/*!< Whether to hide our outgoing caller ID or not */	unsigned int priindication_oob:1;	unsigned int priexclusive:1;	unsigned int pulse:1;	unsigned int pulsedial:1;			/*!< whether a pulse dial phone is detected */	unsigned int restartpending:1;		/*!< flag to ensure counted only once for restart */	unsigned int restrictcid:1;			/*!< Whether restrict the callerid -> only send ANI */	unsigned int threewaycalling:1;	unsigned int transfer:1;	unsigned int use_callerid:1;			/*!< Whether or not to use caller id on this channel */	unsigned int use_callingpres:1;			/*!< Whether to use the callingpres the calling switch sends */	unsigned int usedistinctiveringdetection:1;	unsigned int dahditrcallerid:1;			/*!< should we use the callerid from incoming call on dahdi transfer or not */	unsigned int transfertobusy:1;			/*!< allow flash-transfers to busy channels */#if defined(HAVE_PRI)	unsigned int alerting:1;	unsigned int alreadyhungup:1;	unsigned int isidlecall:1;	unsigned int proceeding:1;	unsigned int progress:1;	unsigned int resetting:1;	unsigned int setup_ack:1;#endif	unsigned int use_smdi:1;		/* Whether to use SMDI on this channel */	struct ast_smdi_interface *smdi_iface;	/* The serial port to listen for SMDI data on */	struct dahdi_distRings drings;	char context[AST_MAX_CONTEXT];	char defcontext[AST_MAX_CONTEXT];	char exten[AST_MAX_EXTENSION];	char language[MAX_LANGUAGE];	char mohinterpret[MAX_MUSICCLASS];	char mohsuggest[MAX_MUSICCLASS];#ifdef PRI_ANI	char cid_ani[AST_MAX_EXTENSION];#endif	char cid_num[AST_MAX_EXTENSION];	int cid_ton;					/*!< Type Of Number (TON) */	char cid_name[AST_MAX_EXTENSION];	char lastcid_num[AST_MAX_EXTENSION];	char lastcid_name[AST_MAX_EXTENSION];	char *origcid_num;				/*!< malloced original callerid */	char *origcid_name;				/*!< malloced original callerid */	char callwait_num[AST_MAX_EXTENSION];	char callwait_name[AST_MAX_EXTENSION];	char rdnis[AST_MAX_EXTENSION];	char dnid[AST_MAX_EXTENSION];	ast_group_t group;	int law;	int confno;					/*!< Our conference */	int confusers;					/*!< Who is using our conference */	int propconfno;					/*!< Propagated conference number */	ast_group_t callgroup;	ast_group_t pickupgroup;	int channel;					/*!< Channel Number or CRV */	int span;					/*!< Span number */	time_t guardtime;				/*!< Must wait this much time before using for new call */	int cid_signalling;				/*!< CID signalling type bell202 or v23 */	int cid_start;					/*!< CID start indicator, polarity or ring */	int callingpres;				/*!< The value of callling presentation that we're going to use when placing a PRI call */	int callwaitingrepeat;				/*!< How many samples to wait before repeating call waiting */	int cidcwexpire;				/*!< When to expire our muting for CID/CW */	unsigned char *cidspill;	int cidpos;	int cidlen;	int ringt;	int ringt_base;	int stripmsd;	int callwaitcas;	int callwaitrings;	int echocancel;	int echotraining;	char echorest[20];	int busycount;	int busy_tonelength;	int busy_quietlength;	int callprogress;	struct timeval flashtime;			/*!< Last flash-hook time */	struct ast_dsp *dsp;	int cref;					/*!< Call reference number */	struct dahdi_dialoperation dop;	int whichwink;					/*!< SIG_FEATDMF_TA Which wink are we on? */	char finaldial[64];	char accountcode[AST_MAX_ACCOUNT_CODE];		/*!< Account code */	int amaflags;					/*!< AMA Flags */	struct tdd_state *tdd;				/*!< TDD flag */	char call_forward[AST_MAX_EXTENSION];	char mailbox[AST_MAX_EXTENSION];	char dialdest[256];	int onhooktime;	int msgstate;	int distinctivering;				/*!< Which distinctivering to use */	int cidrings;					/*!< Which ring to deliver CID on */	int dtmfrelax;					/*!< whether to run in relaxed DTMF mode */	int fake_event;	int polarityonanswerdelay;	struct timeval polaritydelaytv;	int sendcalleridafter;#ifdef HAVE_PRI	struct dahdi_pri *pri;	struct dahdi_pvt *bearer;	struct dahdi_pvt *realcall;	q931_call *call;	int prioffset;	int logicalspan;#endif		int polarity;	int dsp_features;	char begindigit;} *iflist = NULL, *ifend = NULL;/*! \brief Channel configuration from chan_dahdi.conf . * This struct is used for parsing the [channels] section of chan_dahdi.conf. * Generally there is a field here for every possible configuration item. * * The state of fields is saved along the parsing and whenever a 'channel' * statement is reached, the current dahdi_chan_conf is used to configure the  * channel (struct dahdi_pvt) * * @seealso dahdi_chan_init for the default values. */struct dahdi_chan_conf {	struct dahdi_pvt chan;#ifdef HAVE_PRI	struct dahdi_pri pri;#endif	struct dahdi_params timing;	char smdi_port[SMDI_MAX_FILENAME_LEN];};/** returns a new dahdi_chan_conf with default values (by-value) */static struct dahdi_chan_conf dahdi_chan_conf_default(void) {	/* recall that if a field is not included here it is initialized	 * to 0 or equivalent	 */	struct dahdi_chan_conf conf = {#ifdef HAVE_PRI		.pri = {			.nsf = PRI_NSF_NONE,			.switchtype = PRI_SWITCH_NI2,			.dialplan = PRI_NATIONAL_ISDN + 1,			.localdialplan = PRI_NATIONAL_ISDN + 1,			.nodetype = PRI_CPE,			.minunused = 2,			.idleext = "",			.idledial = "",			.internationalprefix = "",			.nationalprefix = "",			.localprefix = "",			.privateprefix = "",			.unknownprefix = "",			.resetinterval = 3600		},#endif		.chan = {			.context = "default",			.cid_num = "",			.cid_name = "",			.mohinterpret = "default",			.mohsuggest = "",			.transfertobusy = 1,			.cid_signalling = CID_SIG_BELL,			.cid_start = CID_START_RING,			.dahditrcallerid = 0,			.use_callerid = 1,			.sig = -1,			.outsigmod = -1,			.tonezone = -1,			.echocancel = 1,			.busycount = 3,			.accountcode = "",			.mailbox = "",			.polarityonanswerdelay = 600,			.sendcalleridafter = DEFAULT_CIDRINGS,			.buf_policy = DAHDI_POLICY_IMMEDIATE,			.buf_no = numbufs		},		.timing = {			.prewinktime = -1,			.preflashtime = -1,			.winktime = -1,			.flashtime = -1,			.starttime = -1,			.rxwinktime = -1,			.rxflashtime = -1,			.debouncetime = -1		},		.smdi_port = "/dev/ttyS0",	};	return conf;}static struct ast_channel *dahdi_request(const char *type, int format, void *data, int *cause);static int dahdi_digit_begin(struct ast_channel *ast, char digit);static int dahdi_digit_end(struct ast_channel *ast, char digit, unsigned int duration);static int dahdi_sendtext(struct ast_channel *c, const char *text);static int dahdi_call(struct ast_channel *ast, char *rdest, int timeout);static int dahdi_hangup(struct ast_channel *ast);static int dahdi_answer(struct ast_channel *ast);static struct ast_frame *dahdi_read(struct ast_channel *ast);static int dahdi_write(struct ast_channel *ast, struct ast_frame *frame);static struct ast_frame *dahdi_exception(struct ast_channel *ast);static int dahdi_indicate(struct ast_channel *chan, int condition, const void *data, size_t datalen);static int dahdi_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);static int dahdi_setoption(struct ast_channel *chan, int option, void *data, int datalen);static int dahdi_func_read(struct ast_channel *chan, char *function, char *data, char *buf, size_t len); static const struct ast_channel_tech dahdi_tech = {	.type = "DAHDI",	.description = tdesc,	.capabilities = AST_FORMAT_SLINEAR | AST_FORMAT_ULAW | AST_FORMAT_ALAW,	.requester = dahdi_request,	.send_digit_begin = dahdi_digit_begin,	.send_digit_end = dahdi_digit_end,	.send_text = dahdi_sendtext,	.call = dahdi_call,	.hangup = dahdi_hangup,	.answer = dahdi_answer,	.read = dahdi_read,	.write = dahdi_write,	.bridge = dahdi_bridge,	.exception = dahdi_exception,	.indicate = dahdi_indicate,	.fixup = dahdi_fixup,	.setoption = dahdi_setoption,	.func_channel_read = dahdi_func_read,};static const struct ast_channel_tech zap_tech = {	.type = "Zap",	.description = tdesc,	.capabilities = AST_FORMAT_SLINEAR | AST_FORMAT_ULAW | AST_FORMAT_ALAW,	.requester = dahdi_request,	.send_digit_begin = dahdi_digit_begin,	.send_digit_end = dahdi_digit_end,	.send_text = dahdi_sendtext,	.call = dahdi_call,	.hangup = dahdi_hangup,	.answer = dahdi_answer,	.read = dahdi_read,	.write = dahdi_write,	.bridge = dahdi_bridge,	.exception = dahdi_exception,	.indicate = dahdi_indicate,	.fixup = dahdi_fixup,	.setoption = dahdi_setoption,	.func_channel_read = dahdi_func_read,};static const struct ast_channel_tech *chan_tech;#ifdef HAVE_PRI#define GET_CHANNEL(p) ((p)->bearer ? (p)->bearer->channel : p->channel)#else#define GET_CHANNEL(p) ((p)->channel)#endifstruct dahdi_pvt *round_robin[32];#ifdef HAVE_PRIstatic inline int pri_grab(struct dahdi_pvt *pvt, struct dahdi_pri *pri){	int res;	/* Grab the lock first */	do {		res = ast_mutex_trylock(&pri->lock);		if (res) {			DEADLOCK_AVOIDANCE(&pvt->lock);		}	} while (res);	/* Then break the poll */	if (pri->master != AST_PTHREADT_NULL)		pthread_kill(pri->master, SIGURG);	return 0;}#endif#define NUM_CADENCE_MAX 25static int num_cadence = 4;static int user_has_defined_cadences = 0;static struct dahdi_ring_cadence cadences[NUM_CADENCE_MAX] = {	{ { 125, 125, 2000, 4000 } },			/*!< Quick chirp followed by normal ring */	{ { 250, 250, 500, 1000, 250, 250, 500, 4000 } }, /*!< British style ring */	{ { 125, 125, 125, 125, 125, 4000 } },	/*!< Three short bursts */	{ { 1000, 500, 2500, 5000 } },	/*!< Long ring */};/*! \brief cidrings says in which pause to transmit the cid information, where the first pause * is 1, the second pause is 2 and so on. */static int cidrings[NUM_CADENCE_MAX] = {	2,										/*!< Right after first long ring */	4,										/*!< Right after long part */	3,										/*!< After third chirp */	2,										/*!< Second spell */};#define ISTRUNK(p) ((p->sig == SIG_FXSLS) || (p->sig == SIG_FXSKS) || \			(p->sig == SIG_FXSGS) || (p->sig == SIG_PRI))#define CANBUSYDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __DAHDI_SIG_FXO) */)#define CANPROGRESSDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __DAHDI_SIG_FXO) */)static int dahdi_get_index(struct ast_channel *ast, struct dahdi_pvt *p, int nullok){	int res;	if (p->subs[SUB_REAL].owner == ast)		res = 0;	else if (p->subs[SUB_CALLWAIT].owner == ast)		res = 1;	else if (p->subs[SUB_THREEWAY].owner == ast)		res = 2;	else {		res = -1;		if (!nullok)			ast_log(LOG_WARNING, "Unable to get index, and nullok is not asserted\n");	}	return res;}#ifdef HAVE_PRIstatic void wakeup_sub(struct dahdi_pvt *p, int a, struct dahdi_pri *pri)#elsestatic void wakeup_sub(struct dahdi_pvt *p, int a, void *pri)#endif{#ifdef HAVE_PRI	if (pri)		ast_mutex_unlock(&pri->lock);#endif				for (;;) {		if (p->subs[a].owner) {			if (ast_mutex_trylock(&p->subs[a].owner->lock)) {				DEADLOCK_AVOIDANCE(&p->lock);			} else {				ast_queue_frame(p->subs[a].owner, &ast_null_frame);				ast_mutex_unlock(&p->subs[a].owner->lock);				break;			}		} else			break;	}#ifdef HAVE_PRI	if (pri)		ast_mutex_lock(&pri->lock);#endif			}#ifdef HAVE_PRIstatic void dahdi_queue_frame(struct dahdi_pvt *p, struct ast_frame *f, struct dahdi_pri *pri)#elsestatic void dahdi_queue_frame(struct dahdi_pvt *p, struct ast_frame *f, void *pri)#endif{	/* We must unlock the PRI to avoid the possibility of a deadlock */#ifdef HAVE_PRI	if (pri)		ast_mutex_unlock(&pri->lock);#endif			for (;;) {		if (p->owner) {			if (ast_mutex_trylock(&p->owner->lock)) {				DEADLOCK_AVOIDANCE(&p->lock);			} else {				ast_queue_frame(p->owner, f);				ast_mutex_unlock(&p->owner->lock);				break;			}		} else			break;	}#ifdef HAVE_PRI	if (pri)		ast_mutex_lock(&pri->lock);#endif		}static int restore_gains(struct dahdi_pvt *p);static void swap_subs(struct dahdi_pvt *p, int a, int b){	int tchan;	int tinthreeway;	struct ast_channel *towner;	ast_log(LOG_DEBUG, "Swapping %d and %d\n", a, b);	tchan = p->subs[a].chan;	towner = p->subs[a].owner;	tinthreeway = p->subs[a].inthreeway;	p->subs[a].chan = p->subs[b].chan;	p->subs[a].owner = p->subs[b].owner;	p->subs[a].inthreeway = p->subs[b].inthreeway;	p->subs[b].chan = tchan;	p->subs[b].owner = towner;	p->subs[b].inthreeway = tinthreeway;	if (p->subs[a].owner) 		p->subs[a].owner->fds[0] = p->subs[a].dfd;	if (p->subs[b].owner) 		p->subs[b].owner->fds[0] = p->subs[b].dfd;	wakeup_sub(p, a, NULL);	wakeup_sub(p, b, NULL);}static int dahdi_open(char *fn){	int fd;	int isnum;	int chan = 0;	int bs;	int x;	isnum = 1;	for (x = 0; x < strlen(fn); x++) {		if (!isdigit(fn[x])) {			isnum = 0;			break;		}	}	if (isnum) {		chan = atoi(fn);		if (chan < 1) {			ast_log(LOG_WARNING, "Invalid channel number '%s'\n", fn);			return -1;		}#ifdef HAVE_ZAPTEL		fn = "/dev/zap/channel";#else		fn = "/dev/dahdi/channel";#endif	}	fd = open(fn, O_RDWR | O_NONBLOCK);	if (fd < 0) {		ast_log(LOG_WARNING, "Unable to open '%s': %s\n", fn, strerror(errno));		return -1;	}

⌨️ 快捷键说明

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