summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Jordan <mjordan@digium.com>2011-09-09 16:28:23 +0000
committerMatthew Jordan <mjordan@digium.com>2011-09-09 16:28:23 +0000
commit8b5ba33fe0e69e8d31f27139daa03e2d05d0b6d2 (patch)
tree1469d7817b6e06619d6664985947a2f8112b6df6
parent8017b65bb97c4226ca7a3c7c944a9811484e0305 (diff)
Merged revisions 335078 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/10 ................ r335078 | mjordan | 2011-09-09 11:27:01 -0500 (Fri, 09 Sep 2011) | 29 lines Merged revisions 335064 via svnmerge from 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/trunk@335079 65c4cc65-6c06-0410-ace0-fbb531ad65f3
-rw-r--r--addons/chan_ooh323.c11
-rw-r--r--apps/app_dial.c8
-rw-r--r--channels/chan_alsa.c1
-rw-r--r--channels/chan_console.c1
-rw-r--r--channels/chan_dahdi.c9
-rw-r--r--channels/chan_h323.c4
-rw-r--r--channels/chan_mgcp.c4
-rw-r--r--channels/chan_misdn.c13
-rw-r--r--channels/chan_oss.c1
-rw-r--r--channels/chan_sip.c23
-rw-r--r--channels/chan_skinny.c4
-rw-r--r--channels/chan_unistim.c4
-rw-r--r--channels/chan_usbradio.c4
-rw-r--r--channels/sig_pri.c9
-rw-r--r--channels/sig_ss7.c8
-rw-r--r--funcs/func_frame_trace.c3
-rw-r--r--include/asterisk/frame.h3
-rw-r--r--main/channel.c8
-rw-r--r--main/dial.c4
-rw-r--r--main/features.c2
-rw-r--r--main/pbx.c2
21 files changed, 110 insertions, 16 deletions
diff --git a/addons/chan_ooh323.c b/addons/chan_ooh323.c
index 1a5f1eea0..9f3f33dd0 100644
--- a/addons/chan_ooh323.c
+++ b/addons/chan_ooh323.c
@@ -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);
diff --git a/apps/app_dial.c b/apps/app_dial.c
index 515fa1b3f..c92dec263 100644
--- a/apps/app_dial.c
+++ b/apps/app_dial.c
@@ -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;
diff --git a/channels/chan_alsa.c b/channels/chan_alsa.c
index b51c942af..bd9aea599 100644
--- a/channels/chan_alsa.c
+++ b/channels/chan_alsa.c
@@ -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;
diff --git a/channels/chan_console.c b/channels/chan_console.c
index a0eddbeae..7a40f9be6 100644
--- a/channels/chan_console.c
+++ b/channels/chan_console.c
@@ -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;
diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c
index 4d5e82174..695ebf4ec 100644
--- a/channels/chan_dahdi.c
+++ b/channels/chan_dahdi.c
@@ -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;
diff --git a/channels/chan_h323.c b/channels/chan_h323.c
index e90bee18c..76fbf80e6 100644
--- a/channels/chan_h323.c
+++ b/channels/chan_h323.c
@@ -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);
diff --git a/channels/chan_mgcp.c b/channels/chan_mgcp.c
index dfd5a310f..502b929b6 100644
--- a/channels/chan_mgcp.c
+++ b/channels/chan_mgcp.c
@@ -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;
diff --git a/channels/chan_misdn.c b/channels/chan_misdn.c
index e9fa80010..79753e369 100644
--- a/channels/chan_misdn.c
+++ b/channels/chan_misdn.c
@@ -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);
diff --git a/channels/chan_oss.c b/channels/chan_oss.c
index a8ca79a3e..17894ab6f 100644
--- a/channels/chan_oss.c
+++ b/channels/chan_oss.c
@@ -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:
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 7836bd818..0300e41d9 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -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) &&
@@ -21189,6 +21203,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)
diff --git a/channels/chan_skinny.c b/channels/chan_skinny.c
index dad151ea1..523d7ffdf 100644
--- a/channels/chan_skinny.c
+++ b/channels/chan_skinny.c
@@ -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 */
diff --git a/channels/chan_unistim.c b/channels/chan_unistim.c
index 8f0cfa59e..4e3f8081f 100644
--- a/channels/chan_unistim.c
+++ b/channels/chan_unistim.c
@@ -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;
diff --git a/channels/chan_usbradio.c b/channels/chan_usbradio.c
index 62a26de7f..e3d605a3c 100644
--- a/channels/chan_usbradio.c
+++ b/channels/chan_usbradio.c
@@ -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;
diff --git a/channels/sig_pri.c b/channels/sig_pri.c
index 312737132..7db123e29 100644
--- a/channels/sig_pri.c
+++ b/channels/sig_pri.c
@@ -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. */
diff --git a/channels/sig_ss7.c b/channels/sig_ss7.c
index b533e9e19..3f7ea2a97 100644
--- a/channels/sig_ss7.c
+++ b/channels/sig_ss7.c
@@ -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;
diff --git a/funcs/func_frame_trace.c b/funcs/func_frame_trace.c
index 681f151fc..61582a607 100644
--- a/funcs/func_frame_trace.c
+++ b/funcs/func_frame_trace.c
@@ -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);
diff --git a/include/asterisk/frame.h b/include/asterisk/frame.h
index 6e8c17779..f8cb71c6a 100644
--- a/include/asterisk/frame.h
+++ b/include/asterisk/frame.h
@@ -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 {
diff --git a/main/channel.c b/main/channel.c
index 8f4d37c8f..5275f9ec3 100644
--- a/main/channel.c
+++ b/main/channel.c
@@ -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;
diff --git a/main/dial.c b/main/dial.c
index 5c30e287d..6faf8f5d5 100644
--- a/main/dial.c
+++ b/main/dial.c
@@ -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])
diff --git a/main/features.c b/main/features.c
index 819b67fb0..ac41a358c 100644
--- a/main/features.c
+++ b/main/features.c
@@ -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);
diff --git a/main/pbx.c b/main/pbx.c
index 90f6d5a89..5b33f3a72 100644
--- a/main/pbx.c
+++ b/main/pbx.c
@@ -9395,6 +9395,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;
}