Merged revisions 183126 via svnmerge from

https://origsvn.digium.com/svn/asterisk/branches/1.4

........
  r183126 | dvossel | 2009-03-19 11:15:16 -0500 (Thu, 19 Mar 2009) | 17 lines
  
  Allow disconnect feature before a call is bridged
  
  feature.conf has a disconnect option.  By default this option is set to '*', but it could be anything.  If a user wishes to disconnect a call before the other side answers, only '*' will work, regardless if the disconnect option is set to something else.  This is because features are unavailable until bridging takes place.  The default disconnect option, '*', was hardcoded in app_dial, which doesn't make any sense from a user perspective since they may expect it to be something different.  This patch allows features to be detected from outside of the bridge, but not operated on.  In this case, the disconnect feature can be detected before briding and handled outside of features.c.
  
  (closes issue #11583)
  Reported by: sobomax
  Patches:
  	patch-apps__app_dial.c uploaded by sobomax (license 359)
  	11583.latest-patch uploaded by murf (license 17)
  	detect_disconnect.diff uploaded by dvossel (license 671)
  Tested by: sobomax, dvossel
  Review: http://reviewboard.digium.com/r/195/
........


git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@183172 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
David Vossel
2009-03-19 16:28:33 +00:00
parent 10529ea029
commit 2764c2821f
3 changed files with 161 additions and 90 deletions

View File

@@ -560,6 +560,7 @@ struct chanlist {
uint64_t flags;
};
static int detect_disconnect(struct ast_channel *chan, char code, struct ast_str *featurecode);
static void hanguptree(struct chanlist *outgoing, struct ast_channel *exception, int answered_elsewhere)
{
@@ -809,7 +810,7 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in,
#ifdef HAVE_EPOLL
struct chanlist *epollo;
#endif
struct ast_str *featurecode = ast_str_alloca(FEATURE_MAX_LEN + 1);
if (single) {
/* Turn off hold music, etc */
ast_deactivate_generator(in);
@@ -1058,8 +1059,8 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in,
}
if (ast_test_flag64(peerflags, OPT_CALLER_HANGUP) &&
(f->subclass == '*')) { /* hmm it it not guaranteed to be '*' anymore. */
ast_verb(3, "User hit %c to disconnect call.\n", f->subclass);
detect_disconnect(in, f->subclass, featurecode)) {
ast_verb(3, "User requested call disconnect.\n");
*to = 0;
strcpy(pa->status, "CANCEL");
ast_cdr_noanswer(in->cdr);
@@ -1103,6 +1104,26 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in,
return peer;
}
static int detect_disconnect(struct ast_channel *chan, char code, struct ast_str *featurecode)
{
struct ast_flags features = { AST_FEATURE_DISCONNECT }; /* only concerned with disconnect feature */
struct ast_call_feature feature;
int res;
ast_str_append(&featurecode, 1, "%c", code);
res = ast_feature_detect(chan, &features, ast_str_buffer(featurecode), &feature);
if (res != AST_FEATURE_RETURN_STOREDIGITS) {
ast_str_reset(featurecode);
}
if (feature.feature_mask & AST_FEATURE_DISCONNECT) {
return 1;
}
return 0;
}
static void replace_macro_delimiter(char *s)
{
for (; *s; s++)
@@ -1597,7 +1618,7 @@ static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags
res = -1; /* reset default */
}
if (ast_test_flag64(&opts, OPT_DTMF_EXIT)) {
if (ast_test_flag64(&opts, OPT_DTMF_EXIT) || ast_test_flag64(&opts, OPT_CALLER_HANGUP)) {
__ast_answer(chan, 0, 0);
}