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