]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Merged revisions 335064 via svnmerge from
authorMatthew Jordan <mjordan@digium.com>
Fri, 9 Sep 2011 16:27:01 +0000 (16:27 +0000)
committerMatthew Jordan <mjordan@digium.com>
Fri, 9 Sep 2011 16:27:01 +0000 (16:27 +0000)
https://origsvn.digium.com/svn/asterisk/branches/1.8

........
  r335064 | mjordan | 2011-09-09 11:09:09 -0500 (Fri, 09 Sep 2011) | 23 lines

  Updated SIP 484 handling; added Incomplete control frame

  When a SIP phone uses the dial application and receives a 484 Address
  Incomplete response, if overlapped dialing is enabled for SIP, then
  the 484 Address Incomplete is forwarded back to the SIP phone and the
  HANGUPCAUSE channel variable is set to 28.  Previously, the Incomplete
  application dialplan logic was automatically triggered; now, explicit
  dialplan usage of the application is required.

  Additionally, this patch adds a new AST_CONTOL_FRAME type called
  AST_CONTROL_INCOMPLETE.  If a channel driver receives this control frame,
  it is an indication that the dialplan expects more digits back from the
  device.  If the device supports overlap dialing it should attempt to
  notify the device that the dialplan is waiting for more digits; otherwise,
  it can handle the frame in a manner appropriate to the channel driver.

  (closes issue ASTERISK-17288)
  Reported by: Mikael Carlsson
  Tested by: Matthew Jordan

  Review: https://reviewboard.asterisk.org/r/1416/
........

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

21 files changed:
addons/chan_ooh323.c
apps/app_dial.c
channels/chan_alsa.c
channels/chan_console.c
channels/chan_dahdi.c
channels/chan_h323.c
channels/chan_mgcp.c
channels/chan_misdn.c
channels/chan_oss.c
channels/chan_sip.c
channels/chan_skinny.c
channels/chan_unistim.c
channels/chan_usbradio.c
channels/sig_pri.c
channels/sig_ss7.c
funcs/func_frame_trace.c
include/asterisk/frame.h
main/channel.c
main/dial.c
main/features.c
main/pbx.c

index 1a5f1eea0133a2307125ee0518efbed5758f46f2..9f3f33dd0051a587a5eea8e9633f3295ee9a1559 100644 (file)
@@ -1243,21 +1243,24 @@ static int ooh323_indicate(struct ast_channel *ast, int condition, const void *d
         
        ast_mutex_lock(&p->lock);
        switch (condition) {
+       case AST_CONTROL_INCOMPLETE:
+               /* While h323 does support overlapped dialing, this channel driver does not
+                * at this time.  Treat a response of Incomplete as if it were congestion.
+                */
        case AST_CONTROL_CONGESTION:
                if (!ast_test_flag(p, H323_ALREADYGONE)) {
-                       ooHangCall(callToken, OO_REASON_LOCAL_CONGESTED, 
-                                               AST_CAUSE_SWITCH_CONGESTION);
+                       ooHangCall(callToken, OO_REASON_LOCAL_CONGESTED, AST_CAUSE_SWITCH_CONGESTION);
                        ast_set_flag(p, H323_ALREADYGONE);
                }
                break;
        case AST_CONTROL_BUSY:
                if (!ast_test_flag(p, H323_ALREADYGONE)) {
-                       ooHangCall(callToken, OO_REASON_LOCAL_BUSY, AST_CAUSE_USER_BUSY);
+                       ooHangCall(callToken, OO_REASON_LOCAL_BUSY, AST_CAUSE_USER_BUSY);
                        ast_set_flag(p, H323_ALREADYGONE);
                }
                break;
        case AST_CONTROL_HOLD:
-               ast_moh_start(ast, data, NULL);         
+               ast_moh_start(ast, data, NULL);
                break;
        case AST_CONTROL_UNHOLD:
                ast_moh_stop(ast);
index 515fa1b3f69cc86bcd3251d89df5c3fb0221bae0..c92dec2639e585a2f3f52c598c15202e1422a31a 100644 (file)
@@ -2423,14 +2423,6 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast
                } else { /* Nobody answered, next please? */
                        res = 0;
                }
-
-               /* SIP, in particular, sends back this error code to indicate an
-                * overlap dialled number needs more digits. */
-               if (chan->hangupcause == AST_CAUSE_INVALID_NUMBER_FORMAT) {
-                       res = AST_PBX_INCOMPLETE;
-               }
-
-               /* almost done, although the 'else' block is 400 lines */
        } else {
                const char *number;
 
index b51c942af3a04a1baaaabe92a6b8e61398a8e3e5..bd9aea599f6a3bd511782607f0e4f0c745a337bf 100644 (file)
@@ -536,6 +536,7 @@ static int alsa_indicate(struct ast_channel *chan, int cond, const void *data, s
        case AST_CONTROL_BUSY:
        case AST_CONTROL_CONGESTION:
        case AST_CONTROL_RINGING:
+       case AST_CONTROL_INCOMPLETE:
        case -1:
                res = -1;  /* Ask for inband indications */
                break;
index a0eddbeae31777d3b1a2c7f1319aebd2733b4e1a..7a40f9be6224ac18944eeda2e0c5a3c84908ecd5 100644 (file)
@@ -602,6 +602,7 @@ static int console_indicate(struct ast_channel *chan, int cond, const void *data
        case AST_CONTROL_BUSY:
        case AST_CONTROL_CONGESTION:
        case AST_CONTROL_RINGING:
+       case AST_CONTROL_INCOMPLETE:
        case -1:
                res = -1;  /* Ask for inband indications */
                break;
index 4d5e821747c28322bad09a5e1cc2d2f30bd83ae1..695ebf4ec62fc0600abbe3aca074eedf58613508 100644 (file)
@@ -9398,13 +9398,18 @@ static int dahdi_indicate(struct ast_channel *chan, int condition, const void *d
                                ast_setstate(chan, AST_STATE_RINGING);
                        }
                        break;
+               case AST_CONTROL_INCOMPLETE:
+                       ast_debug(1, "Received AST_CONTROL_INCOMPLETE on %s\n", chan->name);
+                       /* act as a progress or proceeding, allowing the caller to enter additional numbers */
+                       res = 0;
+                       break;
                case AST_CONTROL_PROCEEDING:
-                       ast_debug(1,"Received AST_CONTROL_PROCEEDING on %s\n",chan->name);
+                       ast_debug(1, "Received AST_CONTROL_PROCEEDING on %s\n", chan->name);
                        /* don't continue in ast_indicate */
                        res = 0;
                        break;
                case AST_CONTROL_PROGRESS:
-                       ast_debug(1,"Received AST_CONTROL_PROGRESS on %s\n",chan->name);
+                       ast_debug(1, "Received AST_CONTROL_PROGRESS on %s\n", chan->name);
                        /* don't continue in ast_indicate */
                        res = 0;
                        break;
index e90bee18c3221e703c14ba0171a67c30e2744f03..76fbf80e6b70f50f7e9f43ac37a11a5d815a4832 100644 (file)
@@ -910,6 +910,10 @@ static int oh323_indicate(struct ast_channel *c, int condition, const void *data
                        res = 0;
                }
                break;
+       case AST_CONTROL_INCOMPLETE:
+               /* While h323 does support overlapped dialing, this channel driver does not
+                * at this time.  Treat a response of Incomplete as if it were congestion.
+                */
        case AST_CONTROL_CONGESTION:
                if (c->_state != AST_STATE_UP) {
                        h323_answering_call(token, 1);
index dfd5a310f33fed9d3cda8b2e6253656b290d16db..502b929b60b3ea664c3c060756a52c1979095b05 100644 (file)
@@ -1456,6 +1456,10 @@ static int mgcp_indicate(struct ast_channel *ast, int ind, const void *data, siz
        case AST_CONTROL_BUSY:
                transmit_notify_request(sub, "L/bz");
                break;
+       case AST_CONTROL_INCOMPLETE:
+               /* We do not currently support resetting of the Interdigit Timer, so treat
+                * Incomplete control frames as a congestion response
+                */
        case AST_CONTROL_CONGESTION:
                transmit_notify_request(sub, sub->parent->ncs ? "L/cg" : "G/cg");
                break;
index e9fa800106c9bacc362340bdb217cd326c820725..79753e369a6498bb4df4e9095d93afec16cb45d0 100644 (file)
@@ -6985,6 +6985,19 @@ static int misdn_indication(struct ast_channel *ast, int cond, const void *data,
                chan_misdn_log(1, p->bc->port, " --> * IND :\tproceeding pid:%d\n", p->bc->pid);
                misdn_lib_send_event(p->bc, EVENT_PROCEEDING);
                break;
+       case AST_CONTROL_INCOMPLETE:
+               chan_misdn_log(1, p->bc->port, " --> *\tincomplete pid:%d\n", p->bc->pid);
+               if (!p->overlap_dial) {
+                       /* Overlapped dialing not enabled - send hangup */
+                       p->bc->out_cause = AST_CAUSE_INVALID_NUMBER_FORMAT;
+                       start_bc_tones(p);
+                       misdn_lib_send_event(p->bc, EVENT_DISCONNECT);
+
+                       if (p->bc->nt) {
+                               hanguptone_indicate(p);
+                       }
+               }
+               break;
        case AST_CONTROL_CONGESTION:
                chan_misdn_log(1, p->bc->port, " --> * IND :\tcongestion pid:%d\n", p->bc->pid);
 
index a8ca79a3ee3aa8101b855bcdbb6eb77e2a3a9393..17894ab6fb2a886b5291b4a8d4461868763f7ef0 100644 (file)
@@ -754,6 +754,7 @@ static int oss_indicate(struct ast_channel *c, int cond, const void *data, size_
        int res = 0;
 
        switch (cond) {
+       case AST_CONTROL_INCOMPLETE:
        case AST_CONTROL_BUSY:
        case AST_CONTROL_CONGESTION:
        case AST_CONTROL_RINGING:
index d670de20bd36a787f62822fc93b4fca0e97decdc..e2b2768dace59bb36981c79b860175ffd7725162 100644 (file)
@@ -6727,6 +6727,20 @@ static int sip_indicate(struct ast_channel *ast, int condition, const void *data
                }
                res = -1;
                break;
+       case AST_CONTROL_INCOMPLETE:
+               if (ast->_state != AST_STATE_UP) {
+                       if (ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP)) {
+                               transmit_response_reliable(p, "484 Address Incomplete", &p->initreq);
+                       } else {
+                               transmit_response_reliable(p, "404 Not Found", &p->initreq);
+                       }
+                       p->invitestate = INV_COMPLETED;
+                       sip_alreadygone(p);
+                       ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV);
+                       break;
+               }
+               res = 0;
+               break;
        case AST_CONTROL_PROCEEDING:
                if ((ast->_state != AST_STATE_UP) &&
                    !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
@@ -21172,6 +21186,15 @@ static void handle_response(struct sip_pvt *p, int resp, const char *rest, struc
                                        if (owner)
                                                ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
                                        break;
+                               case 484: /* Address Incomplete */
+                                       if (owner && sipmethod != SIP_BYE) {
+                                               if (ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP)) {
+                                                       ast_queue_hangup_with_cause(p->owner, hangup_sip2cause(resp));
+                                               } else {
+                                                       ast_queue_hangup_with_cause(p->owner, hangup_sip2cause(404));
+                                               }
+                                       }
+                                       break;
                                default:
                                        /* Send hangup */       
                                        if (owner && sipmethod != SIP_BYE)
index dad151ea11c58011f8f1e8ffb462aeddbb3ba2b1..523d7ffdf39bac0ec918338ec7199ed34b006b59 100644 (file)
@@ -4640,6 +4640,8 @@ static char *control2str(int ind) {
                return "CC Not Possible";
        case AST_CONTROL_SRCCHANGE:
                return "Media Source Change";
+       case AST_CONTROL_INCOMPLETE:
+               return "Incomplete";
        case -1:
                return "Stop tone";
        default:
@@ -4743,6 +4745,8 @@ static int skinny_indicate(struct ast_channel *ast, int ind, const void *data, s
        case AST_CONTROL_BUSY:
                setsubstate(sub, SUBSTATE_BUSY);
                return (d->earlyrtp ? -1 : 0); /* Tell asterisk to provide inband signalling if rtp started */
+       case AST_CONTROL_INCOMPLETE:
+               /* Support for incomplete not supported for chan_skinny; treat as congestion */
        case AST_CONTROL_CONGESTION:
                setsubstate(sub, SUBSTATE_CONGESTION);
                return (d->earlyrtp ? -1 : 0); /* Tell asterisk to provide inband signalling if rtp started */
index 8f0cfa59e42f90eb46bc6c29cf70c167a51db3c1..4e3f8081f549337fd92371d4859d294eac253c60 100644 (file)
@@ -4215,6 +4215,10 @@ static int unistim_indicate(struct ast_channel *ast, int ind, const void *data,
                        break;
                }
                return -1;
+       case AST_CONTROL_INCOMPLETE:
+               /* Overlapped dialing is not currently supported for UNIStim.  Treat an indication
+                * of incomplete as congestion
+                */
        case AST_CONTROL_CONGESTION:
                if (ast->_state != AST_STATE_UP) {
                        sub->alreadygone = 1;
index 62a26de7f6fb13de43663aeabe4518424c3d1506..e3d605a3c8c2297477a1e74f7eab15737fd6194f 100644 (file)
@@ -2120,7 +2120,9 @@ static int usbradio_indicate(struct ast_channel *c, int cond, const void *data,
                case AST_CONTROL_RINGING:
                        res = cond;
                        break;
-
+               case AST_CONTROL_INCOMPLETE:
+                       res = AST_CONTROL_CONGESTION;
+                       break;
                case -1:
 #ifndef        NEW_ASTERISK
                        o->cursound = -1;
index 3127371325ccb9a58c855cff01c9d3fcfa0c17d1..7db123e2980b4ace361dec96f7ec548849be4c72 100644 (file)
@@ -7825,6 +7825,15 @@ int sig_pri_indicate(struct sig_pri_chan *p, struct ast_channel *chan, int condi
                /* don't continue in ast_indicate */
                res = 0;
                break;
+       case AST_CONTROL_INCOMPLETE:
+               /* If we are connected or if we support overlap dialing, wait for additional digits */
+               if (p->call_level == SIG_PRI_CALL_LEVEL_CONNECT || (p->pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)) {
+                       res = 0;
+                       break;
+               }
+               /* Otherwise, treat as congestion */
+               chan->hangupcause = AST_CAUSE_INVALID_NUMBER_FORMAT;
+               /* Falls through */
        case AST_CONTROL_CONGESTION:
                if (p->priindication_oob || p->no_b_channel) {
                        /* There are many cause codes that generate an AST_CONTROL_CONGESTION. */
index b533e9e19ca58d3f0c790c587ed22669d2be8be1..3f7ea2a97cca6a977f12f1a743be158ca40abedf 100644 (file)
@@ -1569,6 +1569,14 @@ int sig_ss7_indicate(struct sig_ss7_chan *p, struct ast_channel *chan, int condi
                /* don't continue in ast_indicate */
                res = 0;
                break;
+       case AST_CONTROL_INCOMPLETE:
+               /* If the channel is connected, wait for additional input */
+               if (p->call_level == SIG_SS7_CALL_LEVEL_CONNECT) {
+                       res = 0;
+                       break;
+               }
+               chan->hangupcause = AST_CAUSE_INVALID_NUMBER_FORMAT;
+               break;
        case AST_CONTROL_CONGESTION:
                chan->hangupcause = AST_CAUSE_CONGESTION;
                break;
index 681f151fc5b37be44bb2c2a5d3d89d236f24d49c..61582a6071758b857b1f70e01e9ebe49bc879753 100644 (file)
@@ -315,6 +315,9 @@ static void print_frame(struct ast_frame *frame)
                case AST_CONTROL_MCID:
                        ast_verbose("SubClass: MCID\n");
                        break;
+               case AST_CONTROL_INCOMPLETE:
+                       ast_verbose("SubClass: INCOMPLETE\n");
+                       break;
                }
                if (frame->subclass.integer == -1) {
                        ast_verbose("SubClass: %d\n", frame->subclass.integer);
index 6e8c17779976fad4991596400cf341adacf545f9..f8cb71c6ace3432dcca9a641123afc919f83d92c 100644 (file)
@@ -263,7 +263,8 @@ enum ast_control_frame_type {
        AST_CONTROL_READ_ACTION = 27,   /*!< Tell ast_read to take a specific action */
        AST_CONTROL_AOC = 28,                   /*!< Advice of Charge with encoded generic AOC payload */
        AST_CONTROL_END_OF_Q = 29,              /*!< Indicate that this position was the end of the channel queue for a softhangup. */
-       AST_CONTROL_MCID = 30,                  /*!< Indicate that the caller is being malicious. */
+       AST_CONTROL_INCOMPLETE = 30,    /*!< Indication that the extension dialed is incomplete */
+       AST_CONTROL_MCID = 31,                  /*!< Indicate that the caller is being malicious. */
 };
 
 enum ast_frame_read_action {
index 8f4d37c8f6895ae7c47b6c8cc5802469f0406f7e..5275f9ec388627ba50faedc827a7e08be241483a 100644 (file)
@@ -4347,6 +4347,7 @@ static int attribute_const is_visible_indication(enum ast_control_frame_type con
        case AST_CONTROL_MCID:
                break;
 
+       case AST_CONTROL_INCOMPLETE:
        case AST_CONTROL_CONGESTION:
        case AST_CONTROL_BUSY:
        case AST_CONTROL_RINGING:
@@ -4503,6 +4504,7 @@ int ast_indicate_data(struct ast_channel *chan, int _condition,
        case AST_CONTROL_BUSY:
                ts = ast_get_indication_tone(chan->zone, "busy");
                break;
+       case AST_CONTROL_INCOMPLETE:
        case AST_CONTROL_CONGESTION:
                ts = ast_get_indication_tone(chan->zone, "congestion");
                break;
@@ -5538,6 +5540,12 @@ struct ast_channel *__ast_request_and_dial(const char *type, struct ast_format_c
                                        timeout = 0;
                                        break;
 
+                               case AST_CONTROL_INCOMPLETE:
+                                       ast_cdr_failed(chan->cdr);
+                                       *outstate = AST_CONTROL_CONGESTION;
+                                       timeout = 0;
+                                       break;
+
                                case AST_CONTROL_CONGESTION:
                                        ast_cdr_failed(chan->cdr);
                                        *outstate = f->subclass.integer;
index 5c30e287dc4ce44cab72dc0d822b8e998dffd1d6..6faf8f5d524e0c8a4f4076218be39258bed0109d 100644 (file)
@@ -412,6 +412,10 @@ static void handle_frame(struct ast_dial *dial, struct ast_dial_channel *channel
                        ast_hangup(channel->owner);
                        channel->owner = NULL;
                        break;
+               case AST_CONTROL_INCOMPLETE:
+                       ast_verb(3, "%s dialed Incomplete extension %s\n", channel->owner->name, channel->owner->exten);
+                       ast_indicate(chan, AST_CONTROL_INCOMPLETE);
+                       break;
                case AST_CONTROL_RINGING:
                        ast_verb(3, "%s is ringing\n", channel->owner->name);
                        if (!dial->options[AST_DIAL_OPTION_MUSIC])
index 819b67fb038e3c869c7107ed6c9162d07096fe9b..ac41a358c78bcb90e44b5db20ff66b052aa46e5c 100644 (file)
@@ -3423,6 +3423,8 @@ static struct ast_channel *feature_request_and_dial(struct ast_channel *caller,
                                        ast_indicate(caller, AST_CONTROL_BUSY);
                                        ast_frfree(f);
                                        break;
+                               } else if (f->subclass.integer == AST_CONTROL_INCOMPLETE) {
+                                       ast_verb(3, "%s dialed incomplete extension %s; ignoring\n", chan->name, chan->exten);
                                } else if (f->subclass.integer == AST_CONTROL_CONGESTION) {
                                        state = f->subclass.integer;
                                        ast_verb(3, "%s is congested\n", chan->name);
index 716c306cf9aa686a1aa7237147a2f521a427e10f..00bf1efdc2341e8e5395d3f8b7f8eccef3dc6d7b 100644 (file)
@@ -9393,6 +9393,8 @@ static int pbx_builtin_incomplete(struct ast_channel *chan, const char *data)
                __ast_answer(chan, 0, 1);
        }
 
+       ast_indicate(chan, AST_CONTROL_INCOMPLETE);
+
        return AST_PBX_INCOMPLETE;
 }