diff options
Diffstat (limited to 'channels')
-rw-r--r-- | channels/chan_dahdi.c | 50 | ||||
-rw-r--r-- | channels/sig_analog.c | 47 | ||||
-rw-r--r-- | channels/sig_analog.h | 8 |
3 files changed, 104 insertions, 1 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); |