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

📄 chan_vpb.cc

📁 Asterisk中信道部分的源码 。。。。
💻 CC
📖 第 1 页 / 共 5 页
字号:
	ast_verb(4, "%s: LOCKING in call \n", p->dev);	ast_verb(4, "%s: LOCKING count[%d] owner[%d] \n", p->dev, p->lock.__m_count,p->lock.__m_owner);*/	ast_mutex_lock(&p->lock);	ast_verb(4, "%s: starting call to [%s]\n", p->dev, dest);	if (s)		s = s + 1;	else		s = dest;	ast_copy_string(dialstring, s, sizeof(dialstring));	for (i = 0; dialstring[i] != '\0'; i++) {		if ((dialstring[i] == 'w') || (dialstring[i] == 'W'))			dialstring[i] = ',';		else if ((dialstring[i] == 'f') || (dialstring[i] == 'F'))			dialstring[i] = '&';	}	if (ast->_state != AST_STATE_DOWN && ast->_state != AST_STATE_RESERVED) {		ast_log(LOG_WARNING, "vpb_call on %s neither down nor reserved!\n", ast->name);		tmp = ast_mutex_unlock(&p->lock);/*		ast_verb(4, "%s: unLOCKING in call [%d]\n", p->dev,tmp);*/		return -1;	}	if (p->mode != MODE_FXO)  /* Station port, ring it. */		vpb_ring_station_async(p->handle, 2);	else {		VPB_CALL call;		int j;		/* Dial must timeout or it can leave channels unuseable */		if (timeout == 0) {			timeout = TIMER_PERIOD_NOANSWER;		} else {			timeout = timeout * 1000; /* convert from secs to ms. */		}		/* These timeouts are only used with call progress dialing */		call.dialtones = 1; /* Number of dialtones to get outside line */		call.dialtone_timeout = VPB_DIALTONE_WAIT; /* Wait this long for dialtone (ms) */		call.ringback_timeout = VPB_RINGWAIT; /* Wait this long for ringing after dialing (ms) */		call.inter_ringback_timeout = VPB_CONNECTED_WAIT; /* If ringing stops for this long consider it connected (ms) */		call.answer_timeout = timeout; /* Time to wait for answer after ringing starts (ms) */		memcpy(&call.tone_map,  DialToneMap, sizeof(DialToneMap));		vpb_set_call(p->handle, &call);		ast_verb(2, "%s: Calling %s on %s \n",p->dev, dialstring, ast->name);		ast_verb(2, "%s: Dial parms for %s %d/%dms/%dms/%dms/%dms\n", p->dev,				ast->name, call.dialtones, call.dialtone_timeout,				call.ringback_timeout, call.inter_ringback_timeout,				call.answer_timeout);		for (j = 0; !call.tone_map[j].terminate; j++) {			ast_verb(2, "%s: Dial parms for %s tone %d->%d\n", p->dev,					ast->name, call.tone_map[j].tone_id, call.tone_map[j].call_id); 		}		ast_verb(4, "%s: Disabling Loop Drop detection\n", p->dev);		vpb_disable_event(p->handle, VPB_MDROP);		vpb_sethook_sync(p->handle, VPB_OFFHOOK);		p->state = VPB_STATE_OFFHOOK;		#ifndef DIAL_WITH_CALL_PROGRESS		vpb_sleep(300);		ast_verb(4, "%s: Enabling Loop Drop detection\n", p->dev);		vpb_enable_event(p->handle, VPB_MDROP);		res = vpb_dial_async(p->handle, dialstring);		#else		ast_verb(4, "%s: Enabling Loop Drop detection\n", p->dev);		vpb_enable_event(p->handle, VPB_MDROP);		res = vpb_call_async(p->handle, dialstring);		#endif		if (res != VPB_OK) {			ast_debug(1, "Call on %s to %s failed: %d\n", ast->name, s, res);			res = -1;		} else			res = 0;	}	ast_verb(3, "%s: VPB Calling %s [t=%d] on %s returned %d\n", p->dev , s, timeout, ast->name, res);	if (res == 0) {		ast_setstate(ast, AST_STATE_RINGING);		ast_queue_control(ast, AST_CONTROL_RINGING);	}	if (!p->readthread) {		ast_pthread_create(&p->readthread, NULL, do_chanreads, (void *)p);	}	tmp = ast_mutex_unlock(&p->lock);/*	ast_verb(4, "%s: unLOCKING in call [%d]\n", p->dev,tmp);*/	return res;}static int vpb_hangup(struct ast_channel *ast){	struct vpb_pvt *p = (struct vpb_pvt *)ast->tech_pvt;	VPB_EVENT je;	char str[VPB_MAX_STR];	int res = 0;/*	ast_verb(4, "%s: LOCKING in hangup \n", p->dev);	ast_verb(4, "%s: LOCKING in hangup count[%d] owner[%d] \n", p->dev, p->lock.__m_count,p->lock.__m_owner);	ast_verb(4, "%s: LOCKING pthread_self(%d)\n", p->dev,pthread_self());	ast_mutex_lock(&p->lock);*/	ast_verb(2, "%s: Hangup requested\n", ast->name);	if (!ast->tech || !ast->tech_pvt) {		ast_log(LOG_WARNING, "%s: channel not connected?\n", ast->name);		res = ast_mutex_unlock(&p->lock);/*		ast_verb(4, "%s: unLOCKING in hangup [%d]\n", p->dev,res);*/		/* Free up ast dsp if we have one */		if (use_ast_dtmfdet && p->vad) {			ast_dsp_free(p->vad);			p->vad = NULL;		}		return 0;	}	/* Stop record */	p->stopreads = 1;	if (p->readthread) {		pthread_join(p->readthread, NULL); 		ast_verb(4, "%s: stopped record thread \n", ast->name);	}	/* Stop play */	if (p->lastoutput != -1) {		ast_verb(2, "%s: Ending play mode \n", ast->name);		vpb_play_terminate(p->handle);		ast_mutex_lock(&p->play_lock);		vpb_play_buf_finish(p->handle);		ast_mutex_unlock(&p->play_lock);	}	ast_verb(4, "%s: Setting state down\n", ast->name);	ast_setstate(ast, AST_STATE_DOWN);/*	ast_verb(4, "%s: LOCKING in hangup \n", p->dev);	ast_verb(4, "%s: LOCKING in hangup count[%d] owner[%d] \n", p->dev, p->lock.__m_count,p->lock.__m_owner);	ast_verb(4, "%s: LOCKING pthread_self(%d)\n", p->dev,pthread_self());*/	ast_mutex_lock(&p->lock);	if (p->mode != MODE_FXO) {		/* station port. */		vpb_ring_station_async(p->handle, 0);		if (p->state != VPB_STATE_ONHOOK) {			/* This is causing a "dial end" "play tone" loop			playtone(p->handle, &Busytone); 			p->state = VPB_STATE_PLAYBUSY;			ast_verb(5, "%s: Station offhook[%d], playing busy tone\n",								ast->name,p->state);			*/		} else {			stoptone(p->handle);		}		#ifdef VPB_PRI		vpb_setloop_async(p->handle, VPB_OFFHOOK);		vpb_sleep(100);		vpb_setloop_async(p->handle, VPB_ONHOOK);		#endif	} else {		stoptone(p->handle); /* Terminates any dialing */		vpb_sethook_sync(p->handle, VPB_ONHOOK);		p->state=VPB_STATE_ONHOOK;	}	while (VPB_OK == vpb_get_event_ch_async(p->handle, &je)) {		vpb_translate_event(&je, str);		ast_verb(4, "%s: Flushing event [%d]=>%s\n", ast->name, je.type, str);	}	p->readthread = 0;	p->lastoutput = -1;	p->lastinput = -1;	p->last_ignore_dtmf = 1;	p->ext[0] = 0;	p->dialtone = 0;	p->owner = NULL;	ast->tech_pvt = NULL;	/* Free up ast dsp if we have one */	if (use_ast_dtmfdet && p->vad) {		ast_dsp_free(p->vad);		p->vad = NULL;	}	ast_verb(2, "%s: Hangup complete\n", ast->name);	restart_monitor();/*	ast_verb(4, "%s: LOCKING in hangup count[%d] owner[%d] \n", p->dev, p->lock.__m_count,p->lock.__m_owner);*/	res = ast_mutex_unlock(&p->lock);/*	ast_verb(4, "%s: unLOCKING in hangup [%d]\n", p->dev,res);	ast_verb(4, "%s: LOCKING in hangup count[%d] owner[%d] \n", p->dev, p->lock.__m_count,p->lock.__m_owner);*/	return 0;}static int vpb_answer(struct ast_channel *ast){	struct vpb_pvt *p = (struct vpb_pvt *)ast->tech_pvt;	int res = 0;/*	VPB_EVENT je;	int ret;	ast_verb(4, "%s: LOCKING in answer \n", p->dev);	ast_verb(4, "%s: LOCKING count[%d] owner[%d] \n", p->dev, p->lock.__m_count,p->lock.__m_owner);*/	ast_mutex_lock(&p->lock);	ast_verb(4, "%s: Answering channel\n", p->dev);	if (p->mode == MODE_FXO) {		ast_verb(4, "%s: Disabling Loop Drop detection\n", p->dev);		vpb_disable_event(p->handle, VPB_MDROP);	}	if (ast->_state != AST_STATE_UP) {		if (p->mode == MODE_FXO) {			vpb_sethook_sync(p->handle, VPB_OFFHOOK);			p->state = VPB_STATE_OFFHOOK;/*			vpb_sleep(500);			ret = vpb_get_event_ch_async(p->handle, &je);			if ((ret == VPB_OK) && ((je.type != VPB_DROP)&&(je.type != VPB_RING))){				ast_verb(4, "%s: Answer collected a wrong event!!\n", p->dev);				vpb_put_event(&je);			}*/		}		ast_setstate(ast, AST_STATE_UP);		ast_verb(2, "%s: Answered call on %s [%s]\n", p->dev,					 ast->name, (p->mode == MODE_FXO) ? "FXO" : "FXS");		ast->rings = 0;		if (!p->readthread) {	/*		res = ast_mutex_unlock(&p->lock); */	/*		ast_verbose("%s: unLOCKING in answer [%d]\n", p->dev,res); */			ast_pthread_create(&p->readthread, NULL, do_chanreads, (void *)p);		} else {			ast_verb(4, "%s: Record thread already running!!\n", p->dev);		}	} else {		ast_verb(4, "%s: Answered state is up\n", p->dev);	/*	res = ast_mutex_unlock(&p->lock); */	/*	ast_verbose("%s: unLOCKING in answer [%d]\n", p->dev,res); */	}	vpb_sleep(500);	if (p->mode == MODE_FXO) {		ast_verb(4, "%s: Re-enabling Loop Drop detection\n", p->dev);		vpb_enable_event(p->handle, VPB_MDROP);	}	res = ast_mutex_unlock(&p->lock);/*	ast_verb(4, "%s: unLOCKING in answer [%d]\n", p->dev,res);*/	return 0;}static struct ast_frame *vpb_read(struct ast_channel *ast){	struct vpb_pvt *p = (struct vpb_pvt *)ast->tech_pvt; 	static struct ast_frame f = { AST_FRAME_NULL }; 	f.src = "vpb";	ast_log(LOG_NOTICE, "%s: vpb_read: should never be called!\n", p->dev);	ast_verbose("%s: vpb_read: should never be called!\n", p->dev);	return &f;}static inline AudioCompress ast2vpbformat(int ast_format){	switch (ast_format) {	case AST_FORMAT_ALAW:		return VPB_ALAW;	case AST_FORMAT_SLINEAR:		return VPB_LINEAR;	case AST_FORMAT_ULAW:		return VPB_MULAW;	case AST_FORMAT_ADPCM:		return VPB_OKIADPCM;	default:		return VPB_RAW;	}}static inline const char * ast2vpbformatname(int ast_format){	switch(ast_format) {	case AST_FORMAT_ALAW:		return "AST_FORMAT_ALAW:VPB_ALAW";	case AST_FORMAT_SLINEAR:		return "AST_FORMAT_SLINEAR:VPB_LINEAR";	case AST_FORMAT_ULAW:		return "AST_FORMAT_ULAW:VPB_MULAW";	case AST_FORMAT_ADPCM:		return "AST_FORMAT_ADPCM:VPB_OKIADPCM";	default:		return "UNKN:UNKN";	}}static inline int astformatbits(int ast_format){	switch (ast_format) {	case AST_FORMAT_SLINEAR:		return 16;	case AST_FORMAT_ADPCM:		return 4;	case AST_FORMAT_ALAW:	case AST_FORMAT_ULAW:	default:		return 8;	}}int a_gain_vector(float g, short *v, int n) {	int i;	float tmp;	for (i = 0; i < n; i++) {		tmp = g * v[i];		if (tmp > 32767.0)			tmp = 32767.0;		if (tmp < -32768.0)			tmp = -32768.0;		v[i] = (short)tmp;		}  	return i;}/* Writes a frame of voice data to a VPB channel */static int vpb_write(struct ast_channel *ast, struct ast_frame *frame){	struct vpb_pvt *p = (struct vpb_pvt *)ast->tech_pvt; 	int res = 0;	AudioCompress fmt = VPB_RAW;	struct timeval play_buf_time_start;	int tdiff;/*	ast_mutex_lock(&p->lock); */	ast_verb(6, "%s: vpb_write: Writing to channel\n", p->dev);	if (frame->frametype != AST_FRAME_VOICE) {		ast_verb(4, "%s: vpb_write: Don't know how to handle from type %d\n", ast->name, frame->frametype);/*		ast_mutex_unlock(&p->lock); */		return 0;	} else if (ast->_state != AST_STATE_UP) {		ast_verb(4, "%s: vpb_write: Attempt to Write frame type[%d]subclass[%d] on not up chan(state[%d])\n",ast->name, frame->frametype, frame->subclass,ast->_state);		p->lastoutput = -1;/*		ast_mutex_unlock(&p->lock); */		return 0;	}/*	ast_debug(1, "%s: vpb_write: Checked frame type..\n", p->dev); */	fmt = ast2vpbformat(frame->subclass);	if (fmt < 0) {		ast_log(LOG_WARNING, "%s: vpb_write: Cannot handle frames of %d format!\n", ast->name, frame->subclass);		return -1;	}	tdiff = ast_tvdiff_ms(ast_tvnow(), p->lastplay);	ast_debug(1, "%s: vpb_write: time since last play(%d) \n", p->dev, tdiff); 	if (tdiff < (VPB_SAMPLES / 8 - 1)) {		ast_debug(1, "%s: vpb_write: Asked to play too often (%d) (%d)\n", p->dev, tdiff, frame->datalen); /*		return 0; */	}	p->lastplay = ast_tvnow();/*	ast_debug(1, "%s: vpb_write: Checked frame format..\n", p->dev); */	ast_mutex_lock(&p->play_lock);/*	ast_debug(1, "%s: vpb_write: Got play lock..\n", p->dev); */	/* Check if we have set up the play_buf */	if (p->lastoutput == -1) {		vpb_play_buf_start(p->handle, fmt);		ast_verb(2, "%s: vpb_write: Starting play mode (codec=%d)[%s]\n", p->dev, fmt, ast2vpbformatname(frame->subclass));		p->lastoutput = fmt;		ast_mutex_unlock(&p->play_lock);		return 0;	} else if (p->lastoutput != fmt) {		vpb_play_buf_finish(p->handle);		vpb_play_buf_start(p->handle, fmt);		ast_verb(2, "%s: vpb_write: Changed play format (%d=>%d)\n", p->dev, p->lastoutput, fmt);		ast_mutex_unlock(&p->play_lock);		return 0;	}	p->lastoutput = fmt;	/* Apply extra gain ! */	if( p->txswgain > MAX_VPB_GAIN )		a_gain_vector(p->txswgain - MAX_VPB_GAIN , (short*)frame->data, frame->datalen / sizeof(short));/*	ast_debug(1, "%s: vpb_write: Applied gain..\n", p->dev); *//*	ast_debug(1, "%s: vpb_write: play_buf_time %d\n", p->dev, p->play_buf_time); */	if ((p->read_state == 1) && (p->play_buf_time < 5)){		play_buf_time_start = ast_tvnow();/*		res = vpb_play_buf_sync(p->handle, (char *)frame->data, tdiff * 8 * 2); */		res = vpb_play_buf_sync(p->handle, (char *)frame->data, frame->datalen);		if(res == VPB_OK) {			short * data = (short*)frame->data;			ast_verb(6, "%s: vpb_write: Wrote chan (codec=%d) %d %d\n", p->dev, fmt, data[0], data[1]);		}		p->play_buf_time = ast_tvdiff_ms(ast_tvnow(), play_buf_time_start);	} else {		p->chuck_count++;		ast_debug(1, "%s: vpb_write: Tossed data away, tooooo much data!![%d]\n", p->dev, p->chuck_count);		p->play_buf_time = 0;	}	ast_mutex_unlock(&p->play_lock);/*	ast_mutex_unlock(&p->lock); */	ast_verb(6, "%s: vpb_write: Done Writing to channel\n", p->dev);	return 0;}/* Read monitor thread function. */static void *do_chanreads(void *pvt){	struct vpb_pvt *p = (struct vpb_pvt *)pvt;	struct ast_frame *fr = &p->fr;	char *readbuf = ((char *)p->buf) + AST_FRIENDLY_OFFSET;	int bridgerec = 0;	int afmt, readlen, res, trycnt=0;	AudioCompress fmt;	int ignore_dtmf;

⌨️ 快捷键说明

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