aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrmudgett <rmudgett@f38db490-d61c-443f-a65b-d21fe96a405b>2009-04-27 20:03:49 +0000
committerrmudgett <rmudgett@f38db490-d61c-443f-a65b-d21fe96a405b>2009-04-27 20:03:49 +0000
commit36963c1bce21d26343ac222911d8528dfe4f8e69 (patch)
treed2139a84e6f6ca8924f8827177c295366227c906
parent3cc822709b22c4011802ffd8b9fb12ea79659d6b (diff)
Make PTP DivertingLegInformation3 message behavior closer to the specifications.
* Wait for a DivertingLegInformation3 message after receiving a DivertingLegInformation1 message to complete the redirecting-to information before queuing a redirecting update to the other channel. * A DivertingLegInformation2 message should be responded to with a DivertingLegInformation3 when the COLR is determined. If the call could or does experience another redirection, you should manually determine the COLR to send to the switch by setting REDIRECTING(to-pres) to the COLR and setting REDIRECTING(to-num) = ${EXTEN}. * A DivertingLegInformation2 message must have an original called number if the redirection count is greater than one. Since Asterisk does not keep track of this information, we can only indicate that the number is not available due to interworking. git-svn-id: http://svn.digium.com/svn/asterisk/trunk@190735 f38db490-d61c-443f-a65b-d21fe96a405b
-rw-r--r--CHANGES5
-rw-r--r--channels/chan_misdn.c113
-rw-r--r--channels/misdn/isdn_lib.c5
-rw-r--r--channels/misdn/isdn_lib.h12
-rw-r--r--funcs/func_redirecting.c12
5 files changed, 125 insertions, 22 deletions
diff --git a/CHANGES b/CHANGES
index 2c70d615f..bb9239e8b 100644
--- a/CHANGES
+++ b/CHANGES
@@ -72,6 +72,11 @@ mISDN channel driver (chan_misdn) changes
the CCBS/CCNR functionality.
* Added new dialplan function mISDN_CC which permits retrieval of various
values from an active call completion record.
+ * For PTP, you should manually send the COLR for an incomming redirected
+ call if the incoming call could or does experience further redirects.
+ Just set the REDIRECTING(to-num,i) = ${EXTEN} and set the
+ REDIRECTING(to-pres) to the COLR. A call has been redirected if the
+ REDIRECTING(from-num) is not empty.
thirdparty mISDN enhancements
-----------------------------
diff --git a/channels/chan_misdn.c b/channels/chan_misdn.c
index f743ec8d1..63b3271fc 100644
--- a/channels/chan_misdn.c
+++ b/channels/chan_misdn.c
@@ -316,7 +316,9 @@ enum misdn_chan_state {
MISDN_HOLD_DISCONNECT, /*!< when on hold */
};
+/*! Asterisk created the channel (outgoing call) */
#define ORG_AST 1
+/*! mISDN created the channel (incoming call) */
#define ORG_MISDN 2
struct hold_info {
@@ -6155,33 +6157,45 @@ static void misdn_copy_redirecting_to_ast(struct ast_channel *ast, const struct
*
* \param ast Current Asterisk channel
* \param bc Associated B channel
+ * \param originator Who originally created this channel. ORG_AST or ORG_MISDN
*
* \return Nothing
*/
-static void misdn_update_redirecting(struct ast_channel *ast, struct misdn_bchannel *bc)
+static void misdn_update_redirecting(struct ast_channel *ast, struct misdn_bchannel *bc, int originator)
{
- int Is_PTMP;
+ int is_ptmp;
misdn_copy_redirecting_from_ast(bc, ast);
- Is_PTMP = !misdn_lib_is_ptp(bc->port);
- if (Is_PTMP) {
+ if (originator != ORG_MISDN) {
+ return;
+ }
+
+ is_ptmp = !misdn_lib_is_ptp(bc->port);
+ if (is_ptmp) {
/* Send NOTIFY(call-is-diverting, redirecting.to data) */
bc->redirecting.to_changed = 1;
bc->notify_description_code = mISDN_NOTIFY_CODE_CALL_IS_DIVERTING;
misdn_lib_send_event(bc, EVENT_NOTIFY);
#if defined(AST_MISDN_ENHANCEMENTS)
} else {
- /* Send DivertingLegInformation1 */
- bc->fac_out.Function = Fac_DivertingLegInformation1;
- bc->fac_out.u.DivertingLegInformation1.InvokeID = ++misdn_invoke_id;
- bc->fac_out.u.DivertingLegInformation1.DiversionReason =
- misdn_to_diversion_reason(bc->redirecting.reason);
- bc->fac_out.u.DivertingLegInformation1.SubscriptionOption = 2;/* notificationWithDivertedToNr */
- bc->fac_out.u.DivertingLegInformation1.DivertedToPresent = 1;
- misdn_PresentedNumberUnscreened_fill(&bc->fac_out.u.DivertingLegInformation1.DivertedTo, &bc->redirecting.to);
- print_facility(&bc->fac_out, bc);
- misdn_lib_send_event(bc, EVENT_FACILITY);
+ int match; /* TRUE if the dialed number matches the redirecting to number */
+
+ match = (strcmp(ast->exten, bc->redirecting.to.number) == 0) ? 1 : 0;
+ if (!bc->div_leg_3_tx_pending
+ || !match) {
+ /* Send DivertingLegInformation1 */
+ bc->fac_out.Function = Fac_DivertingLegInformation1;
+ bc->fac_out.u.DivertingLegInformation1.InvokeID = ++misdn_invoke_id;
+ bc->fac_out.u.DivertingLegInformation1.DiversionReason =
+ misdn_to_diversion_reason(bc->redirecting.reason);
+ bc->fac_out.u.DivertingLegInformation1.SubscriptionOption = 2;/* notificationWithDivertedToNr */
+ bc->fac_out.u.DivertingLegInformation1.DivertedToPresent = 1;
+ misdn_PresentedNumberUnscreened_fill(&bc->fac_out.u.DivertingLegInformation1.DivertedTo, &bc->redirecting.to);
+ print_facility(&bc->fac_out, bc);
+ misdn_lib_send_event(bc, EVENT_FACILITY);
+ }
+ bc->div_leg_3_tx_pending = 0;
/* Send DivertingLegInformation3 */
bc->fac_out.Function = Fac_DivertingLegInformation3;
@@ -6368,6 +6382,10 @@ static int misdn_call(struct ast_channel *ast, char *dest, int timeout)
&newbc->fac_out.u.DivertingLegInformation2.Diverting,
&newbc->redirecting.from);
newbc->fac_out.u.DivertingLegInformation2.OriginalCalledPresent = 0;
+ if (1 < newbc->redirecting.count) {
+ newbc->fac_out.u.DivertingLegInformation2.OriginalCalledPresent = 1;
+ newbc->fac_out.u.DivertingLegInformation2.OriginalCalled.Type = 2;/* numberNotAvailableDueToInterworking */
+ }
}
#endif /* defined(AST_MISDN_ENHANCEMENTS) */
@@ -6488,6 +6506,18 @@ static int misdn_answer(struct ast_channel *ast)
p->bc->connected.number_plan = p->bc->dialed.number_plan;
}
+#if defined(AST_MISDN_ENHANCEMENTS)
+ if (p->bc->div_leg_3_tx_pending) {
+ p->bc->div_leg_3_tx_pending = 0;
+
+ /* Send DivertingLegInformation3 */
+ p->bc->fac_out.Function = Fac_DivertingLegInformation3;
+ p->bc->fac_out.u.DivertingLegInformation3.InvokeID = ++misdn_invoke_id;
+ p->bc->fac_out.u.DivertingLegInformation3.PresentationAllowedIndicator =
+ (p->bc->connected.presentation == 0) ? 1 : 0;
+ print_facility(&p->bc->fac_out, p->bc);
+ }
+#endif /* defined(AST_MISDN_ENHANCEMENTS) */
misdn_lib_send_event(p->bc, EVENT_CONNECT);
start_bc_tones(p);
@@ -6690,7 +6720,7 @@ static int misdn_indication(struct ast_channel *ast, int cond, const void *data,
break;
case AST_CONTROL_REDIRECTING:
chan_misdn_log(1, p->bc->port, "* IND :\tredirecting info update pid:%d\n", p->bc->pid);
- misdn_update_redirecting(ast, p->bc);
+ misdn_update_redirecting(ast, p->bc, p->originator);
break;
default:
chan_misdn_log(1, p->bc->port, " --> * Unknown Indication:%d pid:%d\n", cond, p->bc->pid);
@@ -8608,6 +8638,7 @@ static void misdn_facility_ie_handler(enum event_e event, struct misdn_bchannel
#endif /* We don't handle this yet */
case Fac_DivertingLegInformation1:
/* Private-Public ISDN interworking message */
+ bc->div_leg_3_rx_wanted = 0;
if (ch && ch->ast) {
bc->redirecting.reason =
diversion_reason_to_misdn(bc->fac_in.u.DivertingLegInformation1.DiversionReason);
@@ -8618,12 +8649,15 @@ static void misdn_facility_ie_handler(enum event_e event, struct misdn_bchannel
/* Add configured prefix to redirecting.to.number */
misdn_add_number_prefix(bc->port, bc->redirecting.to.number_type,
bc->redirecting.to.number, sizeof(bc->redirecting.to.number));
-
- misdn_copy_redirecting_to_ast(ch->ast, &bc->redirecting);
- ast_channel_queue_redirecting_update(ch->ast, &ch->ast->redirecting);
} else {
- ch->ast->redirecting.reason = misdn_to_ast_reason(bc->redirecting.reason);
+ bc->redirecting.to.number[0] = '\0';
+ bc->redirecting.to.number_plan = NUMPLAN_ISDN;
+ bc->redirecting.to.number_type = NUMTYPE_UNKNOWN;
+ bc->redirecting.to.presentation = 1;/* restricted */
+ bc->redirecting.to.screening = 0;/* unscreened */
}
+ misdn_copy_redirecting_to_ast(ch->ast, &bc->redirecting);
+ bc->div_leg_3_rx_wanted = 1;
}
break;
case Fac_DivertingLegInformation2:
@@ -8631,7 +8665,25 @@ static void misdn_facility_ie_handler(enum event_e event, struct misdn_bchannel
switch (event) {
case EVENT_SETUP:
/* Comes in on a SETUP with redirecting.from information */
+ bc->div_leg_3_tx_pending = 1;
if (ch && ch->ast) {
+ /*
+ * Setup the redirecting.to informtion so we can identify
+ * if the user wants to manually supply the COLR for this
+ * redirected to number if further redirects could happen.
+ *
+ * All the user needs to do is set the REDIRECTING(to-pres)
+ * to the COLR and REDIRECTING(to-num) = ${EXTEN} to be safe
+ * after determining that the incoming call was redirected by
+ * checking if there is a REDIRECTING(from-num).
+ */
+ ast_copy_string(bc->redirecting.to.number, bc->dialed.number,
+ sizeof(bc->redirecting.to.number));
+ bc->redirecting.to.number_plan = bc->dialed.number_plan;
+ bc->redirecting.to.number_type = bc->dialed.number_type;
+ bc->redirecting.to.presentation = 1;/* restricted */
+ bc->redirecting.to.screening = 0;/* unscreened */
+
bc->redirecting.reason =
diversion_reason_to_misdn(bc->fac_in.u.DivertingLegInformation2.DiversionReason);
bc->redirecting.count = bc->fac_in.u.DivertingLegInformation2.DiversionCounter;
@@ -8660,7 +8712,17 @@ static void misdn_facility_ie_handler(enum event_e event, struct misdn_bchannel
break;
case Fac_DivertingLegInformation3:
/* Private-Public ISDN interworking message */
- /* Don't know what to do with this. */
+ if (bc->div_leg_3_rx_wanted) {
+ bc->div_leg_3_rx_wanted = 0;
+
+ if (ch && ch->ast) {
+ ch->ast->redirecting.to.number_presentation =
+ bc->fac_in.u.DivertingLegInformation3.PresentationAllowedIndicator
+ ? AST_PRES_ALLOWED | AST_PRES_USER_NUMBER_UNSCREENED
+ : AST_PRES_RESTRICTED | AST_PRES_USER_NUMBER_UNSCREENED;
+ ast_channel_queue_redirecting_update(ch->ast, &ch->ast->redirecting);
+ }
+ }
break;
#else /* !defined(AST_MISDN_ENHANCEMENTS) */
@@ -9786,6 +9848,17 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
if (bc->fac_in.Function != Fac_None) {
misdn_facility_ie_handler(event, bc, ch);
}
+#if defined(AST_MISDN_ENHANCEMENTS)
+ if (bc->div_leg_3_rx_wanted) {
+ bc->div_leg_3_rx_wanted = 0;
+
+ if (ch->ast) {
+ ch->ast->redirecting.to.number_presentation =
+ AST_PRES_RESTRICTED | AST_PRES_USER_NUMBER_UNSCREENED;
+ ast_channel_queue_redirecting_update(ch->ast, &ch->ast->redirecting);
+ }
+ }
+#endif /* defined(AST_MISDN_ENHANCEMENTS) */
/* we answer when we've got our very new L3 ID from the NT stack */
misdn_lib_send_event(bc, EVENT_CONNECT_ACKNOWLEDGE);
diff --git a/channels/misdn/isdn_lib.c b/channels/misdn/isdn_lib.c
index 4a0da06d3..c0a4170e2 100644
--- a/channels/misdn/isdn_lib.c
+++ b/channels/misdn/isdn_lib.c
@@ -764,6 +764,11 @@ static void empty_bc(struct misdn_bchannel *bc)
bc->progress_location=0;
bc->progress_indicator=0;
+#if defined(AST_MISDN_ENHANCEMENTS)
+ bc->div_leg_3_rx_wanted = 0;
+ bc->div_leg_3_tx_pending = 0;
+#endif /* defined(AST_MISDN_ENHANCEMENTS) */
+
/** Set Default Bearer Caps **/
bc->capability=INFO_CAPABILITY_SPEECH;
bc->law=INFO_CODEC_ALAW;
diff --git a/channels/misdn/isdn_lib.h b/channels/misdn/isdn_lib.h
index 7bd516565..df11659c3 100644
--- a/channels/misdn/isdn_lib.h
+++ b/channels/misdn/isdn_lib.h
@@ -493,6 +493,18 @@ struct misdn_bchannel {
*/
int progress_indicator;
+#if defined(AST_MISDN_ENHANCEMENTS)
+ /*!
+ * \brief TRUE if waiting for DivertingLegInformation3 to queue redirecting update.
+ */
+ int div_leg_3_rx_wanted;
+
+ /*!
+ * \brief TRUE if a DivertingLegInformation3 needs to be sent with CONNECT.
+ */
+ int div_leg_3_tx_pending;
+#endif /* defined(AST_MISDN_ENHANCEMENTS) */
+
/*! \brief Inbound FACILITY message function type and contents */
struct FacParm fac_in;
diff --git a/funcs/func_redirecting.c b/funcs/func_redirecting.c
index 4a2d7be26..62c6d7bc9 100644
--- a/funcs/func_redirecting.c
+++ b/funcs/func_redirecting.c
@@ -49,6 +49,13 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/options.h"
#include "asterisk/callerid.h"
+/*
+ * Do not document the REDIRECTING(pres) datatype.
+ * It has turned out that the from-pres and to-pres values must be kept
+ * separate. They represent two different parties and there is a case when
+ * they are active at the same time. The plain pres option will simply
+ * live on as a historical relic.
+ */
/*** DOCUMENTATION
<function name="REDIRECTING" language="en_US">
<synopsis>
@@ -62,11 +69,12 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
<enum name = "from-num" />
<enum name = "from-name" />
<enum name = "from-ton" />
+ <enum name = "from-pres" />
<enum name = "to-all" />
<enum name = "to-num" />
<enum name = "to-name" />
<enum name = "to-ton" />
- <enum name = "pres" />
+ <enum name = "to-pres" />
<enum name = "reason" />
<enum name = "count" />
</enumlist>
@@ -323,7 +331,7 @@ static int redirecting_write(struct ast_channel *chan, const char *cmd, char *da
case 'i':
set_it = ast_channel_set_redirecting;
break;
-
+
default:
ast_log(LOG_ERROR, "Unknown redirecting option '%s'.\n", option);
return 0;