aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoralecdavis <alecdavis@f38db490-d61c-443f-a65b-d21fe96a405b>2010-07-22 23:14:50 +0000
committeralecdavis <alecdavis@f38db490-d61c-443f-a65b-d21fe96a405b>2010-07-22 23:14:50 +0000
commitf4110f5c77863958065979fab4027770ea2990c7 (patch)
tree46a9b237320ec45b34bbc4c57965d79679fb8688
parent14194cacf54fca15caba5c92e71d0268525897d6 (diff)
Support FXS module Polarity Reversal on remote party Answer and Hangup
FXS lines normally connect to a telephone. However, when FXS lines are routed to an external PBX or Key System to act as "external" or "CO" lines, it is extremely difficult, if not impossible for the external PBX to know when the call has been disconnected without receiving a polarity reversal on the line. Now using answeronpolarityswitch and hanguponpolarityswitch keywords that previously were used only for FXO ports, now applies like functionality for an FXS port, but from the connected equipment's point of view. (closes issue #17318) Reported by: armeniki Patches: fxs_linepolarity.diff5.txt uploaded by alecdavis (license 585) Tested by: alecdavis Review: https://reviewboard.asterisk.org/r/797/ git-svn-id: http://svn.digium.com/svn/asterisk/trunk@278809 f38db490-d61c-443f-a65b-d21fe96a405b
-rw-r--r--channels/chan_dahdi.c50
-rw-r--r--channels/sig_analog.c47
-rw-r--r--channels/sig_analog.h8
-rw-r--r--configs/chan_dahdi.conf.sample18
4 files changed, 117 insertions, 6 deletions
diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c
index 85855e6a4..d2a567135 100644
--- a/channels/chan_dahdi.c
+++ b/channels/chan_dahdi.c
@@ -2737,6 +2737,52 @@ static void my_set_needringing(void *pvt, int value)
p->subs[SUB_REAL].needringing = value;
}
+static void my_set_polarity(void *pvt, int value)
+{
+ struct dahdi_pvt *p = pvt;
+
+ if (p->channel == CHAN_PSEUDO) {
+ return;
+ }
+ p->polarity = value;
+ ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETPOLARITY, &value);
+}
+
+static void my_start_polarityswitch(void *pvt)
+{
+ struct dahdi_pvt *p = pvt;
+
+ if (p->answeronpolarityswitch || p->hanguponpolarityswitch) {
+ my_set_polarity(pvt, 0);
+ }
+}
+
+static void my_answer_polarityswitch(void *pvt)
+{
+ struct dahdi_pvt *p = pvt;
+
+ if (!p->answeronpolarityswitch) {
+ return;
+ }
+
+ my_set_polarity(pvt, 1);
+}
+
+static void my_hangup_polarityswitch(void *pvt)
+{
+ struct dahdi_pvt *p = pvt;
+
+ if (!p->hanguponpolarityswitch) {
+ return;
+ }
+
+ if (p->answeronpolarityswitch) {
+ my_set_polarity(pvt, 0);
+ } else {
+ my_set_polarity(pvt, 1);
+ }
+}
+
static int my_start(void *pvt)
{
struct dahdi_pvt *p = pvt;
@@ -3454,6 +3500,10 @@ static struct analog_callback dahdi_analog_callbacks =
.set_pulsedial = my_set_pulsedial,
.get_orig_dialstring = my_get_orig_dialstring,
.set_needringing = my_set_needringing,
+ .set_polarity = my_set_polarity,
+ .start_polarityswitch = my_start_polarityswitch,
+ .answer_polarityswitch = my_answer_polarityswitch,
+ .hangup_polarityswitch = my_hangup_polarityswitch,
};
/*! Round robin search locations. */
diff --git a/channels/sig_analog.c b/channels/sig_analog.c
index 68677f561..3214681bd 100644
--- a/channels/sig_analog.c
+++ b/channels/sig_analog.c
@@ -537,6 +537,35 @@ static void analog_set_needringing(struct analog_pvt *p, int value)
}
}
+#if 0
+static void analog_set_polarity(struct analog_pvt *p, int value)
+{
+ if (p->calls->set_polarity) {
+ return p->calls->set_polarity(p->chan_pvt, value);
+ }
+}
+#endif
+
+static void analog_start_polarityswitch(struct analog_pvt *p)
+{
+ if (p->calls->start_polarityswitch) {
+ return p->calls->start_polarityswitch(p->chan_pvt);
+ }
+}
+static void analog_answer_polarityswitch(struct analog_pvt *p)
+{
+ if (p->calls->answer_polarityswitch) {
+ return p->calls->answer_polarityswitch(p->chan_pvt);
+ }
+}
+
+static void analog_hangup_polarityswitch(struct analog_pvt *p)
+{
+ if (p->calls->hangup_polarityswitch) {
+ return p->calls->hangup_polarityswitch(p->chan_pvt);
+ }
+}
+
static int analog_dsp_set_digitmode(struct analog_pvt *p, enum analog_dsp_digitmode mode)
{
if (p->calls->dsp_set_digitmode) {
@@ -1269,6 +1298,7 @@ int analog_hangup(struct analog_pvt *p, struct ast_channel *ast)
case ANALOG_SIG_FXOKS:
/* If they're off hook, try playing congestion */
if (analog_is_off_hook(p)) {
+ analog_hangup_polarityswitch(p);
analog_play_tone(p, ANALOG_SUB_REAL, ANALOG_TONE_CONGESTION);
} else {
analog_play_tone(p, ANALOG_SUB_REAL, -1);
@@ -1360,9 +1390,21 @@ int analog_answer(struct analog_pvt *p, struct ast_channel *ast)
p->owner = p->subs[ANALOG_SUB_REAL].owner;
}
}
- if ((p->sig == ANALOG_SIG_FXSLS) || (p->sig == ANALOG_SIG_FXSKS) || (p->sig == ANALOG_SIG_FXSGS)) {
+
+ switch (p->sig) {
+ case ANALOG_SIG_FXSLS:
+ case ANALOG_SIG_FXSKS:
+ case ANALOG_SIG_FXSGS:
analog_set_echocanceller(p, 1);
analog_train_echocanceller(p);
+ break;
+ case ANALOG_SIG_FXOLS:
+ case ANALOG_SIG_FXOKS:
+ case ANALOG_SIG_FXOGS:
+ analog_answer_polarityswitch(p);
+ break;
+ default:
+ break;
}
break;
default:
@@ -2524,6 +2566,7 @@ static struct ast_frame *__analog_handle_event(struct analog_pvt *p, struct ast_
case ANALOG_SIG_FXOLS:
case ANALOG_SIG_FXOGS:
case ANALOG_SIG_FXOKS:
+ analog_start_polarityswitch(p);
p->fxsoffhookstate = 0;
p->onhooktime = time(NULL);
p->msgstate = -1;
@@ -2705,6 +2748,7 @@ static struct ast_frame *__analog_handle_event(struct analog_pvt *p, struct ast_
ast_setstate(ast, AST_STATE_DIALING);
} else {
ast_setstate(ast, AST_STATE_UP);
+ analog_answer_polarityswitch(p);
}
return &p->subs[index].f;
case AST_STATE_DOWN:
@@ -3443,6 +3487,7 @@ void *analog_handle_init_event(struct analog_pvt *i, int event)
case ANALOG_SIG_FXOLS:
case ANALOG_SIG_FXOGS:
i->fxsoffhookstate = 0;
+ analog_start_polarityswitch(i);
case ANALOG_SIG_FEATD:
case ANALOG_SIG_FEATDMF:
case ANALOG_SIG_FEATDMF_TA:
diff --git a/channels/sig_analog.h b/channels/sig_analog.h
index e7f1ae2be..ff62ed52d 100644
--- a/channels/sig_analog.h
+++ b/channels/sig_analog.h
@@ -147,6 +147,14 @@ struct analog_callback {
/*! \brief Set channel off hook */
int (* const off_hook)(void *pvt);
void (* const set_needringing)(void *pvt, int value);
+ /*! \brief Set FXS line polarity to 0=IDLE NZ=REVERSED */
+ void (* const set_polarity)(void *pvt, int value);
+ /*! \brief Reset FXS line polarity to IDLE, based on answeronpolarityswitch and hanguponpolarityswitch */
+ void (* const start_polarityswitch)(void *pvt);
+ /*! \brief Switch FXS line polarity, based on answeronpolarityswitch=yes */
+ void (* const answer_polarityswitch)(void *pvt);
+ /*! \brief Switch FXS line polarity, based on answeronpolarityswitch and hanguponpolarityswitch */
+ void (* const hangup_polarityswitch)(void *pvt);
/* We're assuming that we're going to only wink on ANALOG_SUB_REAL - even though in the code there's an argument to the index
* function */
int (* const wink)(void *pvt, enum analog_sub sub);
diff --git a/configs/chan_dahdi.conf.sample b/configs/chan_dahdi.conf.sample
index 0bc4ac82e..56794320f 100644
--- a/configs/chan_dahdi.conf.sample
+++ b/configs/chan_dahdi.conf.sample
@@ -820,14 +820,22 @@ pickupgroup=1
; useful to use the ztmonitor utility to record the audio that main/dsp.c
; is receiving after the caller hangs up.
;
-; Use a polarity reversal to mark when a outgoing call is answered by the
-; remote party.
+; For FXS (FXO signalled) ports
+; switch the line polarity to signal the connected PBX that an outgoing
+; call was answered by the remote party.
+; For FXO (FXS signalled) ports
+; watch for a polarity reversal to mark when a outgoing call is
+; answered by the remote party.
;
;answeronpolarityswitch=yes
;
-; In some countries, a polarity reversal is used to signal the disconnect of a
-; phone line. If the hanguponpolarityswitch option is selected, the call will
-; be considered "hung up" on a polarity reversal.
+; For FXS (FXO signalled) ports
+; switch the line polarity to signal the connected PBX that the current
+; call was "hung up" by the remote party
+; For FXO (FXS signalled) ports
+; In some countries, a polarity reversal is used to signal the disconnect of a
+; phone line. If the hanguponpolarityswitch option is selected, the call will
+; be considered "hung up" on a polarity reversal.
;
;hanguponpolarityswitch=yes
;