diff --git a/apps/app_dial.c b/apps/app_dial.c index ba60d278d6..b32ab20671 100755 --- a/apps/app_dial.c +++ b/apps/app_dial.c @@ -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; diff --git a/apps/app_meetme.c b/apps/app_meetme.c index 2070490f17..fd40932e3d 100755 --- a/apps/app_meetme.c +++ b/apps/app_meetme.c @@ -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" diff --git a/apps/app_queue.c b/apps/app_queue.c index 2f9f3df29a..362278034f 100755 --- a/apps/app_queue.c +++ b/apps/app_queue.c @@ -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)) { diff --git a/include/asterisk/channel.h b/include/asterisk/channel.h index e4421c1b1f..cf86318ceb 100755 --- a/include/asterisk/channel.h +++ b/include/asterisk/channel.h @@ -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; diff --git a/res/res_features.c b/res/res_features.c index d03f7f3945..2190cd2851 100755 --- a/res/res_features.c +++ b/res/res_features.c @@ -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;