summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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;
}