[asterisk-commits] rmudgett: branch rmudgett/dahdi_deflection r223051 - /team/rmudgett/dahdi_def...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Thu Oct 8 19:26:26 CDT 2009
Author: rmudgett
Date: Thu Oct 8 19:26:22 2009
New Revision: 223051
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=223051
Log:
Initial call deflection/rerouting support.
Modified:
team/rmudgett/dahdi_deflection/channels/sig_pri.c
team/rmudgett/dahdi_deflection/channels/sig_pri.h
Modified: team/rmudgett/dahdi_deflection/channels/sig_pri.c
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/dahdi_deflection/channels/sig_pri.c?view=diff&rev=223051&r1=223050&r2=223051
==============================================================================
--- team/rmudgett/dahdi_deflection/channels/sig_pri.c (original)
+++ team/rmudgett/dahdi_deflection/channels/sig_pri.c Thu Oct 8 19:26:22 2009
@@ -1144,6 +1144,68 @@
/*!
* \internal
+ * \brief Convert libpri redirecting information into asterisk redirecting information.
+ * \since 1.6.4
+ *
+ * \param ast_redirecting Asterisk redirecting structure to fill.
+ * \param pri_redirecting libpri redirecting structure containing source information.
+ * \param ast_guide Asterisk redirecting structure to use as an initialization guide.
+ * \param pri Span controlling structure.
+ * \param from_number Scratch buffer to hold converted from number.
+ * \param to_number Scratch buffer to hold converted to number.
+ * \param number_buf_size Size of the scratch buffers.
+ *
+ * \return Nothing
+ */
+static void sig_pri_redirecting_convert(struct ast_party_redirecting *ast_redirecting,
+ const struct pri_party_redirecting *pri_redirecting,
+ const struct ast_party_redirecting *ast_guide,
+ struct sig_pri_pri *pri,
+ char *from_number,
+ char *to_number,
+ size_t number_buf_size)
+{
+ ast_party_redirecting_set_init(ast_redirecting, ast_guide);
+
+ /* ast_redirecting->from */
+ if (pri_redirecting->from.name.valid) {
+ ast_redirecting->from.name = (char *) pri_redirecting->from.name.str;
+ }
+ if (pri_redirecting->from.number.valid) {
+ apply_plan_to_number(from_number, number_buf_size, pri,
+ pri_redirecting->from.number.str,
+ pri_redirecting->from.number.plan);
+ ast_redirecting->from.number = from_number;
+ ast_redirecting->from.number_type = pri_redirecting->from.number.plan;
+ }
+ if (pri_redirecting->from.name.valid
+ || pri_redirecting->from.number.valid) {
+ ast_redirecting->from.number_presentation =
+ overall_ast_presentation(&pri_redirecting->from);
+ }
+
+ /* ast_redirecting->to */
+ if (pri_redirecting->to.name.valid) {
+ ast_redirecting->to.name = (char *) pri_redirecting->to.name.str;
+ }
+ if (pri_redirecting->to.number.valid) {
+ apply_plan_to_number(to_number, number_buf_size, pri,
+ pri_redirecting->to.number.str, pri_redirecting->to.number.plan);
+ ast_redirecting->to.number = to_number;
+ ast_redirecting->to.number_type = pri_redirecting->to.number.plan;
+ }
+ if (pri_redirecting->to.name.valid
+ || pri_redirecting->to.number.valid) {
+ ast_redirecting->to.number_presentation =
+ overall_ast_presentation(&pri_redirecting->from);
+ }
+
+ ast_redirecting->count = pri_redirecting->count;
+ ast_redirecting->reason = pri_to_ast_reason(pri_redirecting->reason);
+}
+
+/*!
+ * \internal
* \brief Determine if the given extension matches one of the MSNs in the pattern list.
* \since 1.6.3
*
@@ -1216,6 +1278,10 @@
* \param event_id PRI event id
* \param channel PRI encoded span/channel
* \param subcmds Subcommands to process if any. (Could be NULL).
+ * \param call_rsp libpri opaque call structure to send any responses toward.
+ * Could be NULL either because it is not available or the call is for the
+ * dummy call reference. However, this should not be NULL in the cases that
+ * need to use the pointer to send a response message back.
*
* \note Assumes the pri->lock is already obtained.
* \note Assumes the sig_pri_lock_private(pri->pvts[chanpos]) is already obtained.
@@ -1223,10 +1289,13 @@
* \return Nothing
*/
static void sig_pri_handle_subcmds(struct sig_pri_pri *pri, int chanpos, int event_id,
- int channel, const struct pri_subcommands *subcmds)
+ int channel, const struct pri_subcommands *subcmds, q931_call *call_rsp)
{
int index;
struct ast_channel *owner;
+ struct ast_party_redirecting ast_redirecting;
+ char from_number[AST_MAX_EXTENSION];
+ char to_number[AST_MAX_EXTENSION];
if (!subcmds) {
return;
@@ -1302,50 +1371,9 @@
sig_pri_lock_owner(pri, chanpos);
owner = pri->pvts[chanpos]->owner;
if (owner) {
- struct ast_party_redirecting ast_redirecting;
- const struct pri_party_redirecting *pri_redirecting;
- char from_number[AST_MAX_EXTENSION];
- char to_number[AST_MAX_EXTENSION];
-
- ast_party_redirecting_set_init(&ast_redirecting, &owner->redirecting);
-
- pri_redirecting = &subcmd->u.redirecting;
-
- /* ast_redirecting.from */
- if (pri_redirecting->from.name.valid) {
- ast_redirecting.from.name = (char *) pri_redirecting->from.name.str;
- }
- if (pri_redirecting->from.number.valid) {
- apply_plan_to_number(from_number, sizeof(from_number), pri,
- pri_redirecting->from.number.str,
- pri_redirecting->from.number.plan);
- ast_redirecting.from.number = from_number;
- ast_redirecting.from.number_type = pri_redirecting->from.number.plan;
- }
- if (pri_redirecting->from.name.valid
- || pri_redirecting->from.number.valid) {
- ast_redirecting.from.number_presentation =
- overall_ast_presentation(&pri_redirecting->from);
- }
-
- /* ast_redirecting.to */
- if (pri_redirecting->to.name.valid) {
- ast_redirecting.to.name = (char *) pri_redirecting->to.name.str;
- }
- if (pri_redirecting->to.number.valid) {
- apply_plan_to_number(to_number, sizeof(to_number), pri,
- pri_redirecting->to.number.str, pri_redirecting->to.number.plan);
- ast_redirecting.to.number = to_number;
- ast_redirecting.to.number_type = pri_redirecting->to.number.plan;
- }
- if (pri_redirecting->to.name.valid
- || pri_redirecting->to.number.valid) {
- ast_redirecting.to.number_presentation =
- overall_ast_presentation(&pri_redirecting->from);
- }
-
- ast_redirecting.count = pri_redirecting->count;
- ast_redirecting.reason = pri_to_ast_reason(pri_redirecting->reason);
+ sig_pri_redirecting_convert(&ast_redirecting, &subcmd->u.redirecting,
+ &owner->redirecting, pri, from_number, to_number,
+ sizeof(from_number));
/*! \todo XXX Original called data can be put in a channel data store that is inherited. */
@@ -1358,6 +1386,63 @@
ast_channel_unlock(owner);
}
break;
+#if defined(HAVE_PRI_CALL_REROUTING)
+ case PRI_SUBCMD_REROUTING:
+ sig_pri_lock_owner(pri, chanpos);
+ owner = pri->pvts[chanpos]->owner;
+ if (owner) {
+ struct pri_party_redirecting pri_deflection;
+
+ if (!call_rsp) {
+ ast_channel_unlock(owner);
+ ast_log(LOG_WARNING,
+ "CallRerouting/CallDeflection to '%s' without call!\n",
+ subcmd->u.rerouting.deflection.to.number.str);
+ break;
+ }
+
+ pri_deflection = subcmd->u.rerouting.deflection;
+
+ ast_string_field_set(owner, call_forward, pri_deflection.to.number.str);
+
+ /* Adjust the deflecting to number based upon the subscription option. */
+ switch (subcmd->u.rerouting.subscription_option) {
+ case 0: /* noNotification */
+ case 1: /* notificationWithoutDivertedToNr */
+ /* Delete the number because the far end is not supposed to see it. */
+ pri_deflection.to.number.presentation =
+ PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED;
+ pri_deflection.to.number.plan =
+ (PRI_TON_UNKNOWN << 4) | PRI_NPI_E163_E164;
+ pri_deflection.to.number.str[0] = '\0';
+ break;
+ case 2: /* notificationWithDivertedToNr */
+ break;
+ case 3: /* notApplicable */
+ default:
+ break;
+ }
+ sig_pri_redirecting_convert(&ast_redirecting, &pri_deflection,
+ &owner->redirecting, pri, from_number, to_number,
+ sizeof(from_number));
+ ast_channel_set_redirecting(owner, &ast_redirecting);
+
+ /*
+ * Send back positive ACK to CallRerouting/CallDeflection.
+ *
+ * Note: This call will be hungup by the dial application when
+ * it processes the call_forward string set above.
+ */
+ pri_rerouting_rsp(pri->pri, call_rsp, subcmd->u.rerouting.invoke_id,
+ PRI_REROUTING_RSP_OK_CLEAR);
+
+ /* This line is BUSY to further attempts by this dialing attempt. */
+ ast_queue_control(owner, AST_CONTROL_BUSY);
+
+ ast_channel_unlock(owner);
+ }
+ break;
+#endif /* defined(HAVE_PRI_CALL_REROUTING) */
default:
ast_debug(2,
"Unknown call subcommand(%d) in %s event on channel %d/%d on span %d.\n",
@@ -1493,7 +1578,8 @@
retval = -1;
goto done_with_owner;
}
- sig_pri_handle_subcmds(pri, chanpos_old, ev->e, ev->hold.channel, ev->hold.subcmds);
+ sig_pri_handle_subcmds(pri, chanpos_old, ev->e, ev->hold.channel, ev->hold.subcmds,
+ ev->hold.call);
chanpos_new = pri_fixup_principle(pri, chanpos_new, ev->hold.call);
if (chanpos_new < 0) {
/* Should never happen. */
@@ -1568,7 +1654,7 @@
}
sig_pri_lock_private(pri->pvts[chanpos]);
sig_pri_handle_subcmds(pri, chanpos, ev->e, ev->retrieve.channel,
- ev->retrieve.subcmds);
+ ev->retrieve.subcmds, ev->retrieve.call);
{
struct ast_frame f = { AST_FRAME_CONTROL, };
@@ -1906,7 +1992,7 @@
if (chanpos > -1) {
sig_pri_lock_private(pri->pvts[chanpos]);
sig_pri_handle_subcmds(pri, chanpos, e->e, e->digit.channel,
- e->digit.subcmds);
+ e->digit.subcmds, e->digit.call);
/* queue DTMF frame if the PBX for this call was already started (we're forwarding KEYPAD_DIGITs further on */
if ((pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)
&& pri->pvts[chanpos]->call == e->digit.call
@@ -1936,7 +2022,7 @@
if (chanpos > -1) {
sig_pri_lock_private(pri->pvts[chanpos]);
sig_pri_handle_subcmds(pri, chanpos, e->e, e->ring.channel,
- e->ring.subcmds);
+ e->ring.subcmds, e->ring.call);
/* queue DTMF frame if the PBX for this call was already started (we're forwarding INFORMATION further on */
if ((pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)
&& pri->pvts[chanpos]->call == e->ring.call
@@ -2168,7 +2254,7 @@
#endif
sig_pri_handle_subcmds(pri, chanpos, e->e, e->ring.channel,
- e->ring.subcmds);
+ e->ring.subcmds, e->ring.call);
}
if (c && !ast_pthread_create_detached(&threadid, NULL, pri_ss_thread, pri->pvts[chanpos])) {
ast_verb(3, "Accepting overlap call from '%s' to '%s' on channel %d/%d, span %d\n",
@@ -2231,7 +2317,7 @@
pbx_builtin_setvar_helper(c, "CALLEDTON", calledtonstr);
sig_pri_handle_subcmds(pri, chanpos, e->e, e->ring.channel,
- e->ring.subcmds);
+ e->ring.subcmds, e->ring.call);
}
if (c && !ast_pbx_start(c)) {
ast_verb(3, "Accepting call from '%s' to '%s' on channel %d/%d, span %d\n",
@@ -2279,7 +2365,7 @@
sig_pri_lock_private(pri->pvts[chanpos]);
sig_pri_handle_subcmds(pri, chanpos, e->e, e->ringing.channel,
- e->ringing.subcmds);
+ e->ringing.subcmds, e->ringing.call);
sig_pri_set_echocanceller(pri->pvts[chanpos], 1);
pri_queue_control(pri->pvts[chanpos], AST_CONTROL_RINGING, pri);
pri->pvts[chanpos]->alerting = 1;
@@ -2308,7 +2394,7 @@
if (chanpos > -1) {
sig_pri_lock_private(pri->pvts[chanpos]);
sig_pri_handle_subcmds(pri, chanpos, e->e, e->proceeding.channel,
- e->proceeding.subcmds);
+ e->proceeding.subcmds, e->proceeding.call);
if ((!pri->pvts[chanpos]->progress)
#ifdef PRI_PROGRESS_MASK
|| (e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE)
@@ -2357,7 +2443,7 @@
if (chanpos > -1) {
sig_pri_lock_private(pri->pvts[chanpos]);
sig_pri_handle_subcmds(pri, chanpos, e->e, e->proceeding.channel,
- e->proceeding.subcmds);
+ e->proceeding.subcmds, e->proceeding.call);
if (!pri->pvts[chanpos]->proceeding) {
struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_PROCEEDING, };
@@ -2393,8 +2479,13 @@
PRI_SPAN(e->facility.channel), PRI_CHANNEL(e->facility.channel), pri->span);
} else {
sig_pri_lock_private(pri->pvts[chanpos]);
+#if defined(HAVE_PRI_CALL_REROUTING)
sig_pri_handle_subcmds(pri, chanpos, e->e, e->facility.channel,
- e->facility.subcmds);
+ e->facility.subcmds, e->facility.subcall);
+#else
+ sig_pri_handle_subcmds(pri, chanpos, e->e, e->facility.channel,
+ e->facility.subcmds, e->facility.call);
+#endif /* defined(HAVE_PRI_CALL_REROUTING) */
sig_pri_unlock_private(pri->pvts[chanpos]);
}
}
@@ -2413,7 +2504,7 @@
sig_pri_lock_private(pri->pvts[chanpos]);
sig_pri_handle_subcmds(pri, chanpos, e->e, e->answer.channel,
- e->answer.subcmds);
+ e->answer.subcmds, e->answer.call);
pri_queue_control(pri->pvts[chanpos], AST_CONTROL_ANSWER, pri);
/* Enable echo cancellation if it's not on already */
sig_pri_set_dialing(pri->pvts[chanpos], 0);
@@ -2447,7 +2538,7 @@
if (chanpos > -1) {
sig_pri_lock_private(pri->pvts[chanpos]);
sig_pri_handle_subcmds(pri, chanpos, e->e, e->hangup.channel,
- e->hangup.subcmds);
+ e->hangup.subcmds, e->hangup.call);
if (!pri->pvts[chanpos]->alreadyhungup) {
/* we're calling here dahdi_hangup so once we get there we need to clear p->call after calling pri_hangup */
pri->pvts[chanpos]->alreadyhungup = 1;
@@ -2522,7 +2613,7 @@
if (chanpos > -1) {
sig_pri_lock_private(pri->pvts[chanpos]);
sig_pri_handle_subcmds(pri, chanpos, e->e, e->hangup.channel,
- e->hangup.subcmds);
+ e->hangup.subcmds, e->hangup.call);
#if defined(HAVE_PRI_CALL_HOLD)
if (e->hangup.call_active && e->hangup.call_held
&& pri->hold_disconnect_transfer) {
@@ -2685,7 +2776,7 @@
if (chanpos > -1) {
sig_pri_lock_private(pri->pvts[chanpos]);
sig_pri_handle_subcmds(pri, chanpos, e->e, e->setup_ack.channel,
- e->setup_ack.subcmds);
+ e->setup_ack.subcmds, e->setup_ack.call);
pri->pvts[chanpos]->setup_ack = 1;
/* Send any queued digits */
for (x = 0;x < strlen(pri->pvts[chanpos]->dialdest); x++) {
@@ -2709,8 +2800,13 @@
PRI_SPAN(e->notify.channel), PRI_CHANNEL(e->notify.channel), pri->span);
} else {
sig_pri_lock_private(pri->pvts[chanpos]);
+#if defined(HAVE_PRI_CALL_HOLD)
sig_pri_handle_subcmds(pri, chanpos, e->e, e->notify.channel,
- e->notify.subcmds);
+ e->notify.subcmds, e->notify.call);
+#else
+ sig_pri_handle_subcmds(pri, chanpos, e->e, e->notify.channel,
+ e->notify.subcmds, NULL);
+#endif /* !defined(HAVE_PRI_CALL_HOLD) */
switch (e->notify.info) {
case PRI_NOTIFY_REMOTE_HOLD:
if (!pri->discardremoteholdretrieval) {
@@ -3384,6 +3480,9 @@
#if defined(HAVE_PRI_CALL_HOLD)
pri_hold_enable(pri->dchans[i], 1);
#endif /* defined(HAVE_PRI_CALL_HOLD) */
+#if defined(HAVE_PRI_CALL_REROUTING)
+ pri_reroute_enable(pri->dchans[i], 1);
+#endif /* defined(HAVE_PRI_CALL_REROUTING) */
/* Enslave to master if appropriate */
if (i)
pri_enslave(pri->dchans[0], pri->dchans[i]);
Modified: team/rmudgett/dahdi_deflection/channels/sig_pri.h
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/dahdi_deflection/channels/sig_pri.h?view=diff&rev=223051&r1=223050&r2=223051
==============================================================================
--- team/rmudgett/dahdi_deflection/channels/sig_pri.h (original)
+++ team/rmudgett/dahdi_deflection/channels/sig_pri.h Thu Oct 8 19:26:22 2009
@@ -30,6 +30,7 @@
#include <libpri.h>
#include <dahdi/user.h>
#define HAVE_PRI_CALL_HOLD 1 /* BUGBUG remove this line and put test in configure.ac */
+#define HAVE_PRI_CALL_REROUTING 1 /* BUGBUG remove this line and put test in configure.ac */
enum sig_pri_tone {
SIG_PRI_TONE_RINGTONE = 0,
More information about the asterisk-commits
mailing list