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

📄 chan_misdn.c

📁 Asterisk中信道部分的源码 。。。。
💻 C
📖 第 1 页 / 共 5 页
字号:
		ast_log(LOG_WARNING, " --> ! misdn_call called on ast_channel *ast where ast == NULL\n");		return -1;	}	if (((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) || !dest  ) {		ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name);		ast->hangupcause=41;		ast_setstate(ast, AST_STATE_DOWN);		return -1;	}	if (!ch) {		ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name);		ast->hangupcause=41;		ast_setstate(ast, AST_STATE_DOWN);		return -1;	}		newbc=ch->bc;		if (!newbc) {		ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name);		ast->hangupcause=41;		ast_setstate(ast, AST_STATE_DOWN);		return -1;	}		port=newbc->port;	if ((exceed=add_out_calls(port))) {		char tmp[16];		sprintf(tmp,"%d",exceed);		pbx_builtin_setvar_helper(ast,"MAX_OVERFLOW",tmp);		return -1;	}		chan_misdn_log(1, port, "* CALL: %s\n",dest);		chan_misdn_log(2, port, " --> * dad:%s tech:%s ctx:%s\n",ast->exten,ast->name, ast->context);		chan_misdn_log(3, port, " --> * adding2newbc ext %s\n",ast->exten);	if (ast->exten) {		int l = sizeof(newbc->dad);		strncpy(ast->exten,ext,sizeof(ast->exten));		strncpy(newbc->dad,ext,l);		newbc->dad[l-1] = 0;	}	if (ast->cid.cid_rdnis)  		strcpy(newbc->rad, ast->cid.cid_rdnis);	else 		newbc->rad[0]=0;	chan_misdn_log(3, port, " --> * adding2newbc callerid %s\n",ast->cid.cid_num);	if (ast_strlen_zero(newbc->oad) && ast->cid.cid_num ) {		if (ast->cid.cid_num) {			int l = sizeof(newbc->oad);			strncpy(newbc->oad,ast->cid.cid_num, l);			newbc->oad[l-1] = 0;		}	}	{		int bridging;		struct chan_list *ch=MISDN_ASTERISK_TECH_PVT(ast);		if (!ch) { ast_verbose("No chan_list in misdn_call\n"); return -1;}				newbc->capability=ast->transfercapability;		pbx_builtin_setvar_helper(ast,"TRANSFERCAPABILITY",ast_transfercapability2str(newbc->capability));		if ( ast->transfercapability == INFO_CAPABILITY_DIGITAL_UNRESTRICTED) {			chan_misdn_log(2, port, " --> * Call with flag Digital\n");		}				/* update screening and presentation */ 		update_config(ch,ORG_AST);				/* fill in some ies from channel vary*/		import_ch(ast, newbc, ch);				/* Finally The Options Override Everything */		if (opts)			misdn_set_opt_exec(ast,opts);		else			chan_misdn_log(2,port,"NO OPTS GIVEN\n");		/*check for bridging*/		misdn_cfg_get( 0, MISDN_GEN_BRIDGING, &bridging, sizeof(int));		if (bridging && ch->other_ch) {#ifdef MISDN_1_2			chan_misdn_log(1, port, "Disabling EC (aka Pipeline) on both Sides\n");			*ch->bc->pipeline=0;			*ch->other_ch->bc->pipeline=0;#else			chan_misdn_log(1, port, "Disabling EC on both Sides\n");			ch->bc->ec_enable=0;			ch->other_ch->bc->ec_enable=0;#endif		}				r=misdn_lib_send_event( newbc, EVENT_SETUP );				/** we should have l3id after sending setup **/		ch->l3id=newbc->l3_id;	}		if ( r == -ENOCHAN  ) {		chan_misdn_log(0, port, " --> * Theres no Channel at the moment .. !\n");		chan_misdn_log(1, port, " --> * SEND: State Down pid:%d\n",newbc?newbc->pid:-1);		ast->hangupcause=34;		ast_setstate(ast, AST_STATE_DOWN);		return -1;	}		chan_misdn_log(2, port, " --> * SEND: State Dialing pid:%d\n",newbc?newbc->pid:1);	ast_setstate(ast, AST_STATE_DIALING);	ast->hangupcause=16;		if (newbc->nt) stop_bc_tones(ch);	ch->state=MISDN_CALLING;	return 0; }static int misdn_answer(struct ast_channel *ast){	struct chan_list *p;		if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast)) ) return -1;		chan_misdn_log(1, p? (p->bc? p->bc->port : 0) : 0, "* ANSWER:\n");		if (!p) {		ast_log(LOG_WARNING, " --> Channel not connected ??\n");		ast_queue_hangup(ast);	}	if (!p->bc) {		chan_misdn_log(1, 0, " --> Got Answer, but theres no bc obj ??\n");		ast_queue_hangup(ast);	}	{		const char *tmp_key = pbx_builtin_getvar_helper(p->ast, "CRYPT_KEY");				if (tmp_key ) {			chan_misdn_log(1, p->bc->port, " --> Connection will be BF crypted\n");			{				int l = sizeof(p->bc->crypt_key);				strncpy(p->bc->crypt_key,tmp_key, l);				p->bc->crypt_key[l-1] = 0;			}		} else {			chan_misdn_log(3, p->bc->port, " --> Connection is without BF encryption\n");		}    	}	{		const char *nodsp=pbx_builtin_getvar_helper(ast, "MISDN_DIGITAL_TRANS");		if (nodsp) {			chan_misdn_log(1, p->bc->port, " --> Connection is transparent digital\n");			p->bc->nodsp=1;			p->bc->hdlc=0;			p->bc->nojitter=1;		}	}		p->state = MISDN_CONNECTED;	stop_indicate(p);	if ( ast_strlen_zero(p->bc->cad) ) {		chan_misdn_log(2,p->bc->port," --> empty cad using dad\n");		ast_copy_string(p->bc->cad,p->bc->dad,sizeof(p->bc->cad));	}	misdn_lib_send_event( p->bc, EVENT_CONNECT);	start_bc_tones(p);		return 0;}static int misdn_digit_begin(struct ast_channel *chan, char digit){	/* XXX Modify this callback to support Asterisk controlling the length of DTMF */	return 0;}static int misdn_digit_end(struct ast_channel *ast, char digit, unsigned int duration){	struct chan_list *p;	struct misdn_bchannel *bc;		if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast))) return -1;	bc=p->bc;	chan_misdn_log(1, bc?bc->port:0, "* IND : Digit %c\n",digit);		if (!bc) {		ast_log(LOG_WARNING, " --> !! Got Digit Event without having bchannel Object\n");		return -1;	}		switch (p->state ) {		case MISDN_CALLING:		{			int l;					char buf[8];			buf[0]=digit;			buf[1]=0;						l = sizeof(bc->infos_pending);			strncat(bc->infos_pending, buf, l - strlen(bc->infos_pending) - 1);		}		break;		case MISDN_CALLING_ACKNOWLEDGE:		{			bc->info_dad[0]=digit;			bc->info_dad[1]=0;						{				int l = sizeof(bc->dad);				strncat(bc->dad, bc->info_dad, l - strlen(bc->dad) - 1);			}			{				int l = sizeof(p->ast->exten);				strncpy(p->ast->exten, bc->dad, l);				p->ast->exten[l-1] = 0;			}						misdn_lib_send_event( bc, EVENT_INFORMATION);		}		break;				default:				/* Do not send Digits in CONNECTED State, when			 * the other side is too mISDN. */			if (p->other_ch ) 				return 0;			if ( bc->send_dtmf ) 				send_digit_to_chan(p,digit);		break;	}		return 0;}static int misdn_fixup(struct ast_channel *oldast, struct ast_channel *ast){	struct chan_list *p;		if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast) )) return -1;		chan_misdn_log(1, p->bc?p->bc->port:0, "* IND: Got Fixup State:%s L3id:%x\n", misdn_get_ch_state(p), p->l3id);		p->ast = ast ;  	return 0;}static int misdn_indication(struct ast_channel *ast, int cond, const void *data, size_t datalen){	struct chan_list *p;  	if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast))) {		ast_log(LOG_WARNING, "Returned -1 in misdn_indication\n");		return -1;	}		if (!p->bc ) {		chan_misdn_log(1, 0, "* IND : Indication from %s\n",ast->exten);		ast_log(LOG_WARNING, "Private Pointer but no bc ?\n");		return -1;	}		chan_misdn_log(5, p->bc->port, "* IND : Indication [%d] from %s\n",cond, ast->exten);		switch (cond) {	case AST_CONTROL_BUSY:		chan_misdn_log(1, p->bc->port, "* IND :\tbusy pid:%d\n",p->bc?p->bc->pid:-1);		ast_setstate(ast,AST_STATE_BUSY);		p->bc->out_cause=17;		if (p->state != MISDN_CONNECTED) {			start_bc_tones(p);			misdn_lib_send_event( p->bc, EVENT_DISCONNECT);		} else {			chan_misdn_log(-1, p->bc->port, " --> !! Got Busy in Connected State !?! ast:%s\n", ast->name);		}		return -1;		break;	case AST_CONTROL_RING:		chan_misdn_log(1, p->bc->port, "* IND :\tring pid:%d\n",p->bc?p->bc->pid:-1);		return -1;		break;			case AST_CONTROL_RINGING:		chan_misdn_log(1, p->bc->port, "* IND :\tringing pid:%d\n",p->bc?p->bc->pid:-1);		switch (p->state) {			case MISDN_ALERTING:				chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d but I was Ringing before, so ignoring it\n",p->bc?p->bc->pid:-1);				break;			case MISDN_CONNECTED:				chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d but Connected, so just send TONE_ALERTING without state changes \n",p->bc?p->bc->pid:-1);				return -1;				break;			default:				p->state=MISDN_ALERTING;				chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d\n",p->bc?p->bc->pid:-1);				misdn_lib_send_event( p->bc, EVENT_ALERTING);							if (p->other_ch && p->other_ch->bc) {					if (misdn_inband_avail(p->other_ch->bc)) {						chan_misdn_log(2,p->bc->port, " --> other End is mISDN and has inband info available\n");						break;					}					if (!p->other_ch->bc->nt) {						chan_misdn_log(2,p->bc->port, " --> other End is mISDN TE so it has inband info for sure (?)\n");						break;					}				}				chan_misdn_log(3, p->bc->port, " --> * SEND: State Ring pid:%d\n",p->bc?p->bc->pid:-1);				ast_setstate(ast,AST_STATE_RINGING);							if ( !p->bc->nt && (p->originator==ORG_MISDN) && !p->incoming_early_audio ) 					chan_misdn_log(2,p->bc->port, " --> incoming_early_audio off\n");				else 					return -1;		}		break;	case AST_CONTROL_ANSWER:		chan_misdn_log(1, p->bc->port, " --> * IND :\tanswer pid:%d\n",p->bc?p->bc->pid:-1);		start_bc_tones(p);		break;	case AST_CONTROL_TAKEOFFHOOK:		chan_misdn_log(1, p->bc->port, " --> *\ttakeoffhook pid:%d\n",p->bc?p->bc->pid:-1);		return -1;		break;	case AST_CONTROL_OFFHOOK:		chan_misdn_log(1, p->bc->port, " --> *\toffhook pid:%d\n",p->bc?p->bc->pid:-1);		return -1;		break; 	case AST_CONTROL_FLASH:		chan_misdn_log(1, p->bc->port, " --> *\tflash pid:%d\n",p->bc?p->bc->pid:-1);		break;	case AST_CONTROL_PROGRESS:		chan_misdn_log(1, p->bc->port, " --> * IND :\tprogress pid:%d\n",p->bc?p->bc->pid:-1);		misdn_lib_send_event( p->bc, EVENT_PROGRESS);		break;	case AST_CONTROL_PROCEEDING:		chan_misdn_log(1, p->bc->port, " --> * IND :\tproceeding pid:%d\n",p->bc?p->bc->pid:-1);		misdn_lib_send_event( p->bc, EVENT_PROCEEDING);		break;	case AST_CONTROL_CONGESTION:		chan_misdn_log(1, p->bc->port, " --> * IND :\tcongestion pid:%d\n",p->bc?p->bc->pid:-1);		p->bc->out_cause=42;		start_bc_tones(p);		misdn_lib_send_event( p->bc, EVENT_DISCONNECT);		if (p->bc->nt) {			hanguptone_indicate(p);		}		break;	case -1 :		chan_misdn_log(1, p->bc->port, " --> * IND :\t-1! (stop indication) pid:%d\n",p->bc?p->bc->pid:-1);				stop_indicate(p);		if (p->state == MISDN_CONNECTED) 			start_bc_tones(p);		break;	case AST_CONTROL_HOLD:		ast_moh_start(ast,data,ast->musicclass); 		chan_misdn_log(1, p->bc->port, " --> *\tHOLD pid:%d\n",p->bc?p->bc->pid:-1);		break;	case AST_CONTROL_UNHOLD:		ast_moh_stop(ast);		chan_misdn_log(1, p->bc->port, " --> *\tUNHOLD pid:%d\n",p->bc?p->bc->pid:-1);		break;	default:		chan_misdn_log(1, p->bc->port, " --> * Unknown Indication:%d pid:%d\n",cond,p->bc?p->bc->pid:-1);	}  	return 0;}static int misdn_hangup(struct ast_channel *ast){	struct chan_list *p;	struct misdn_bchannel *bc=NULL;	ast_log(LOG_DEBUG, "misdn_hangup(%s)\n", ast->name);		if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast) ) ) return -1;		if (!p) {		chan_misdn_log(3, 0, "misdn_hangup called, without chan_list obj.\n");		return 0 ;	}		bc=p->bc;	if (bc) {		const char *tmp=pbx_builtin_getvar_helper(ast,"MISDN_USERUSER");		if (tmp) {			ast_log(LOG_NOTICE, "MISDN_USERUSER: %s\n", tmp);			strcpy(bc->uu, tmp);			bc->uulen=strlen(bc->uu);		}	}	MISDN_ASTERISK_TECH_PVT(ast)=NULL;	p->ast=NULL;	if (ast->_state == AST_STATE_RESERVED || 		p->state == MISDN_NOTHING || 		p->state == MISDN_HOLDED || 		p->state == MISDN_HOLD_DISCONNECT ) {		CLEAN_CH:		/* between request and call */		ast_log(LOG_DEBUG, "State Reserved (or nothing) => chanIsAvail\n");		MISDN_ASTERISK_TECH_PVT(ast)=NULL;			ast_mutex_lock(&release_lock);		cl_dequeue_chan(&cl_te, p);		close(p->pipe[0]);		close(p->pipe[1]);		free(p);		ast_mutex_unlock(&release_lock);				if (bc)			misdn_lib_release(bc);				return 0;	}	if (!bc) {		ast_log(LOG_WARNING,"Hangup with private but no bc ? state:%s l3id:%x\n", misdn_get_ch_state(p), p->l3id);		goto CLEAN_CH;	}	p->need_hangup=0;	p->need_queue_hangup=0;	p->need_busy=0;	if (!p->bc->nt) 		stop_bc_tones(p);		{		const char *varcause=NULL;		bc->out_cause=ast->hangupcause?ast->hangupcause:16;				if ( (varcause=pbx_builtin_getvar_helper(ast, "HANGUPCAUSE")) ||		     (varcause=pbx_builtin_getvar_helper(ast, "PRI_CAUSE"))) {			int tmpcause=atoi(varcause);			bc->out_cause=tmpcause?tmpcause:16;		}    		chan_misdn_log(1, bc->port, "* IND : HANGUP\tpid:%d ctx:%s dad:%s oad:%s State:%s\n",p->bc?p->bc->pid:-1, ast->context, ast->exten, ast->cid.cid_num, misdn_get_ch_state(p));		chan_misdn_log(3, bc->port, " --> l3id:%x\n",p->l3id);		chan_misdn_log(3, bc->port, " --> cause:%d\n",bc->cause);		chan_misdn_log(2, bc->port, " --> out_cause:%d\n",bc->out_cause);		chan_misdn_log(2, bc->port, " --> state:%s\n", misdn_get_ch_state(p));				switch (p->state) {		case MISDN_CALLING:		case MISDN_INCOMING_SETUP:			/* This is the only place in misdn_hangup, where we 			 * can call release_chan, else it might create lot's of trouble			 * */			ast_log(LOG_NOTICE, "release channel, in CALLING/INCOMING_SETUP state.. no other events happened\n");			release_chan(bc);			p->state=MISDN_CLEANING;			if (bc->need_release_complete)				misdn_lib_send_event( bc, EVENT_RELEASE_COMPLETE);			break;		case MISDN_HOLDED:		case MISDN_DIALING:			start_bc_tones(p);			hanguptone_indicate(p

⌨️ 快捷键说明

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