Merged revisions 311297 via svnmerge from
authorRichard Mudgett <rmudgett@digium.com>
Fri, 18 Mar 2011 03:00:39 +0000 (03:00 +0000)
committerRichard Mudgett <rmudgett@digium.com>
Fri, 18 Mar 2011 03:00:39 +0000 (03:00 +0000)
https://origsvn.digium.com/svn/asterisk/branches/1.8

........
  r311297 | rmudgett | 2011-03-17 21:59:05 -0500 (Thu, 17 Mar 2011) | 12 lines

  Race condition when ISDN CallRerouting/CallDeflection invoked.

  The queued AST_CONTROL_BUSY could sometimes be processed before the
  call_forward dial string is recognized.

  * Moved setting the call_forwarding dial string after sending a response
  to the initiator and just queue an empty frame to wake up the media thread
  instead of an AST_CONTROL_BUSY.

  * Added check for empty rerouting/deflection number and respond with an
  error.
........

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

channels/sig_pri.c

index c66b82d..f36a7e2 100644 (file)
@@ -3927,16 +3927,35 @@ static void sig_pri_handle_subcmds(struct sig_pri_span *pri, int chanpos, int ev
                                struct pri_party_redirecting pri_deflection;
 
                                if (!call_rsp) {
+                                       ast_log(LOG_WARNING,
+                                               "Span %d: %s tried CallRerouting/CallDeflection to '%s' without call!\n",
+                                               pri->span, owner->name, subcmd->u.rerouting.deflection.to.number.str);
                                        ast_channel_unlock(owner);
+                                       break;
+                               }
+                               if (ast_strlen_zero(subcmd->u.rerouting.deflection.to.number.str)) {
                                        ast_log(LOG_WARNING,
-                                               "CallRerouting/CallDeflection to '%s' without call!\n",
-                                               subcmd->u.rerouting.deflection.to.number.str);
+                                               "Span %d: %s tried CallRerouting/CallDeflection to empty number!\n",
+                                               pri->span, owner->name);
+                                       pri_rerouting_rsp(pri->pri, call_rsp, subcmd->u.rerouting.invoke_id,
+                                               PRI_REROUTING_RSP_INVALID_NUMBER);
+                                       ast_channel_unlock(owner);
                                        break;
                                }
 
-                               pri_deflection = subcmd->u.rerouting.deflection;
+                               ast_verb(3, "Span %d: %s is CallRerouting/CallDeflection to '%s'.\n",
+                                       pri->span, owner->name, subcmd->u.rerouting.deflection.to.number.str);
 
-                               ast_string_field_set(owner, call_forward, pri_deflection.to.number.str);
+                               /*
+                                * Send back positive ACK to CallRerouting/CallDeflection.
+                                *
+                                * Note:  This call will be hungup by the core when it processes
+                                * the call_forward string.
+                                */
+                               pri_rerouting_rsp(pri->pri, call_rsp, subcmd->u.rerouting.invoke_id,
+                                       PRI_REROUTING_RSP_OK_CLEAR);
+
+                               pri_deflection = subcmd->u.rerouting.deflection;
 
                                /* Adjust the deflecting to number based upon the subscription option. */
                                switch (subcmd->u.rerouting.subscription_option) {
@@ -3962,17 +3981,12 @@ static void sig_pri_handle_subcmds(struct sig_pri_span *pri, int chanpos, int ev
                                ast_channel_set_redirecting(owner, &ast_redirecting, NULL);
                                ast_party_redirecting_free(&ast_redirecting);
 
-                               /*
-                                * Send back positive ACK to CallRerouting/CallDeflection.
-                                *
-                                * Note:  This call will be hungup by the dial application when
-                                * it processes the call_forward string set above.
-                                */
-                               pri_rerouting_rsp(pri->pri, call_rsp, subcmd->u.rerouting.invoke_id,
-                                       PRI_REROUTING_RSP_OK_CLEAR);
+                               /* Request the core to forward to the new number. */
+                               ast_string_field_set(owner, call_forward,
+                                       subcmd->u.rerouting.deflection.to.number.str);
 
-                               /* This line is BUSY to further attempts by this dialing attempt. */
-                               ast_queue_control(owner, AST_CONTROL_BUSY);
+                               /* Wake up the channel. */
+                               ast_queue_frame(owner, &ast_null_frame);
 
                                ast_channel_unlock(owner);
                        }