aboutsummaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authordvossel <dvossel@f38db490-d61c-443f-a65b-d21fe96a405b>2009-03-19 16:15:16 +0000
committerdvossel <dvossel@f38db490-d61c-443f-a65b-d21fe96a405b>2009-03-19 16:15:16 +0000
commit8da3da0e2bd336aea758d848c7cb5d7364858ec7 (patch)
treebdffd6a73516bcad0d3e9e13b7f5b3cd53a32420 /apps
parenta7a0e1e586424706c1b1799d76eb09f6770771c2 (diff)
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: http://svn.digium.com/svn/asterisk/branches/1.4@183126 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'apps')
-rw-r--r--apps/app_dial.c39
1 files changed, 35 insertions, 4 deletions
diff --git a/apps/app_dial.c b/apps/app_dial.c
index 6178b346c..63d00a7d4 100644
--- a/apps/app_dial.c
+++ b/apps/app_dial.c
@@ -383,6 +383,7 @@ static int onedigit_goto(struct ast_channel *chan, const char *context, char ext
return 0;
}
+static int detect_disconnect(struct ast_channel *chan, char code, char *featurecode, int len);
static const char *get_cid_name(char *name, int namelen, struct ast_channel *chan)
{
@@ -417,7 +418,9 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in, struct dial_l
struct ast_channel *peer = NULL;
/* single is set if only one destination is enabled */
int single = outgoing && !outgoing->next && !ast_test_flag(outgoing, OPT_MUSICBACK | OPT_RINGBACK);
-
+
+ char featurecode[FEATURE_MAX_LEN + 1] = { 0, };
+
if (single) {
/* Turn off hold music, etc */
ast_deactivate_generator(in);
@@ -742,10 +745,10 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in, struct dial_l
}
}
- if (ast_test_flag(peerflags, OPT_CALLER_HANGUP) &&
- (f->subclass == '*')) { /* hmm it it not guaranteed to be '*' anymore. */
+ if (ast_test_flag(peerflags, OPT_CALLER_HANGUP) &&
+ detect_disconnect(in, f->subclass, featurecode, sizeof(featurecode))) {
if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "User hit %c to disconnect call.\n", f->subclass);
+ ast_verbose(VERBOSE_PREFIX_3 "User requested call disconnect.\n");
*to=0;
ast_cdr_noanswer(in->cdr);
strcpy(status, "CANCEL");
@@ -786,6 +789,34 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in, struct dial_l
return peer;
}
+static int detect_disconnect(struct ast_channel *chan, char code, char *featurecode, int len)
+{
+ struct ast_flags features = { AST_FEATURE_DISCONNECT }; /* only concerned with disconnect feature */
+ struct ast_call_feature feature;
+ char *tmp;
+ int res;
+
+ if ((strlen(featurecode)) < (len - 2)) {
+ tmp = &featurecode[strlen(featurecode)];
+ tmp[0] = code;
+ tmp[1] = '\0';
+ } else {
+ featurecode[0] = 0;
+ return -1; /* no room in featurecode buffer */
+ }
+
+ res = ast_feature_detect(chan, &features, featurecode, &feature);
+
+ if (res != FEATURE_RETURN_STOREDIGITS) {
+ featurecode[0] = '\0';
+ }
+ if (feature.feature_mask & AST_FEATURE_DISCONNECT) {
+ return 1;
+ }
+
+ return 0;
+}
+
static void replace_macro_delimiter(char *s)
{
for (; *s; s++)