mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-11-04 05:15:22 +00:00 
			
		
		
		
	Merge alternate hangup and meetme patches from Matt N.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@3529 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
		@@ -67,6 +67,7 @@ static char *descrip =
 | 
			
		||||
"             that are assigned to you.\n"
 | 
			
		||||
"      'r' -- indicate ringing to the calling party, pass no audio until answered.\n"
 | 
			
		||||
"      'm' -- provide hold music to the calling party until answered.\n"
 | 
			
		||||
"      'h' -- allow callee to hang up by hitting *.\n"
 | 
			
		||||
"      'H' -- allow caller to hang up by hitting *.\n"
 | 
			
		||||
"      'C' -- reset call detail record for this call.\n"
 | 
			
		||||
"      'P[(x)]' -- privacy mode, using 'x' as database if provided.\n"
 | 
			
		||||
@@ -108,7 +109,8 @@ struct localuser {
 | 
			
		||||
	int allowredirect_out;
 | 
			
		||||
	int ringbackonly;
 | 
			
		||||
	int musiconhold;
 | 
			
		||||
	int allowdisconnect;
 | 
			
		||||
	int allowdisconnect_in;
 | 
			
		||||
	int allowdisconnect_out;
 | 
			
		||||
	int forcecallerid;
 | 
			
		||||
	struct localuser *next;
 | 
			
		||||
};
 | 
			
		||||
@@ -131,7 +133,7 @@ static void hanguptree(struct localuser *outgoing, struct ast_channel *exception
 | 
			
		||||
 | 
			
		||||
#define AST_MAX_WATCHERS 256
 | 
			
		||||
 | 
			
		||||
static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localuser *outgoing, int *to, int *allowredir_in, int *allowredir_out, int *allowdisconnect, int *sentringing, char *status, size_t statussize)
 | 
			
		||||
static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localuser *outgoing, int *to, int *allowredir_in, int *allowredir_out, int *allowdisconnect_in, int *allowdisconnect_out, int *sentringing, char *status, size_t statussize)
 | 
			
		||||
{
 | 
			
		||||
	struct localuser *o;
 | 
			
		||||
	int found;
 | 
			
		||||
@@ -202,7 +204,8 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localu
 | 
			
		||||
					peer = o->chan;
 | 
			
		||||
					*allowredir_in = o->allowredirect_in;
 | 
			
		||||
					*allowredir_out = o->allowredirect_out;
 | 
			
		||||
					*allowdisconnect = o->allowdisconnect;
 | 
			
		||||
					*allowdisconnect_in = o->allowdisconnect_in;
 | 
			
		||||
					*allowdisconnect_out = o->allowdisconnect_out;
 | 
			
		||||
				}
 | 
			
		||||
			} else if (o->chan && (o->chan == winner)) {
 | 
			
		||||
				if (!ast_strlen_zero(o->chan->call_forward)) {
 | 
			
		||||
@@ -294,7 +297,8 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localu
 | 
			
		||||
								peer = o->chan;
 | 
			
		||||
								*allowredir_in = o->allowredirect_in;
 | 
			
		||||
								*allowredir_out = o->allowredirect_out;
 | 
			
		||||
								*allowdisconnect = o->allowdisconnect;
 | 
			
		||||
								*allowdisconnect_in = o->allowdisconnect_in;
 | 
			
		||||
								*allowdisconnect_out = o->allowdisconnect_out;
 | 
			
		||||
							}
 | 
			
		||||
							break;
 | 
			
		||||
						case AST_CONTROL_BUSY:
 | 
			
		||||
@@ -379,7 +383,7 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localu
 | 
			
		||||
				strncpy(status, "CANCEL", statussize - 1);
 | 
			
		||||
				return NULL;
 | 
			
		||||
			}
 | 
			
		||||
			if (f && (f->frametype == AST_FRAME_DTMF) && *allowdisconnect &&
 | 
			
		||||
			if (f && (f->frametype == AST_FRAME_DTMF) && *allowdisconnect_out &&
 | 
			
		||||
				(f->subclass == '*')) {
 | 
			
		||||
			    if (option_verbose > 3)
 | 
			
		||||
				ast_verbose(VERBOSE_PREFIX_3 "User hit %c to disconnect call.\n", f->subclass);
 | 
			
		||||
@@ -413,7 +417,8 @@ static int dial_exec(struct ast_channel *chan, void *data)
 | 
			
		||||
	int to;
 | 
			
		||||
	int allowredir_in=0;
 | 
			
		||||
	int allowredir_out=0;
 | 
			
		||||
	int allowdisconnect=0;
 | 
			
		||||
	int allowdisconnect_in=0;
 | 
			
		||||
	int allowdisconnect_out=0;
 | 
			
		||||
	int privacy=0;
 | 
			
		||||
	int announce=0;
 | 
			
		||||
	int resetcdr=0;
 | 
			
		||||
@@ -683,8 +688,11 @@ static int dial_exec(struct ast_channel *chan, void *data)
 | 
			
		||||
				tmp->musiconhold = 1;
 | 
			
		||||
                        else    tmp->musiconhold = 0;
 | 
			
		||||
			if (strchr(transfer, 'H'))
 | 
			
		||||
				allowdisconnect = tmp->allowdisconnect = 1;
 | 
			
		||||
                        else    allowdisconnect = tmp->allowdisconnect = 0;
 | 
			
		||||
				allowdisconnect_out = tmp->allowdisconnect_out = 1;
 | 
			
		||||
                        else    allowdisconnect_out = tmp->allowdisconnect_out = 0;
 | 
			
		||||
			if(strchr(transfer, 'h'))
 | 
			
		||||
				allowdisconnect_in = tmp->allowdisconnect_in = 1;
 | 
			
		||||
			else	allowdisconnect_in = tmp->allowdisconnect_in = 0;
 | 
			
		||||
			if(strchr(transfer, 'g'))
 | 
			
		||||
				go_on=1;
 | 
			
		||||
			if (strchr(transfer, 'f'))
 | 
			
		||||
@@ -843,7 +851,7 @@ static int dial_exec(struct ast_channel *chan, void *data)
 | 
			
		||||
		strncpy(status, "CHANUNAVAIL", sizeof(status) - 1);
 | 
			
		||||
 | 
			
		||||
	time(&start_time);
 | 
			
		||||
	peer = wait_for_answer(chan, outgoing, &to, &allowredir_in, &allowredir_out, &allowdisconnect, &sentringing, status, sizeof(status));
 | 
			
		||||
	peer = wait_for_answer(chan, outgoing, &to, &allowredir_in, &allowredir_out, &allowdisconnect_in, &allowdisconnect_out, &sentringing, status, sizeof(status));
 | 
			
		||||
 | 
			
		||||
	if (!peer) {
 | 
			
		||||
		if (to) 
 | 
			
		||||
@@ -913,7 +921,8 @@ static int dial_exec(struct ast_channel *chan, void *data)
 | 
			
		||||
			config.play_to_callee=play_to_callee;
 | 
			
		||||
			config.allowredirect_in = allowredir_in;
 | 
			
		||||
			config.allowredirect_out = allowredir_out;
 | 
			
		||||
			config.allowdisconnect = allowdisconnect;
 | 
			
		||||
			config.allowdisconnect_in = allowdisconnect_in;
 | 
			
		||||
			config.allowdisconnect_out = allowdisconnect_out;
 | 
			
		||||
			config.timelimit = timelimit;
 | 
			
		||||
			config.play_warning = play_warning;
 | 
			
		||||
			config.warning_freq = warning_freq;
 | 
			
		||||
 
 | 
			
		||||
@@ -66,8 +66,8 @@ static char *descrip =
 | 
			
		||||
"      'v' -- video mode\n"
 | 
			
		||||
"      'q' -- quiet mode (don't play enter/leave sounds)\n"
 | 
			
		||||
"      'M' -- enable music on hold when the conference has a single caller\n"
 | 
			
		||||
"      'x' -- exit the conference if the last marked user left\n"
 | 
			
		||||
"      'w' -- wait until a marked user has entered the conference\n"
 | 
			
		||||
"      'x' -- close the conference when last user marked with 'x' exits\n"
 | 
			
		||||
"      'w' -- wait until a user marked with the 'x' option enters the conference\n"
 | 
			
		||||
"      'b' -- run AGI script specified in ${MEETME_AGI_BACKGROUND}\n"
 | 
			
		||||
"         Default: conf-background.agi\n"
 | 
			
		||||
"        (Note: This does not work with non-Zap channels in the same conference)\n"
 | 
			
		||||
 
 | 
			
		||||
@@ -101,6 +101,7 @@ static char *descrip =
 | 
			
		||||
"      't' -- allow the called user transfer the calling user\n"
 | 
			
		||||
"      'T' -- to allow the calling user to transfer the call.\n"
 | 
			
		||||
"      'd' -- data-quality (modem) call (minimum delay).\n"
 | 
			
		||||
"      'h' -- allow callee to hang up by hitting *.\n"
 | 
			
		||||
"      'H' -- allow caller to hang up by hitting *.\n"
 | 
			
		||||
"      'n' -- no retries on the timeout; will exit this application and go to the next step.\n"
 | 
			
		||||
"      'r' -- ring instead of playing MOH\n"
 | 
			
		||||
@@ -149,7 +150,8 @@ struct localuser {
 | 
			
		||||
	int ringbackonly;
 | 
			
		||||
	int musiconhold;
 | 
			
		||||
	int dataquality;
 | 
			
		||||
	int allowdisconnect;
 | 
			
		||||
	int allowdisconnect_in;
 | 
			
		||||
	int allowdisconnect_out;
 | 
			
		||||
	time_t lastcall;
 | 
			
		||||
	struct member *member;
 | 
			
		||||
	struct localuser *next;
 | 
			
		||||
@@ -703,7 +705,7 @@ static int valid_exit(struct queue_ent *qe, char digit)
 | 
			
		||||
 | 
			
		||||
#define AST_MAX_WATCHERS 256
 | 
			
		||||
 | 
			
		||||
static struct localuser *wait_for_answer(struct queue_ent *qe, struct localuser *outgoing, int *to, int *allowredir_in, int *allowredir_out, int *allowdisconnect, char *digit)
 | 
			
		||||
static struct localuser *wait_for_answer(struct queue_ent *qe, struct localuser *outgoing, int *to, int *allowredir_in, int *allowredir_out, int *allowdisconnect_in, int *allowdisconnect_out, char *digit)
 | 
			
		||||
{
 | 
			
		||||
	char *queue = qe->parent->name;
 | 
			
		||||
	struct localuser *o;
 | 
			
		||||
@@ -753,7 +755,8 @@ static struct localuser *wait_for_answer(struct queue_ent *qe, struct localuser
 | 
			
		||||
					peer = o;
 | 
			
		||||
					*allowredir_in = o->allowredirect_in;
 | 
			
		||||
					*allowredir_out = o->allowredirect_out;
 | 
			
		||||
					*allowdisconnect = o->allowdisconnect;
 | 
			
		||||
					*allowdisconnect_in = o->allowdisconnect_in;
 | 
			
		||||
					*allowdisconnect_out = o->allowdisconnect_out;
 | 
			
		||||
				}
 | 
			
		||||
			} else if (o->chan && (o->chan == winner)) {
 | 
			
		||||
				f = ast_read(winner);
 | 
			
		||||
@@ -768,7 +771,8 @@ static struct localuser *wait_for_answer(struct queue_ent *qe, struct localuser
 | 
			
		||||
								peer = o;
 | 
			
		||||
								*allowredir_in = o->allowredirect_in;
 | 
			
		||||
								*allowredir_out = o->allowredirect_out;
 | 
			
		||||
								*allowdisconnect = o->allowdisconnect;
 | 
			
		||||
								*allowdisconnect_in = o->allowdisconnect_out;
 | 
			
		||||
								*allowdisconnect_out = o->allowdisconnect_out;
 | 
			
		||||
							}
 | 
			
		||||
							break;
 | 
			
		||||
						case AST_CONTROL_BUSY:
 | 
			
		||||
@@ -836,7 +840,7 @@ static struct localuser *wait_for_answer(struct queue_ent *qe, struct localuser
 | 
			
		||||
				*to=-1;
 | 
			
		||||
				return NULL;
 | 
			
		||||
			}
 | 
			
		||||
			if (f && (f->frametype == AST_FRAME_DTMF) && allowdisconnect && (f->subclass == '*')) {
 | 
			
		||||
			if (f && (f->frametype == AST_FRAME_DTMF) && allowdisconnect_out && (f->subclass == '*')) {
 | 
			
		||||
			    if (option_verbose > 3)
 | 
			
		||||
					ast_verbose(VERBOSE_PREFIX_3 "User hit %c to disconnect call.\n", f->subclass);
 | 
			
		||||
				*to=0;
 | 
			
		||||
@@ -995,7 +999,8 @@ static int try_calling(struct queue_ent *qe, char *options, char *announceoverri
 | 
			
		||||
	int to;
 | 
			
		||||
	int allowredir_in=0;
 | 
			
		||||
	int allowredir_out=0;
 | 
			
		||||
	int allowdisconnect=0;
 | 
			
		||||
	int allowdisconnect_in=0;
 | 
			
		||||
	int allowdisconnect_out=0;
 | 
			
		||||
	char restofit[AST_MAX_EXTENSION];
 | 
			
		||||
	char oldexten[AST_MAX_EXTENSION]="";
 | 
			
		||||
	char oldcontext[AST_MAX_EXTENSION]="";
 | 
			
		||||
@@ -1046,8 +1051,10 @@ static int try_calling(struct queue_ent *qe, char *options, char *announceoverri
 | 
			
		||||
				tmp->musiconhold = 1;
 | 
			
		||||
			if (strchr(options, 'd'))
 | 
			
		||||
				tmp->dataquality = 1;
 | 
			
		||||
			if (strchr(options, 'h'))
 | 
			
		||||
				tmp->allowdisconnect_in = 1;
 | 
			
		||||
			if (strchr(options, 'H'))
 | 
			
		||||
				tmp->allowdisconnect = 1;
 | 
			
		||||
				tmp->allowdisconnect_out = 1;
 | 
			
		||||
			if ((strchr(options, 'n')) && (now - qe->start >= qe->parent->timeout))
 | 
			
		||||
				*go_on = 1;
 | 
			
		||||
		}
 | 
			
		||||
@@ -1089,7 +1096,7 @@ static int try_calling(struct queue_ent *qe, char *options, char *announceoverri
 | 
			
		||||
		to = -1;
 | 
			
		||||
	ring_one(qe, outgoing);
 | 
			
		||||
	ast_mutex_unlock(&qe->parent->lock);
 | 
			
		||||
	lpeer = wait_for_answer(qe, outgoing, &to, &allowredir_in, &allowredir_out, &allowdisconnect, &digit);
 | 
			
		||||
	lpeer = wait_for_answer(qe, outgoing, &to, &allowredir_in, &allowredir_out, &allowdisconnect_in, &allowdisconnect_out, &digit);
 | 
			
		||||
	ast_mutex_lock(&qe->parent->lock);
 | 
			
		||||
	if (qe->parent->strategy == QUEUE_STRATEGY_RRMEMORY) {
 | 
			
		||||
		store_next(qe, outgoing);
 | 
			
		||||
@@ -1194,7 +1201,8 @@ static int try_calling(struct queue_ent *qe, char *options, char *announceoverri
 | 
			
		||||
		memset(&config,0,sizeof(struct ast_bridge_config));
 | 
			
		||||
        config.allowredirect_in = allowredir_in;
 | 
			
		||||
        config.allowredirect_out = allowredir_out;
 | 
			
		||||
        config.allowdisconnect = allowdisconnect;
 | 
			
		||||
        config.allowdisconnect_in = allowdisconnect_in;
 | 
			
		||||
	config.allowdisconnect_out = allowdisconnect_out;
 | 
			
		||||
        bridge = ast_bridge_call(qe->chan,peer,&config);
 | 
			
		||||
 | 
			
		||||
		if (strcasecmp(oldcontext, qe->chan->context) || strcasecmp(oldexten, qe->chan->exten)) {
 | 
			
		||||
 
 | 
			
		||||
@@ -271,7 +271,8 @@ struct ast_bridge_config {
 | 
			
		||||
	int play_to_callee;
 | 
			
		||||
	int allowredirect_in;
 | 
			
		||||
	int allowredirect_out;
 | 
			
		||||
	int allowdisconnect;
 | 
			
		||||
	int allowdisconnect_in;
 | 
			
		||||
	int allowdisconnect_out;
 | 
			
		||||
	long timelimit;
 | 
			
		||||
	long play_warning;
 | 
			
		||||
	long warning_freq;
 | 
			
		||||
 
 | 
			
		||||
@@ -226,9 +226,10 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast
 | 
			
		||||
	struct ast_channel *transferer;
 | 
			
		||||
	struct ast_channel *transferee;
 | 
			
		||||
	char *transferer_real_context;
 | 
			
		||||
	int allowdisconnect,allowredirect_in,allowredirect_out;
 | 
			
		||||
	int allowdisconnect_in,allowdisconnect_out,allowredirect_in,allowredirect_out;
 | 
			
		||||
 | 
			
		||||
	allowdisconnect = config->allowdisconnect;
 | 
			
		||||
	allowdisconnect_in = config->allowdisconnect_in;
 | 
			
		||||
	allowdisconnect_out = config->allowdisconnect_out;
 | 
			
		||||
	allowredirect_in = config->allowredirect_in;
 | 
			
		||||
	allowredirect_out = config->allowredirect_out;
 | 
			
		||||
 | 
			
		||||
@@ -283,14 +284,16 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast
 | 
			
		||||
					ast_channel_setoption(chan, ntohs(aoh->option), aoh->data, f->datalen - sizeof(struct ast_option_header), 0);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
            if (f && (f->frametype == AST_FRAME_DTMF) && (who == chan) && allowdisconnect &&
 | 
			
		||||
		     (f->subclass == '*')) {
 | 
			
		||||
		if (option_verbose > 3)
 | 
			
		||||
			ast_verbose(VERBOSE_PREFIX_3 "User hit %c to disconnect call.\n", f->subclass);
 | 
			
		||||
		/* check for '*', if we find it it's time to disconnect */
 | 
			
		||||
		if (f && (f->frametype == AST_FRAME_DTMF) &&
 | 
			
		||||
			(((who == chan) && allowdisconnect_out) || ((who == peer) && allowdisconnect_in)) &&
 | 
			
		||||
			(f->subclass == '*')) {
 | 
			
		||||
			
 | 
			
		||||
			if (option_verbose > 3)
 | 
			
		||||
				ast_verbose(VERBOSE_PREFIX_3 "User hit %c to disconnect call.\n", f->subclass);
 | 
			
		||||
			res = -1;
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if ((f->frametype == AST_FRAME_DTMF) &&
 | 
			
		||||
			((allowredirect_in && who == peer) || (allowredirect_out && who == chan)) &&
 | 
			
		||||
@@ -586,7 +589,8 @@ static int park_exec(struct ast_channel *chan, void *data)
 | 
			
		||||
		memset(&config,0,sizeof(struct ast_bridge_config));
 | 
			
		||||
		config.allowredirect_in = 1;
 | 
			
		||||
		config.allowredirect_out = 1;
 | 
			
		||||
		config.allowdisconnect = 0;
 | 
			
		||||
		config.allowdisconnect_out = 0;
 | 
			
		||||
		config.allowdisconnect_in = 0;
 | 
			
		||||
		config.timelimit = 0;
 | 
			
		||||
		config.play_warning = 0;
 | 
			
		||||
		config.warning_freq = 0;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user