dect
/
asterisk
Archived
13
0
Fork 0

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
This commit is contained in:
rmudgett 2009-04-27 20:03:49 +00:00
parent 3cc822709b
commit 36963c1bce
5 changed files with 125 additions and 22 deletions

View File

@ -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
-----------------------------

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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;