Make the Hangup application set a softhangup flag.
authorRichard Mudgett <rmudgett@digium.com>
Thu, 14 Jun 2012 22:57:21 +0000 (22:57 +0000)
committerRichard Mudgett <rmudgett@digium.com>
Thu, 14 Jun 2012 22:57:21 +0000 (22:57 +0000)
The Hangup application used to just return -1 to cause normal dialplan
execution to hangup a channel.  For the non-normal execution routines like
predial and connected-line interception routines, the hangup request would
exit the routine early but otherwise be ignored.

* Made the Hangup application not allow setting a cause code of zero.  A
zero cause code is not defined.

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@368979 65c4cc65-6c06-0410-ace0-fbb531ad65f3

main/pbx.c

index 3ed7df4..c6120b2 100644 (file)
@@ -10020,29 +10020,32 @@ static int pbx_builtin_setamaflags(struct ast_channel *chan, const char *data)
  */
 static int pbx_builtin_hangup(struct ast_channel *chan, const char *data)
 {
+       int cause;
+
        ast_set_hangupsource(chan, "dialplan/builtin", 0);
 
        if (!ast_strlen_zero(data)) {
-               int cause;
-               char *endptr;
-
-               if ((cause = ast_str2cause(data)) > -1) {
-                       ast_channel_hangupcause_set(chan, cause);
-                       return -1;
-               }
-
-               cause = strtol((const char *) data, &endptr, 10);
-               if (cause != 0 || (data != endptr)) {
-                       ast_channel_hangupcause_set(chan, cause);
-                       return -1;
+               cause = ast_str2cause(data);
+               if (cause <= 0) {
+                       if (sscanf(data, "%30d", &cause) != 1 || cause <= 0) {
+                               ast_log(LOG_WARNING, "Invalid cause given to Hangup(): \"%s\"\n", data);
+                               cause = 0;
+                       }
                }
-
-               ast_log(LOG_WARNING, "Invalid cause given to Hangup(): \"%s\"\n", (char *) data);
+       } else {
+               cause = 0;
        }
 
-       if (!ast_channel_hangupcause(chan)) {
-               ast_channel_hangupcause_set(chan, AST_CAUSE_NORMAL_CLEARING);
+       ast_channel_lock(chan);
+       if (cause <= 0) {
+               cause = ast_channel_hangupcause(chan);
+               if (cause <= 0) {
+                       cause = AST_CAUSE_NORMAL_CLEARING;
+               }
        }
+       ast_channel_hangupcause_set(chan, cause);
+       ast_softhangup_nolock(chan, AST_SOFTHANGUP_EXPLICIT);
+       ast_channel_unlock(chan);
 
        return -1;
 }