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

📄 chan_vpb.cc

📁 Asterisk中信道部分的源码 。。。。
💻 CC
📖 第 1 页 / 共 5 页
字号:
			}		} else if (e->data == VPB_FAX) {			if (!p->faxhandled) {				if (strcmp(p->owner->exten, "fax")) {					const char *target_context = S_OR(p->owner->macrocontext, p->owner->context);					if (ast_exists_extension(p->owner, target_context, "fax", 1, p->owner->cid.cid_num)) {						ast_verb(3, "Redirecting %s to fax extension\n", p->owner->name);						/* Save the DID/DNIS when we transfer the fax call to a "fax" extension */						pbx_builtin_setvar_helper(p->owner, "FAXEXTEN", p->owner->exten);						if (ast_async_goto(p->owner, target_context, "fax", 1)) {							ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", p->owner->name, target_context);						}					} else {						ast_log(LOG_NOTICE, "Fax detected, but no fax extension\n");					}				} else {					ast_debug(1, "Already in a fax extension, not redirecting\n");				}			} else {				ast_debug(1, "Fax already handled\n");			}		} else if (e->data == VPB_GRUNT) {			if (ast_tvdiff_ms(ast_tvnow(), p->lastgrunt) > gruntdetect_timeout) {				/* Nothing heard on line for a very long time				 * Timeout connection */				ast_verb(3, "grunt timeout\n");				ast_log(LOG_NOTICE, "%s: Line hangup due of lack of conversation\n", p->dev); 				f.subclass = AST_CONTROL_HANGUP;			} else {				p->lastgrunt = ast_tvnow();				f.frametype = AST_FRAME_NULL;			}		} else {			f.frametype = AST_FRAME_NULL;		}		break;	case VPB_CALLEND:		#ifdef DIAL_WITH_CALL_PROGRESS		if (e->data == VPB_CALL_CONNECTED) {			f.subclass = AST_CONTROL_ANSWER;		} else if (e->data == VPB_CALL_NO_DIAL_TONE || e->data == VPB_CALL_NO_RING_BACK) {			f.subclass =  AST_CONTROL_CONGESTION;		} else if (e->data == VPB_CALL_NO_ANSWER || e->data == VPB_CALL_BUSY) {			f.subclass = AST_CONTROL_BUSY;		} else if (e->data  == VPB_CALL_DISCONNECTED) {			f.subclass = AST_CONTROL_HANGUP;		}		#else		ast_log(LOG_NOTICE, "%s: Got call progress callback but blind dialing \n", p->dev); 		f.frametype = AST_FRAME_NULL;		#endif		break;	case VPB_STATION_OFFHOOK:		f.subclass = AST_CONTROL_ANSWER;		break;	case VPB_DROP:		if ((p->mode == MODE_FXO) && (UseLoopDrop)) { /* ignore loop drop on stations */			if (p->owner->_state == AST_STATE_UP) {				f.subclass = AST_CONTROL_HANGUP;			} else {				f.frametype = AST_FRAME_NULL;			}		}		break;	case VPB_LOOP_ONHOOK:		if (p->owner->_state == AST_STATE_UP) {			f.subclass = AST_CONTROL_HANGUP;		} else {			f.frametype = AST_FRAME_NULL;		}		break;	case VPB_STATION_ONHOOK:		f.subclass = AST_CONTROL_HANGUP;		break;	case VPB_STATION_FLASH:		f.subclass = AST_CONTROL_FLASH;		break;	/* Called when dialing has finished and ringing starts	 * No indication that call has really been answered when using blind dialing	 */	case VPB_DIALEND:		if (p->state < 5) {			f.subclass = AST_CONTROL_ANSWER;			ast_verb(2, "%s: Dialend\n", p->dev);		} else {			f.frametype = AST_FRAME_NULL;		}		break;/*	case VPB_PLAY_UNDERFLOW:		f.frametype = AST_FRAME_NULL;		vpb_reset_play_fifo_alarm(p->handle);		break;	case VPB_RECORD_OVERFLOW:		f.frametype = AST_FRAME_NULL;		vpb_reset_record_fifo_alarm(p->handle);		break;*/	default:		f.frametype = AST_FRAME_NULL;		break;	}/*	ast_verb(4, "%s: LOCKING in handle_owned [%d]\n", p->dev,res);	res = ast_mutex_lock(&p->lock); 	ast_verb(4, "%s: LOCKING count[%d] owner[%d] \n", p->dev, p->lock.__m_count,p->lock.__m_owner);*/	if (p->bridge) { /* Check what happened, see if we need to report it. */		switch (f.frametype) {		case AST_FRAME_DTMF:			if (	!(p->bridge->c0 == p->owner && 					(p->bridge->flags & AST_BRIDGE_DTMF_CHANNEL_0) ) &&					!(p->bridge->c1 == p->owner && 					(p->bridge->flags & AST_BRIDGE_DTMF_CHANNEL_1) )) {				/* Kill bridge, this is interesting. */				endbridge = 1;			}			break;		case AST_FRAME_CONTROL:			if (!(p->bridge->flags & AST_BRIDGE_IGNORE_SIGS)) {			#if 0			if (f.subclass == AST_CONTROL_BUSY ||			f.subclass == AST_CONTROL_CONGESTION ||			f.subclass == AST_CONTROL_HANGUP ||			f.subclass == AST_CONTROL_FLASH)			#endif				endbridge = 1;			}			break;		default:			break;		}		if (endbridge) {			if (p->bridge->fo) {				*p->bridge->fo = ast_frisolate(&f);			}			if (p->bridge->rc) {				*p->bridge->rc = p->owner;			}			ast_mutex_lock(&p->bridge->lock);			p->bridge->endbridge = 1;			ast_cond_signal(&p->bridge->cond);			ast_mutex_unlock(&p->bridge->lock); 	       		   		}	  	}	if (endbridge) {		res = ast_mutex_unlock(&p->lock);/*		ast_verb(4, "%s: unLOCKING in handle_owned [%d]\n", p->dev,res);*/		return 0;	}	ast_verb(4, "%s: handle_owned: Prepared frame type[%d]subclass[%d], bridge=%p owner=[%s]\n",			p->dev, f.frametype, f.subclass, (void *)p->bridge, p->owner->name);	/* Trylock used here to avoid deadlock that can occur if we	 * happen to be in here handling an event when hangup is called	 * Problem is that hangup holds p->owner->lock	 */	if ((f.frametype >= 0) && (f.frametype != AST_FRAME_NULL) && (p->owner)) {		if (ast_channel_trylock(p->owner) == 0) {			ast_queue_frame(p->owner, &f);			ast_channel_unlock(p->owner);			ast_verb(4, "%s: handled_owned: Queued Frame to [%s]\n", p->dev, p->owner->name);		} else {			ast_verbose("%s: handled_owned: Missed event %d/%d \n",				p->dev, f.frametype, f.subclass);		}	}	res = ast_mutex_unlock(&p->lock);/*	ast_verb(4, "%s: unLOCKING in handle_owned [%d]\n", p->dev,res);*/	return 0;}static inline int monitor_handle_notowned(struct vpb_pvt *p, VPB_EVENT *e){	char s[2] = {0};	struct ast_channel *owner = p->owner;	char cid_num[256];	char cid_name[256];/*	struct ast_channel *c;*/	char str[VPB_MAX_STR];	vpb_translate_event(e, str);	ast_verb(4, "%s: handle_notowned: mode=%d, event[%d][%s]=[%d]\n", p->dev, p->mode, e->type,str, e->data);	switch (e->type) {	case VPB_LOOP_ONHOOK:	case VPB_LOOP_POLARITY:		if (UsePolarityCID == 1) {			ast_verb(4, "Polarity reversal\n");			if (p->callerid_type == 1) {				ast_verb(4, "Using VPB Caller ID\n");				get_callerid(p);        /* UK CID before 1st ring*/			}/*			get_callerid_ast(p); */   /* Caller ID using the ast functions */		}		break;	case VPB_RING:		if (p->mode == MODE_FXO) /* FXO port ring, start * */ {			vpb_new(p, AST_STATE_RING, p->context);			if (UsePolarityCID != 1) {				if (p->callerid_type == 1) {					ast_verb(4, "Using VPB Caller ID\n");					get_callerid(p);        /* Australian CID only between 1st and 2nd ring  */				}				get_callerid_ast(p);    /* Caller ID using the ast functions */			} else {				ast_log(LOG_ERROR, "Setting caller ID: %s %s\n", p->cid_num, p->cid_name);				ast_set_callerid(p->owner, p->cid_num, p->cid_name, p->cid_num);				p->cid_num[0] = 0;				p->cid_name[0] = 0;			}			vpb_timer_stop(p->ring_timer);			vpb_timer_start(p->ring_timer);		}		break;	case VPB_RING_OFF:		break;	case VPB_STATION_OFFHOOK:		if (p->mode == MODE_IMMEDIATE) {			vpb_new(p,AST_STATE_RING, p->context);		} else {			ast_verb(4, "%s: handle_notowned: playing dialtone\n", p->dev);			playtone(p->handle, &Dialtone);			p->state = VPB_STATE_PLAYDIAL;			p->wantdtmf = 1;			p->ext[0] = 0;	/* Just to be sure & paranoid.*/		}		break;	case VPB_DIALEND:		if (p->mode == MODE_DIALTONE) {			if (p->state == VPB_STATE_PLAYDIAL) {				playtone(p->handle, &Dialtone);				p->wantdtmf = 1;				p->ext[0] = 0;	/* Just to be sure & paranoid. */			}#if 0			/* These are not needed as they have timers to restart them */			else if (p->state == VPB_STATE_PLAYBUSY) {				playtone(p->handle, &Busytone);				p->wantdtmf = 1;				p->ext[0] = 0;				} else if (p->state == VPB_STATE_PLAYRING) {				playtone(p->handle, &Ringbacktone);				p->wantdtmf = 1;				p->ext[0] = 0;			}#endif		} else {			ast_verb(4, "%s: handle_notowned: Got a DIALEND when not really expected\n",p->dev);		}		break;	case VPB_STATION_ONHOOK:	/* clear ext */		stoptone(p->handle);		p->wantdtmf = 1 ;		p->ext[0] = 0;		p->state = VPB_STATE_ONHOOK;		break;	case VPB_TIMEREXP:		if (e->data == p->dtmfidd_timer_id) {			if (ast_exists_extension(NULL, p->context, p->ext, 1, p->callerid)){				ast_verb(4, "%s: handle_notowned: DTMF IDD timer out, matching on [%s] in [%s]\n", p->dev, p->ext, p->context);				vpb_new(p, AST_STATE_RING, p->context);			}		} else if (e->data == p->ring_timer_id) {			/* We didnt get another ring in time! */			if (p->owner) {				if (p->owner->_state != AST_STATE_UP) {					 /* Assume caller has hung up */					vpb_timer_stop(p->ring_timer);				}			} else {				 /* No owner any more, Assume caller has hung up */				vpb_timer_stop(p->ring_timer);			}		} 		break;	case VPB_DTMF:		if (p->state == VPB_STATE_ONHOOK){			/* DTMF's being passed while on-hook maybe Caller ID */			if (p->mode == MODE_FXO) {				if (e->data == DTMF_CID_START) { /* CallerID Start signal */					p->dtmf_caller_pos = 0; /* Leaves the first digit out */					memset(p->callerid, 0, sizeof(p->callerid));				} else if (e->data == DTMF_CID_STOP) { /* CallerID End signal */					p->callerid[p->dtmf_caller_pos] = '\0';					ast_verb(3, " %s: DTMF CallerID %s\n", p->dev, p->callerid);					if (owner) {						/*						if (owner->cid.cid_num)							ast_free(owner->cid.cid_num);						owner->cid.cid_num=NULL;						if (owner->cid.cid_name)							ast_free(owner->cid.cid_name);						owner->cid.cid_name=NULL;						owner->cid.cid_num = strdup(p->callerid);						*/						cid_name[0] = '\0';						cid_num[0] = '\0';						ast_callerid_split(p->callerid, cid_name, sizeof(cid_name), cid_num, sizeof(cid_num));						ast_set_callerid(owner, cid_num, cid_name, cid_num);					} else {						ast_verb(3, " %s: DTMF CallerID: no owner to assign CID \n", p->dev);					}				} else if (p->dtmf_caller_pos < AST_MAX_EXTENSION) {					if (p->dtmf_caller_pos >= 0) {						p->callerid[p->dtmf_caller_pos] = e->data;					}					p->dtmf_caller_pos++;				}			}			break;		}		if (p->wantdtmf == 1) {			stoptone(p->handle);			p->wantdtmf = 0;		}		p->state = VPB_STATE_GETDTMF;		s[0] = e->data;		strncat(p->ext, s, sizeof(p->ext) - strlen(p->ext) - 1);		#if 0		if (!strcmp(p->ext, ast_pickup_ext())) {			/* Call pickup has been dialled! */			if (ast_pickup_call(c)) {				/* Call pickup wasnt possible */			}		} else 		#endif		if (ast_exists_extension(NULL, p->context, p->ext, 1, p->callerid)) {			if (ast_canmatch_extension(NULL, p->context, p->ext, 1, p->callerid)) {				ast_verb(4, "%s: handle_notowned: Multiple matches on [%s] in [%s]\n", p->dev, p->ext, p->context);				/* Start DTMF IDD timer */				vpb_timer_stop(p->dtmfidd_timer);				vpb_timer_start(p->dtmfidd_timer);			} else {				ast_verb(4, "%s: handle_notowned: Matched on [%s] in [%s]\n", p->dev, p->ext , p->context);				vpb_new(p, AST_STATE_UP, p->context);			}		} else if (!ast_canmatch_extension(NULL, p->context, p->ext, 1, p->callerid)) {			if (ast_exists_extension(NULL, "default", p->ext, 1, p->callerid)) {				vpb_new(p, AST_STATE_UP, "default");			} else if (!ast_canmatch_extension(NULL, "default", p->ext, 1, p->callerid)) {				ast_verb(4, "%s: handle_notowned: can't match anything in %s or default\n", p->dev, p->context);				playtone(p->handle, &Busytone);				vpb_timer_stop(p->busy_timer);				vpb_timer_start(p->busy_timer);				p->state = VPB_STATE_PLAYBUSY;			}		}		break;	default:		/* Ignore.*/		break;	}	ast_verb(4, "%s: handle_notowned: mode=%d, [%d=>%d]\n", p->dev, p->mode, e->type, e->data);	return 0;}static void *do_monitor(void *unused){	/* Monitor thread, doesn't die until explicitly killed. */	ast_verb(2, "Starting vpb monitor thread[%ld]\n", pthread_self());	pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);	for (;;) {		VPB_EVENT e;		VPB_EVENT je;		char str[VPB_MAX_STR];		struct vpb_pvt *p;		/*		ast_verb(4, "Monitor waiting for event\n");		*/		int res = vpb_get_event_sync(&e, VPB_WAIT_TIMEOUT);		if ((res == VPB_NO_EVENTS) || (res == VPB_TIME_OUT)) {			/*			if (res == VPB_NO_EVENTS) {				ast_verb(4, "No events....\n");			} else {				ast_verb(4, "No events, timed out....\n");			}			*/			continue;		}		if (res != VPB_OK) {			ast_log(LOG_ERROR,"Monitor get event error %d\n", res );			ast_verbose("Monitor get event error %d\n", res );			continue;		}		str[0] = 0;		p = NULL;		ast_mutex_lock(&monlock);		if (e.type == VPB_NULL_EVENT) {			ast_verb(4, "Monitor got null event\n");		} else {			vpb_translate_event(&e, str);			if (*str && *(str + 1)) {				str[strlen(str) - 1] = '\0';			}			ast_mutex_lock(&iflock);			for (p = iflist; p && p->handle != e.handle; p = p->next);			ast_mutex_unlock(&iflock);			if (p) {				ast_verb(4, "%s: Event [%d=>%s]\n",					p ? p->dev : "null", e.type, str);			}		}		ast_mutex_unlock(&monlock); 		if (!p) {			if (e.type != VPB_NULL_EVENT) {				ast_log(LOG_WARNING, "Got event [%s][%d], no matching iface!\n", str, e.type);    				ast_verb(4, "vpb/ERR: No interface for Event [%d=>%s] \n", e.type, str);

⌨️ 快捷键说明

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