summaryrefslogtreecommitdiff
path: root/net/asterisk/files/patch-apps::app_dial.c
blob: 6abe48a17d9f18b0acfd4135fd064d1079014b0d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
--- apps/app_dial.c.orig	Wed Feb  6 18:45:30 2008
+++ apps/app_dial.c	Wed Feb  6 18:51:59 2008
@@ -297,6 +297,8 @@ AST_APP_OPTIONS(dial_exec_options, {
 	OPT_CALLER_HANGUP | OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER | \
 	OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR | OPT_CALLEE_PARK | OPT_CALLER_PARK))
 
+static int detect_disconnect(struct ast_channel *chan, char code);
+
 /* We define a custom "local user" structure because we
    use it not only for keeping track of what is in use but
    also for keeping track of who we're dialing. */
@@ -402,6 +404,7 @@ static struct ast_channel *wait_for_answ
 	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);
+
 	
 	if (single) {
 		/* Turn off hold music, etc */
@@ -716,9 +719,9 @@ static struct ast_channel *wait_for_answ
 				}
 
 				if (ast_test_flag(peerflags, OPT_CALLER_HANGUP) && 
-						  (f->subclass == '*')) { /* hmm it it not guaranteed to be '*' anymore. */
+						  detect_disconnect(in, f->subclass)) { /* hmm it it not guaranteed to be '*' anymore. */
 					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");
@@ -776,6 +779,56 @@ static struct ast_channel *wait_for_answ
 	
 	return peer;
 }
+
+static char featurecode[FEATURE_MAX_LEN + 1] = "";
+
+static int detect_disconnect(struct ast_channel *chan, char code)
+{
+	struct feature_interpret_result result;
+	int x;
+	struct ast_flags features;
+	int res = FEATURE_RETURN_PASSDIGITS;
+	struct ast_call_feature *feature;
+	char *cptr;
+	int len;
+
+	len = strlen(featurecode);
+	if (len >= FEATURE_MAX_LEN) {
+		featurecode[0] = '\0';
+	}
+	cptr = &featurecode[strlen(featurecode)];
+	cptr[0] = code;
+	cptr[1] = '\0';
+
+	memset(&features, 0, sizeof(struct ast_flags));
+	ast_set_flag(&features, AST_FEATURE_DISCONNECT);
+
+	ast_features_lock();
+
+	res = ast_feature_detect(chan, &features, featurecode, &result);
+
+	if (res != FEATURE_RETURN_STOREDIGITS)
+		featurecode[0] = '\0';
+
+	if (result.builtin_feature && result.builtin_feature->feature_mask & AST_FEATURE_DISCONNECT) {
+		ast_features_unlock();
+		return 1;
+	}
+		
+	for (x = 0; x < result.num_dyn_features; ++x) {
+		feature = result.dynamic_features[x];
+		if (feature->feature_mask & AST_FEATURE_DISCONNECT) {
+			ast_features_unlock();
+			return 1;
+		}
+	}
+
+	ast_features_unlock();
+
+	return 0;
+}
+
+
 
 static void replace_macro_delimiter(char *s)
 {