Index: channels/chan_dahdi.c =================================================================== --- channels/chan_dahdi.c (revision 278424) +++ channels/chan_dahdi.c (working copy) @@ -2744,6 +2744,52 @@ 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; @@ -3461,6 +3507,10 @@ .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. */ Index: channels/sig_analog.c =================================================================== --- channels/sig_analog.c (revision 278424) +++ channels/sig_analog.c (working copy) @@ -530,6 +530,35 @@ } } +#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) { @@ -1266,6 +1295,7 @@ 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); @@ -1357,9 +1387,21 @@ 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: @@ -2521,6 +2563,7 @@ 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; @@ -2702,6 +2745,7 @@ 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: @@ -3440,6 +3484,7 @@ 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: Index: channels/sig_analog.h =================================================================== --- channels/sig_analog.h (revision 278424) +++ channels/sig_analog.h (working copy) @@ -147,6 +147,14 @@ /*! \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); Index: configs/chan_dahdi.conf.sample =================================================================== --- configs/chan_dahdi.conf.sample (revision 278424) +++ configs/chan_dahdi.conf.sample (working copy) @@ -820,14 +820,22 @@ ; 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 ;