mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-04-23 03:33:48 +00:00
freetdm: Added new OOB event FTDM_OOB_POLARITY_REVERSE
Added new channel command FTDM_COMMAND_SET_POLARITY ftmod_wanpipe - Added support to enqueue polarity events on FXO lines ftmod_wanpipe - Added support to set polarity on FXS lines ftmod_analog - Added support to answer and hangup FXO lines on polarity reverse ftmod_analog - Added support to reverse polarity in the FXS line on answer and hangup mod_freetdm - Added parameters answer-on-polarity, hangup-on-polarity and polarity-delay to enable those analog features
This commit is contained in:
parent
092d22a214
commit
cdfa8bf7ae
@ -12,31 +12,81 @@ with the signaling protocols that you can run on top of your I/O interfaces.
|
|||||||
<settings>
|
<settings>
|
||||||
<param name="debug" value="0"/>
|
<param name="debug" value="0"/>
|
||||||
<!--<param name="hold-music" value="$${moh_uri}"/>-->
|
<!--<param name="hold-music" value="$${moh_uri}"/>-->
|
||||||
|
<!-- Analog global options (they apply to all spans)
|
||||||
|
Remember you can only choose between either call-swap
|
||||||
|
or 3-way, not both!
|
||||||
|
-->
|
||||||
<!--<param name="enable-analog-option" value="call-swap"/>-->
|
<!--<param name="enable-analog-option" value="call-swap"/>-->
|
||||||
<!--<param name="enable-analog-option" value="3-way"/>-->
|
<!--<param name="enable-analog-option" value="3-way"/>-->
|
||||||
</settings>
|
</settings>
|
||||||
|
|
||||||
<!-- Sample analog configuration -->
|
<!-- Sample analog configuration (The analog_spans tag is for ftmod_analog) -->
|
||||||
<analog_spans>
|
<analog_spans>
|
||||||
<!-- The span name must match the name in your freetdm.conf -->
|
<!-- The span name must match the name in your freetdm.conf -->
|
||||||
<span name="myAnalog">
|
<span name="myAnalog">
|
||||||
<!--<param name="hold-music" value="$${moh_uri}"/>-->
|
<!--<param name="hold-music" value="$${moh_uri}"/>-->
|
||||||
<!--<param name="enable-analog-option" value="call-swap"/>-->
|
<!--
|
||||||
<!--<param name="enable-analog-option" value="3-way"/>-->
|
3-way allows you to flash your FXS line and dial
|
||||||
|
another number and put all the parties in a conference
|
||||||
|
|
||||||
|
call-swap allows you to flash your FXS line and swap
|
||||||
|
between one call and another
|
||||||
|
|
||||||
|
Remember you can only choose between either call-swap
|
||||||
|
or 3-way, not both!
|
||||||
|
|
||||||
|
<param name="enable-analog-option" value="call-swap"/>
|
||||||
|
<param name="enable-analog-option" value="3-way"/>
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!-- Tones are defined in tones.conf
|
||||||
|
This setting is very important for analog lines to
|
||||||
|
work properly
|
||||||
|
-->
|
||||||
<param name="tonegroup" value="us"/>
|
<param name="tonegroup" value="us"/>
|
||||||
|
|
||||||
|
<!-- How much time to wait for digits (in FXS lines) -->
|
||||||
<param name="digit-timeout" value="2000"/>
|
<param name="digit-timeout" value="2000"/>
|
||||||
|
|
||||||
|
<!-- Maximum number of digits to wait for (in FXS lines) -->
|
||||||
<param name="max-digits" value="11"/>
|
<param name="max-digits" value="11"/>
|
||||||
<param name="dialplan" value="XML"/>
|
|
||||||
<param name="context" value="default"/>
|
<!-- whether you want to wait for caller id -->
|
||||||
<param name="enable-callerid" value="true"/>
|
<param name="enable-callerid" value="true"/>
|
||||||
|
|
||||||
|
<!-- whether you want to enable callwaiting feature -->
|
||||||
|
<!--<param name="callwaiting" value="true"/>-->
|
||||||
|
|
||||||
|
<!-- whether you want to answer/hangup on polarity reverse for outgoing calls in FXO devices
|
||||||
|
and send polarity reverse on answer/hangup for incoming calls in FXS devices -->
|
||||||
|
<!--<param name="answer-polarity-reverse" value="false"/>-->
|
||||||
|
<!--<param name="hangup-polarity-reverse" value="false"/>-->
|
||||||
|
<!--
|
||||||
|
Minimum delay (in milliseconds) required between an answer polarity reverse
|
||||||
|
and hangup polarity reverse in order to assume the second polarity reverse is a real hangup
|
||||||
|
<param name="polarity-delay" value="600"/>
|
||||||
|
-->
|
||||||
|
|
||||||
<!-- regex to stop dialing when it matches -->
|
<!-- regex to stop dialing when it matches -->
|
||||||
<!--<param name="dial-regex" value="5555"/>-->
|
<!--<param name="dial-regex" value="5555"/>-->
|
||||||
|
|
||||||
<!-- regex to stop dialing when it does not match -->
|
<!-- regex to stop dialing when it does not match -->
|
||||||
<!--<param name="fail-dial-regex" value="^5"/>-->
|
<!--<param name="fail-dial-regex" value="^5"/>-->
|
||||||
|
|
||||||
|
<!-- FreeSWITCH dialplan type and context to send the calls -->
|
||||||
|
<param name="dialplan" value="XML"/>
|
||||||
|
<param name="context" value="default"/>
|
||||||
</span>
|
</span>
|
||||||
</analog_spans>
|
</analog_spans>
|
||||||
|
|
||||||
<!-- openr2 (MFC-R2 signaling) spans
|
<!--
|
||||||
|
|
||||||
|
openr2 (MFC-R2 signaling) spans (ftmod_r2)
|
||||||
|
|
||||||
|
In order to use this type of spans your FreeTDM must have been compiled with ftmod_r2 module.
|
||||||
|
The module is compiled if the openr2 library is present when running the ./configure script
|
||||||
|
in the FreeTDM source code
|
||||||
|
|
||||||
MFC-R2 signaling has lots of variants from country to country and even sometimes
|
MFC-R2 signaling has lots of variants from country to country and even sometimes
|
||||||
minor variants inside the same country. The only mandatory parameters here are:
|
minor variants inside the same country. The only mandatory parameters here are:
|
||||||
variant, but typically you also want to set max_ani and max_dnis.
|
variant, but typically you also want to set max_ani and max_dnis.
|
||||||
@ -46,6 +96,7 @@ with the signaling protocols that you can run on top of your I/O interfaces.
|
|||||||
best defaults for your country. If you want to contribute your configs for a particular
|
best defaults for your country. If you want to contribute your configs for a particular
|
||||||
country send them to the e-mail of the primary OpenR2 developer that you can find in the
|
country send them to the e-mail of the primary OpenR2 developer that you can find in the
|
||||||
AUTHORS file of the OpenR2 package, they will be added to the samples directory of openr2.
|
AUTHORS file of the OpenR2 package, they will be added to the samples directory of openr2.
|
||||||
|
|
||||||
-->
|
-->
|
||||||
<r2_spans>
|
<r2_spans>
|
||||||
<span name="wp1" cfgprofile="testr2">
|
<span name="wp1" cfgprofile="testr2">
|
||||||
|
@ -2717,6 +2717,9 @@ static switch_status_t load_config(void)
|
|||||||
char *hold_music = NULL;
|
char *hold_music = NULL;
|
||||||
char *fail_dial_regex = NULL;
|
char *fail_dial_regex = NULL;
|
||||||
const char *enable_callerid = "true";
|
const char *enable_callerid = "true";
|
||||||
|
const char *answer_polarity = "false";
|
||||||
|
const char *hangup_polarity = "false";
|
||||||
|
int polarity_delay = 600;
|
||||||
int callwaiting = 1;
|
int callwaiting = 1;
|
||||||
|
|
||||||
uint32_t span_id = 0, to = 0, max = 0;
|
uint32_t span_id = 0, to = 0, max = 0;
|
||||||
@ -2788,6 +2791,12 @@ static switch_status_t load_config(void)
|
|||||||
dial_regex = val;
|
dial_regex = val;
|
||||||
} else if (!strcasecmp(var, "enable-callerid")) {
|
} else if (!strcasecmp(var, "enable-callerid")) {
|
||||||
enable_callerid = val;
|
enable_callerid = val;
|
||||||
|
} else if (!strcasecmp(var, "answer-polarity-reverse")) {
|
||||||
|
answer_polarity = val;
|
||||||
|
} else if (!strcasecmp(var, "hangup-polarity-reverse")) {
|
||||||
|
hangup_polarity = val;
|
||||||
|
} else if (!strcasecmp(var, "polarity-delay")) {
|
||||||
|
polarity_delay = atoi(val);
|
||||||
} else if (!strcasecmp(var, "fail-dial-regex")) {
|
} else if (!strcasecmp(var, "fail-dial-regex")) {
|
||||||
fail_dial_regex = val;
|
fail_dial_regex = val;
|
||||||
} else if (!strcasecmp(var, "hold-music")) {
|
} else if (!strcasecmp(var, "hold-music")) {
|
||||||
@ -2848,6 +2857,9 @@ static switch_status_t load_config(void)
|
|||||||
"max_dialstr", &max,
|
"max_dialstr", &max,
|
||||||
"hotline", hotline ? hotline : "",
|
"hotline", hotline ? hotline : "",
|
||||||
"enable_callerid", enable_callerid,
|
"enable_callerid", enable_callerid,
|
||||||
|
"answer_polarity_reverse", answer_polarity,
|
||||||
|
"hangup_polarity_reverse", hangup_polarity,
|
||||||
|
"polarity_delay", &polarity_delay,
|
||||||
"callwaiting", &callwaiting,
|
"callwaiting", &callwaiting,
|
||||||
FTDM_TAG_END) != FTDM_SUCCESS) {
|
FTDM_TAG_END) != FTDM_SUCCESS) {
|
||||||
ftdm_log(FTDM_LOG_ERROR, "Error configuring FreeTDM analog span %s\n", ftdm_span_get_name(span));
|
ftdm_log(FTDM_LOG_ERROR, "Error configuring FreeTDM analog span %s\n", ftdm_span_get_name(span));
|
||||||
|
@ -1541,6 +1541,7 @@ end:
|
|||||||
ftdm_mutex_unlock(ftdmchan->span->mutex);
|
ftdm_mutex_unlock(ftdmchan->span->mutex);
|
||||||
} else {
|
} else {
|
||||||
ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_WARNING, "VETO state change from %s to %s\n", ftdm_channel_state2str(ftdmchan->state), ftdm_channel_state2str(state));
|
ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_WARNING, "VETO state change from %s to %s\n", ftdm_channel_state2str(ftdmchan->state), ftdm_channel_state2str(state));
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* there is an inherent race here between set and check of the change flag but we do not care because
|
/* there is an inherent race here between set and check of the change flag but we do not care because
|
||||||
@ -1570,7 +1571,7 @@ end:
|
|||||||
ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_WARNING, "state change from %s to %s was most likely not processed after aprox %dms\n",
|
ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_WARNING, "state change from %s to %s was most likely not processed after aprox %dms\n",
|
||||||
ftdm_channel_state2str(ftdmchan->last_state), ftdm_channel_state2str(state), DEFAULT_WAIT_TIME);
|
ftdm_channel_state2str(ftdmchan->last_state), ftdm_channel_state2str(state), DEFAULT_WAIT_TIME);
|
||||||
}
|
}
|
||||||
|
done:
|
||||||
return ok ? FTDM_SUCCESS : FTDM_FAIL;
|
return ok ? FTDM_SUCCESS : FTDM_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2289,9 +2290,16 @@ static ftdm_status_t call_hangup(ftdm_channel_t *chan, const char *file, const c
|
|||||||
ftdm_channel_set_state(file, func, line, chan, FTDM_CHANNEL_STATE_HANGUP, 1);
|
ftdm_channel_set_state(file, func, line, chan, FTDM_CHANNEL_STATE_HANGUP, 1);
|
||||||
} else {
|
} else {
|
||||||
/* the signaling stack did not touch the state,
|
/* the signaling stack did not touch the state,
|
||||||
* core is responsible from clearing flags and stuff */
|
* core is responsible from clearing flags and stuff, however, because ftmod_analog
|
||||||
|
* is a bitch in a serious need of refactoring, we also check whether the channel is open
|
||||||
|
* to avoid an spurious warning about the channel not being open. This is because ftmod_analog
|
||||||
|
* does not follow our convention of sending SIGEVENT_STOP and waiting for the user to move
|
||||||
|
* to HANGUP (implicitly through ftdm_channel_call_hangup(), as soon as ftmod_analog is fixed
|
||||||
|
* this check can be removed */
|
||||||
|
if (ftdm_test_flag(chan, FTDM_CHANNEL_OPEN)) {
|
||||||
ftdm_channel_close(&chan);
|
ftdm_channel_close(&chan);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return FTDM_SUCCESS;
|
return FTDM_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3933,7 +3941,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_write(ftdm_channel_t *ftdmchan, void *dat
|
|||||||
|
|
||||||
|
|
||||||
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OPEN)) {
|
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OPEN)) {
|
||||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "cannot write in channel not open\n");
|
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "cannot write in channel not open\n");
|
||||||
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "channel not open");
|
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "channel not open");
|
||||||
status = FTDM_FAIL;
|
status = FTDM_FAIL;
|
||||||
goto done;
|
goto done;
|
||||||
|
@ -37,7 +37,9 @@
|
|||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
FTDM_ANALOG_RUNNING = (1 << 0),
|
FTDM_ANALOG_RUNNING = (1 << 0),
|
||||||
FTDM_ANALOG_CALLERID = (1 << 1)
|
FTDM_ANALOG_CALLERID = (1 << 1),
|
||||||
|
FTDM_ANALOG_ANSWER_POLARITY_REVERSE = (1 << 2),
|
||||||
|
FTDM_ANALOG_HANGUP_POLARITY_REVERSE = (1 << 3)
|
||||||
} ftdm_analog_flag_t;
|
} ftdm_analog_flag_t;
|
||||||
|
|
||||||
#define FTDM_MAX_HOTLINE_STR 20
|
#define FTDM_MAX_HOTLINE_STR 20
|
||||||
@ -47,11 +49,13 @@ struct ftdm_analog_data {
|
|||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
uint32_t max_dialstr;
|
uint32_t max_dialstr;
|
||||||
uint32_t wait_dialtone_timeout;
|
uint32_t wait_dialtone_timeout;
|
||||||
|
uint32_t polarity_delay;
|
||||||
uint32_t digit_timeout;
|
uint32_t digit_timeout;
|
||||||
char hotline[FTDM_MAX_HOTLINE_STR];
|
char hotline[FTDM_MAX_HOTLINE_STR];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Analog flags to be set in the sflags (signaling flags) channel memeber */
|
||||||
|
#define AF_POLARITY_REVERSE (1 << 0)
|
||||||
|
|
||||||
static void *ftdm_analog_run(ftdm_thread_t *me, void *obj);
|
static void *ftdm_analog_run(ftdm_thread_t *me, void *obj);
|
||||||
typedef struct ftdm_analog_data ftdm_analog_data_t;
|
typedef struct ftdm_analog_data ftdm_analog_data_t;
|
||||||
|
@ -184,6 +184,7 @@ static FIO_SIG_CONFIGURE_FUNCTION(ftdm_analog_configure_span)
|
|||||||
uint32_t digit_timeout = 10;
|
uint32_t digit_timeout = 10;
|
||||||
uint32_t wait_dialtone_timeout = 30000;
|
uint32_t wait_dialtone_timeout = 30000;
|
||||||
uint32_t max_dialstr = MAX_DTMF;
|
uint32_t max_dialstr = MAX_DTMF;
|
||||||
|
uint32_t polarity_delay = 600;
|
||||||
const char *var, *val;
|
const char *var, *val;
|
||||||
int *intval;
|
int *intval;
|
||||||
uint32_t flags = FTDM_ANALOG_CALLERID;
|
uint32_t flags = FTDM_ANALOG_CALLERID;
|
||||||
@ -236,6 +237,29 @@ static FIO_SIG_CONFIGURE_FUNCTION(ftdm_analog_configure_span)
|
|||||||
} else {
|
} else {
|
||||||
flags &= ~FTDM_ANALOG_CALLERID;
|
flags &= ~FTDM_ANALOG_CALLERID;
|
||||||
}
|
}
|
||||||
|
} else if (!strcasecmp(var, "answer_polarity_reverse")) {
|
||||||
|
if (!(val = va_arg(ap, char *))) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (ftdm_true(val)) {
|
||||||
|
flags |= FTDM_ANALOG_ANSWER_POLARITY_REVERSE;
|
||||||
|
} else {
|
||||||
|
flags &= ~FTDM_ANALOG_ANSWER_POLARITY_REVERSE;
|
||||||
|
}
|
||||||
|
} else if (!strcasecmp(var, "hangup_polarity_reverse")) {
|
||||||
|
if (!(val = va_arg(ap, char *))) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (ftdm_true(val)) {
|
||||||
|
flags |= FTDM_ANALOG_HANGUP_POLARITY_REVERSE;
|
||||||
|
} else {
|
||||||
|
flags &= ~FTDM_ANALOG_HANGUP_POLARITY_REVERSE;
|
||||||
|
}
|
||||||
|
} else if (!strcasecmp(var, "polarity_delay")) {
|
||||||
|
if (!(intval = va_arg(ap, int *))) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
polarity_delay = *intval;
|
||||||
} else if (!strcasecmp(var, "callwaiting")) {
|
} else if (!strcasecmp(var, "callwaiting")) {
|
||||||
if (!(intval = va_arg(ap, int *))) {
|
if (!(intval = va_arg(ap, int *))) {
|
||||||
break;
|
break;
|
||||||
@ -276,6 +300,7 @@ static FIO_SIG_CONFIGURE_FUNCTION(ftdm_analog_configure_span)
|
|||||||
analog_data->flags = flags;
|
analog_data->flags = flags;
|
||||||
analog_data->digit_timeout = digit_timeout;
|
analog_data->digit_timeout = digit_timeout;
|
||||||
analog_data->wait_dialtone_timeout = wait_dialtone_timeout;
|
analog_data->wait_dialtone_timeout = wait_dialtone_timeout;
|
||||||
|
analog_data->polarity_delay = polarity_delay;
|
||||||
analog_data->max_dialstr = max_dialstr;
|
analog_data->max_dialstr = max_dialstr;
|
||||||
span->signal_cb = sig_cb;
|
span->signal_cb = sig_cb;
|
||||||
strncpy(analog_data->hotline, hotline, sizeof(analog_data->hotline));
|
strncpy(analog_data->hotline, hotline, sizeof(analog_data->hotline));
|
||||||
@ -399,6 +424,7 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
|
|||||||
ftdm_analog_data_t *analog_data = ftdmchan->span->signal_data;
|
ftdm_analog_data_t *analog_data = ftdmchan->span->signal_data;
|
||||||
ftdm_channel_t *closed_chan;
|
ftdm_channel_t *closed_chan;
|
||||||
uint32_t state_counter = 0, elapsed = 0, collecting = 0, interval = 0, last_digit = 0, indicate = 0, dial_timeout = analog_data->wait_dialtone_timeout;
|
uint32_t state_counter = 0, elapsed = 0, collecting = 0, interval = 0, last_digit = 0, indicate = 0, dial_timeout = analog_data->wait_dialtone_timeout;
|
||||||
|
uint32_t answer_on_polarity_counter = 0;
|
||||||
ftdm_sigmsg_t sig;
|
ftdm_sigmsg_t sig;
|
||||||
ftdm_status_t status;
|
ftdm_status_t status;
|
||||||
|
|
||||||
@ -469,11 +495,16 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
|
|||||||
if (state_counter > dial_timeout) {
|
if (state_counter > dial_timeout) {
|
||||||
if (ftdmchan->needed_tones[FTDM_TONEMAP_DIAL]) {
|
if (ftdmchan->needed_tones[FTDM_TONEMAP_DIAL]) {
|
||||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_BUSY);
|
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_BUSY);
|
||||||
|
} else {
|
||||||
|
/* do not go up if we're waiting for polarity reversal */
|
||||||
|
if (ftdm_test_flag(analog_data, FTDM_ANALOG_ANSWER_POLARITY_REVERSE)) {
|
||||||
|
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
|
||||||
} else {
|
} else {
|
||||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP);
|
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case FTDM_CHANNEL_STATE_GENRING:
|
case FTDM_CHANNEL_STATE_GENRING:
|
||||||
{
|
{
|
||||||
@ -561,8 +592,30 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
|
|||||||
}
|
}
|
||||||
case FTDM_CHANNEL_STATE_UP:
|
case FTDM_CHANNEL_STATE_UP:
|
||||||
case FTDM_CHANNEL_STATE_RING:
|
case FTDM_CHANNEL_STATE_RING:
|
||||||
|
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
|
||||||
{
|
{
|
||||||
|
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND) &&
|
||||||
|
ftdmchan->state == FTDM_CHANNEL_STATE_PROGRESS_MEDIA &&
|
||||||
|
ftdm_test_sflag(ftdmchan, AF_POLARITY_REVERSE)) {
|
||||||
|
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_NOTICE, "Answering on polarity reverse\n");
|
||||||
|
ftdm_clear_sflag(ftdmchan, AF_POLARITY_REVERSE);
|
||||||
|
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP);
|
||||||
|
answer_on_polarity_counter = state_counter;
|
||||||
|
} else if (ftdmchan->state == FTDM_CHANNEL_STATE_UP
|
||||||
|
&& ftdm_test_sflag(ftdmchan, AF_POLARITY_REVERSE)){
|
||||||
|
/* if this polarity reverse is close to the answer polarity reverse, ignore it */
|
||||||
|
if (answer_on_polarity_counter
|
||||||
|
&& (state_counter - answer_on_polarity_counter) > analog_data->polarity_delay) {
|
||||||
|
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_NOTICE, "Hanging up on polarity reverse\n");
|
||||||
|
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
|
||||||
|
} else {
|
||||||
|
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING,
|
||||||
|
"Not hanging up on polarity reverse, too close to Answer reverse\n");
|
||||||
|
}
|
||||||
|
ftdm_clear_sflag(ftdmchan, AF_POLARITY_REVERSE);
|
||||||
|
} else {
|
||||||
ftdm_sleep(interval);
|
ftdm_sleep(interval);
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -615,6 +668,18 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
|
|||||||
sig.event_id = FTDM_SIGEVENT_UP;
|
sig.event_id = FTDM_SIGEVENT_UP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ftdmchan->type == FTDM_CHAN_TYPE_FXS &&
|
||||||
|
!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND) &&
|
||||||
|
ftdm_test_flag(analog_data, FTDM_ANALOG_ANSWER_POLARITY_REVERSE)) {
|
||||||
|
ftdm_polarity_t polarity = FTDM_POLARITY_REVERSE;
|
||||||
|
if (ftdmchan->polarity != FTDM_POLARITY_FORWARD) {
|
||||||
|
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Polarity is already reversed on answer??\n");
|
||||||
|
} else {
|
||||||
|
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Reversing polarity on answer\n");
|
||||||
|
ftdm_channel_command(ftdmchan, FTDM_COMMAND_SET_POLARITY, &polarity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ftdm_span_send_signal(ftdmchan->span, &sig);
|
ftdm_span_send_signal(ftdmchan->span, &sig);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -639,6 +704,22 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case FTDM_CHANNEL_STATE_HANGUP:
|
||||||
|
/* this state is only used when the user hangup, if the device hang up (onhook) we currently
|
||||||
|
* go straight to DOWN. If we ever change this (as other signaling modules do) by using this
|
||||||
|
* state for both user and device hangup, we should check here for the type of hangup since
|
||||||
|
* some actions (polarity reverse) do not make sense if the device hung up */
|
||||||
|
if (ftdmchan->type == FTDM_CHAN_TYPE_FXS &&
|
||||||
|
ftdmchan->last_state == FTDM_CHANNEL_STATE_UP &&
|
||||||
|
ftdm_test_flag(analog_data, FTDM_ANALOG_HANGUP_POLARITY_REVERSE)) {
|
||||||
|
ftdm_polarity_t polarity = ftdmchan->polarity == FTDM_POLARITY_REVERSE
|
||||||
|
? FTDM_POLARITY_FORWARD : FTDM_POLARITY_REVERSE;
|
||||||
|
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Reversing polarity on hangup\n");
|
||||||
|
ftdm_channel_command(ftdmchan, FTDM_COMMAND_SET_POLARITY, &polarity);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case FTDM_CHANNEL_STATE_DOWN:
|
case FTDM_CHANNEL_STATE_DOWN:
|
||||||
{
|
{
|
||||||
sig.event_id = FTDM_SIGEVENT_STOP;
|
sig.event_id = FTDM_SIGEVENT_STOP;
|
||||||
@ -847,6 +928,9 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
|
|||||||
|
|
||||||
done:
|
done:
|
||||||
|
|
||||||
|
closed_chan = ftdmchan;
|
||||||
|
|
||||||
|
ftdm_channel_lock(closed_chan);
|
||||||
|
|
||||||
if (ftdmchan->type == FTDM_CHAN_TYPE_FXO && ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OFFHOOK)) {
|
if (ftdmchan->type == FTDM_CHAN_TYPE_FXO && ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OFFHOOK)) {
|
||||||
ftdm_channel_command(ftdmchan, FTDM_COMMAND_ONHOOK, NULL);
|
ftdm_channel_command(ftdmchan, FTDM_COMMAND_ONHOOK, NULL);
|
||||||
@ -857,7 +941,8 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
closed_chan = ftdmchan;
|
ftdm_clear_sflag(ftdmchan, AF_POLARITY_REVERSE);
|
||||||
|
|
||||||
ftdm_channel_close(&ftdmchan);
|
ftdm_channel_close(&ftdmchan);
|
||||||
|
|
||||||
ftdm_channel_command(closed_chan, FTDM_COMMAND_SET_NATIVE_CODEC, NULL);
|
ftdm_channel_command(closed_chan, FTDM_COMMAND_SET_NATIVE_CODEC, NULL);
|
||||||
@ -875,8 +960,11 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ftdm_log_chan(closed_chan, FTDM_LOG_DEBUG, "ANALOG CHANNEL %d:%d thread ended.\n", closed_chan->span_id, closed_chan->chan_id);
|
ftdm_log_chan(closed_chan, FTDM_LOG_DEBUG, "ANALOG CHANNEL %d:%d thread ended.\n", closed_chan->span_id, closed_chan->chan_id);
|
||||||
|
|
||||||
ftdm_clear_flag(closed_chan, FTDM_CHANNEL_INTHREAD);
|
ftdm_clear_flag(closed_chan, FTDM_CHANNEL_INTHREAD);
|
||||||
|
|
||||||
|
ftdm_channel_unlock(closed_chan);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -903,6 +991,19 @@ static __inline__ ftdm_status_t process_event(ftdm_span_t *span, ftdm_event_t *e
|
|||||||
ftdm_mutex_lock(event->channel->mutex);
|
ftdm_mutex_lock(event->channel->mutex);
|
||||||
locked++;
|
locked++;
|
||||||
|
|
||||||
|
/* MAINTENANCE WARNING:
|
||||||
|
* 1. Be aware you are working on the locked channel
|
||||||
|
* 2. We should not be calling ftdm_span_send_signal or ftdm_set_state when there is already a channel thread running
|
||||||
|
* however, since this is old code I am not changing it now, but new code should adhere to that convention
|
||||||
|
* otherwise, we have possible races where we compete with the user for state changes, ie, the user requests
|
||||||
|
* a state change and then we process an event, the state change from the user is pending so our ftdm_set_state
|
||||||
|
* operation will fail. In cases where we win the race, our state change will be accepted but if a user requests
|
||||||
|
* a state change before the state change we requested here is processed by the channel thread, we'll end up
|
||||||
|
* rejecting the user request.
|
||||||
|
*
|
||||||
|
* See docs/locking.txt for further information about what guarantees should signaling modules provide when
|
||||||
|
* locking/unlocking a channel
|
||||||
|
* */
|
||||||
switch(event->enum_id) {
|
switch(event->enum_id) {
|
||||||
case FTDM_OOB_RING_START:
|
case FTDM_OOB_RING_START:
|
||||||
{
|
{
|
||||||
@ -940,7 +1041,11 @@ static __inline__ ftdm_status_t process_event(ftdm_span_t *span, ftdm_event_t *e
|
|||||||
}
|
}
|
||||||
ftdm_set_state(event->channel, FTDM_CHANNEL_STATE_DOWN);
|
ftdm_set_state(event->channel, FTDM_CHANNEL_STATE_DOWN);
|
||||||
}
|
}
|
||||||
|
if (event->channel->type == FTDM_CHAN_TYPE_FXS) {
|
||||||
|
/* we always return to forward when the device goes onhook */
|
||||||
|
ftdm_polarity_t forward_polarity = FTDM_POLARITY_FORWARD;
|
||||||
|
ftdm_channel_command(event->channel, FTDM_COMMAND_SET_POLARITY, &forward_polarity);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case FTDM_OOB_FLASH:
|
case FTDM_OOB_FLASH:
|
||||||
@ -1004,6 +1109,35 @@ static __inline__ ftdm_status_t process_event(ftdm_span_t *span, ftdm_event_t *e
|
|||||||
ftdm_span_send_signal(span, &sig);
|
ftdm_span_send_signal(span, &sig);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case FTDM_OOB_POLARITY_REVERSE:
|
||||||
|
{
|
||||||
|
if (event->channel->type != FTDM_CHAN_TYPE_FXO) {
|
||||||
|
ftdm_log_chan_msg(event->channel, FTDM_LOG_WARNING,
|
||||||
|
"Ignoring polarity reversal, this should not happen in non-FXO channels!\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!ftdm_test_flag(event->channel, FTDM_CHANNEL_INTHREAD) &&
|
||||||
|
ftdm_test_flag(event->channel, FTDM_CHANNEL_OFFHOOK)) {
|
||||||
|
ftdm_log_chan_msg(event->channel, FTDM_LOG_WARNING,
|
||||||
|
"Forcing onhook in channel not in thread after polarity reversal\n");
|
||||||
|
ftdm_channel_command(event->channel, FTDM_COMMAND_ONHOOK, NULL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!ftdm_test_flag(analog_data, FTDM_ANALOG_ANSWER_POLARITY_REVERSE)
|
||||||
|
&& !ftdm_test_flag(analog_data, FTDM_ANALOG_HANGUP_POLARITY_REVERSE)) {
|
||||||
|
ftdm_log_chan_msg(event->channel, FTDM_LOG_DEBUG,
|
||||||
|
"Ignoring polarity reversal because this channel is not configured for it\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (event->channel->state == FTDM_CHANNEL_STATE_DOWN) {
|
||||||
|
ftdm_log_chan_msg(event->channel, FTDM_LOG_DEBUG,
|
||||||
|
"Ignoring polarity reversal because this channel is down\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* we have a good channel, set the polarity flag and let the channel thread deal with it */
|
||||||
|
ftdm_set_sflag(event->channel, AF_POLARITY_REVERSE);
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
ftdm_log_chan(event->channel, FTDM_LOG_DEBUG, "Ignoring event [%s] in state [%s]\n", ftdm_oob_event2str(event->enum_id), ftdm_channel_state2str(event->channel->state));
|
ftdm_log_chan(event->channel, FTDM_LOG_DEBUG, "Ignoring event [%s] in state [%s]\n", ftdm_oob_event2str(event->enum_id), ftdm_channel_state2str(event->channel->state));
|
||||||
|
@ -784,17 +784,27 @@ static FIO_COMMAND_FUNCTION(wanpipe_command)
|
|||||||
err = sangoma_set_tx_queue_sz(ftdmchan->sockfd, &tdm_api, queue_size);
|
err = sangoma_set_tx_queue_sz(ftdmchan->sockfd, &tdm_api, queue_size);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case FTDM_COMMAND_SET_POLARITY:
|
||||||
|
{
|
||||||
|
ftdm_polarity_t polarity = FTDM_COMMAND_OBJ_INT;
|
||||||
|
err = sangoma_tdm_set_polarity(ftdmchan->sockfd, &tdm_api, polarity);
|
||||||
|
if (!err) {
|
||||||
|
ftdmchan->polarity = polarity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
err = FTDM_NOTIMPL;
|
err = FTDM_NOTIMPL;
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "%s", strerror(errno));
|
int myerrno = errno;
|
||||||
|
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Wanpipe failed to execute command %d: %s\n", command, strerror(myerrno));
|
||||||
|
errno = myerrno;
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return FTDM_SUCCESS;
|
return FTDM_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1237,8 +1247,9 @@ FIO_CHANNEL_NEXT_EVENT_FUNCTION(wanpipe_channel_next_event)
|
|||||||
wanpipe_tdm_api_t tdm_api;
|
wanpipe_tdm_api_t tdm_api;
|
||||||
ftdm_span_t *span = ftdmchan->span;
|
ftdm_span_t *span = ftdmchan->span;
|
||||||
|
|
||||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_EVENT))
|
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_EVENT)) {
|
||||||
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_EVENT);
|
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_EVENT);
|
||||||
|
}
|
||||||
|
|
||||||
memset(&tdm_api, 0, sizeof(tdm_api));
|
memset(&tdm_api, 0, sizeof(tdm_api));
|
||||||
status = sangoma_tdm_read_event(ftdmchan->sockfd, &tdm_api);
|
status = sangoma_tdm_read_event(ftdmchan->sockfd, &tdm_api);
|
||||||
@ -1251,7 +1262,7 @@ FIO_CHANNEL_NEXT_EVENT_FUNCTION(wanpipe_channel_next_event)
|
|||||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "read wanpipe event %d\n", tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type);
|
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "read wanpipe event %d\n", tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type);
|
||||||
switch(tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type) {
|
switch(tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type) {
|
||||||
|
|
||||||
case WP_TDMAPI_EVENT_LINK_STATUS:
|
case WP_API_EVENT_LINK_STATUS:
|
||||||
{
|
{
|
||||||
switch(tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_link_status) {
|
switch(tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_link_status) {
|
||||||
case WP_TDMAPI_EVENT_LINK_STATUS_CONNECTED:
|
case WP_TDMAPI_EVENT_LINK_STATUS_CONNECTED:
|
||||||
@ -1264,7 +1275,7 @@ FIO_CHANNEL_NEXT_EVENT_FUNCTION(wanpipe_channel_next_event)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WP_TDMAPI_EVENT_RXHOOK:
|
case WP_API_EVENT_RXHOOK:
|
||||||
{
|
{
|
||||||
if (ftdmchan->type == FTDM_CHAN_TYPE_FXS) {
|
if (ftdmchan->type == FTDM_CHAN_TYPE_FXS) {
|
||||||
event_id = tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_hook_state & WP_TDMAPI_EVENT_RXHOOK_OFF ? FTDM_OOB_OFFHOOK : FTDM_OOB_ONHOOK;
|
event_id = tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_hook_state & WP_TDMAPI_EVENT_RXHOOK_OFF ? FTDM_OOB_OFFHOOK : FTDM_OOB_ONHOOK;
|
||||||
@ -1300,26 +1311,26 @@ FIO_CHANNEL_NEXT_EVENT_FUNCTION(wanpipe_channel_next_event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case WP_TDMAPI_EVENT_RING_DETECT:
|
case WP_API_EVENT_RING_DETECT:
|
||||||
{
|
{
|
||||||
event_id = tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_ring_state == WP_TDMAPI_EVENT_RING_PRESENT ? FTDM_OOB_RING_START : FTDM_OOB_RING_STOP;
|
event_id = tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_ring_state == WP_TDMAPI_EVENT_RING_PRESENT ? FTDM_OOB_RING_START : FTDM_OOB_RING_STOP;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
/*
|
/*
|
||||||
disabled this ones when configuring, we don't need them, do we?
|
disabled this ones when configuring, we don't need them, do we?
|
||||||
case WP_TDMAPI_EVENT_RING_TRIP_DETECT:
|
case WP_API_EVENT_RING_TRIP_DETECT:
|
||||||
{
|
{
|
||||||
event_id = tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_ring_state == WP_TDMAPI_EVENT_RING_PRESENT ? FTDM_OOB_ONHOOK : FTDM_OOB_OFFHOOK;
|
event_id = tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_ring_state == WP_TDMAPI_EVENT_RING_PRESENT ? FTDM_OOB_ONHOOK : FTDM_OOB_OFFHOOK;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
*/
|
*/
|
||||||
case WP_TDMAPI_EVENT_RBS:
|
case WP_API_EVENT_RBS:
|
||||||
{
|
{
|
||||||
event_id = FTDM_OOB_CAS_BITS_CHANGE;
|
event_id = FTDM_OOB_CAS_BITS_CHANGE;
|
||||||
ftdmchan->rx_cas_bits = wanpipe_swap_bits(tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_rbs_bits);
|
ftdmchan->rx_cas_bits = wanpipe_swap_bits(tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_rbs_bits);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case WP_TDMAPI_EVENT_DTMF:
|
case WP_API_EVENT_DTMF:
|
||||||
{
|
{
|
||||||
char tmp_dtmf[2] = { tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_dtmf_digit, 0 };
|
char tmp_dtmf[2] = { tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_dtmf_digit, 0 };
|
||||||
event_id = FTDM_OOB_NOOP;
|
event_id = FTDM_OOB_NOOP;
|
||||||
@ -1342,12 +1353,18 @@ FIO_CHANNEL_NEXT_EVENT_FUNCTION(wanpipe_channel_next_event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case WP_TDMAPI_EVENT_ALARM:
|
case WP_API_EVENT_ALARM:
|
||||||
{
|
{
|
||||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Got wanpipe alarms %d\n", tdm_api.wp_tdm_cmd.event.wp_api_event_alarm);
|
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Got wanpipe alarms %d\n", tdm_api.wp_tdm_cmd.event.wp_api_event_alarm);
|
||||||
event_id = FTDM_OOB_ALARM_TRAP;
|
event_id = FTDM_OOB_ALARM_TRAP;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case WP_API_EVENT_POLARITY_REVERSE:
|
||||||
|
{
|
||||||
|
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Got polarity reverse\n");
|
||||||
|
event_id = FTDM_OOB_POLARITY_REVERSE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Unhandled wanpipe event %d\n", tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type);
|
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Unhandled wanpipe event %d\n", tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type);
|
||||||
@ -1423,7 +1440,7 @@ FIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_span_next_event)
|
|||||||
ftdm_log_chan(span->channels[i], FTDM_LOG_DEBUG, "read wanpipe event %d\n", tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type);
|
ftdm_log_chan(span->channels[i], FTDM_LOG_DEBUG, "read wanpipe event %d\n", tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type);
|
||||||
switch(tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type) {
|
switch(tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type) {
|
||||||
|
|
||||||
case WP_TDMAPI_EVENT_LINK_STATUS:
|
case WP_API_EVENT_LINK_STATUS:
|
||||||
{
|
{
|
||||||
switch(tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_link_status) {
|
switch(tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_link_status) {
|
||||||
case WP_TDMAPI_EVENT_LINK_STATUS_CONNECTED:
|
case WP_TDMAPI_EVENT_LINK_STATUS_CONNECTED:
|
||||||
@ -1436,7 +1453,7 @@ FIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_span_next_event)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WP_TDMAPI_EVENT_RXHOOK:
|
case WP_API_EVENT_RXHOOK:
|
||||||
{
|
{
|
||||||
if (span->channels[i]->type == FTDM_CHAN_TYPE_FXS) {
|
if (span->channels[i]->type == FTDM_CHAN_TYPE_FXS) {
|
||||||
event_id = tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_hook_state & WP_TDMAPI_EVENT_RXHOOK_OFF ? FTDM_OOB_OFFHOOK : FTDM_OOB_ONHOOK;
|
event_id = tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_hook_state & WP_TDMAPI_EVENT_RXHOOK_OFF ? FTDM_OOB_OFFHOOK : FTDM_OOB_ONHOOK;
|
||||||
@ -1472,26 +1489,26 @@ FIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_span_next_event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case WP_TDMAPI_EVENT_RING_DETECT:
|
case WP_API_EVENT_RING_DETECT:
|
||||||
{
|
{
|
||||||
event_id = tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_ring_state == WP_TDMAPI_EVENT_RING_PRESENT ? FTDM_OOB_RING_START : FTDM_OOB_RING_STOP;
|
event_id = tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_ring_state == WP_TDMAPI_EVENT_RING_PRESENT ? FTDM_OOB_RING_START : FTDM_OOB_RING_STOP;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
/*
|
/*
|
||||||
disabled this ones when configuring, we don't need them, do we?
|
disabled this ones when configuring, we don't need them, do we?
|
||||||
case WP_TDMAPI_EVENT_RING_TRIP_DETECT:
|
case WP_API_EVENT_RING_TRIP_DETECT:
|
||||||
{
|
{
|
||||||
event_id = tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_ring_state == WP_TDMAPI_EVENT_RING_PRESENT ? FTDM_OOB_ONHOOK : FTDM_OOB_OFFHOOK;
|
event_id = tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_ring_state == WP_TDMAPI_EVENT_RING_PRESENT ? FTDM_OOB_ONHOOK : FTDM_OOB_OFFHOOK;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
*/
|
*/
|
||||||
case WP_TDMAPI_EVENT_RBS:
|
case WP_API_EVENT_RBS:
|
||||||
{
|
{
|
||||||
event_id = FTDM_OOB_CAS_BITS_CHANGE;
|
event_id = FTDM_OOB_CAS_BITS_CHANGE;
|
||||||
span->channels[i]->rx_cas_bits = wanpipe_swap_bits(tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_rbs_bits);
|
span->channels[i]->rx_cas_bits = wanpipe_swap_bits(tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_rbs_bits);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case WP_TDMAPI_EVENT_DTMF:
|
case WP_API_EVENT_DTMF:
|
||||||
{
|
{
|
||||||
char tmp_dtmf[2] = { tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_dtmf_digit, 0 };
|
char tmp_dtmf[2] = { tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_dtmf_digit, 0 };
|
||||||
event_id = FTDM_OOB_NOOP;
|
event_id = FTDM_OOB_NOOP;
|
||||||
@ -1514,12 +1531,18 @@ FIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_span_next_event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case WP_TDMAPI_EVENT_ALARM:
|
case WP_API_EVENT_ALARM:
|
||||||
{
|
{
|
||||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Got wanpipe alarms %d\n", tdm_api.wp_tdm_cmd.event.wp_api_event_alarm);
|
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Got wanpipe alarms %d\n", tdm_api.wp_tdm_cmd.event.wp_api_event_alarm);
|
||||||
event_id = FTDM_OOB_ALARM_TRAP;
|
event_id = FTDM_OOB_ALARM_TRAP;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case WP_API_EVENT_POLARITY_REVERSE:
|
||||||
|
{
|
||||||
|
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Got polarity reverse\n");
|
||||||
|
event_id = FTDM_OOB_POLARITY_REVERSE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Unhandled wanpipe event %d\n", tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type);
|
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Unhandled wanpipe event %d\n", tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type);
|
||||||
|
@ -557,8 +557,14 @@ typedef enum {
|
|||||||
FTDM_COMMAND_COUNT,
|
FTDM_COMMAND_COUNT,
|
||||||
FTDM_COMMAND_SET_RX_QUEUE_SIZE,
|
FTDM_COMMAND_SET_RX_QUEUE_SIZE,
|
||||||
FTDM_COMMAND_SET_TX_QUEUE_SIZE,
|
FTDM_COMMAND_SET_TX_QUEUE_SIZE,
|
||||||
|
FTDM_COMMAND_SET_POLARITY,
|
||||||
} ftdm_command_t;
|
} ftdm_command_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
FTDM_POLARITY_FORWARD = 0,
|
||||||
|
FTDM_POLARITY_REVERSE = 1
|
||||||
|
} ftdm_polarity_t;
|
||||||
|
|
||||||
/*! \brief Custom memory handler hooks. Not recommended to use unless you need memory allocation customizations */
|
/*! \brief Custom memory handler hooks. Not recommended to use unless you need memory allocation customizations */
|
||||||
typedef void *(*ftdm_malloc_func_t)(void *pool, ftdm_size_t len);
|
typedef void *(*ftdm_malloc_func_t)(void *pool, ftdm_size_t len);
|
||||||
typedef void *(*ftdm_calloc_func_t)(void *pool, ftdm_size_t elements, ftdm_size_t len);
|
typedef void *(*ftdm_calloc_func_t)(void *pool, ftdm_size_t elements, ftdm_size_t len);
|
||||||
|
@ -143,7 +143,9 @@ extern "C" {
|
|||||||
\return true value if the object has the flags defined
|
\return true value if the object has the flags defined
|
||||||
*/
|
*/
|
||||||
#define ftdm_test_flag(obj, flag) ((obj)->flags & flag)
|
#define ftdm_test_flag(obj, flag) ((obj)->flags & flag)
|
||||||
|
/*!< Physical (IO) module specific flags */
|
||||||
#define ftdm_test_pflag(obj, flag) ((obj)->pflags & flag)
|
#define ftdm_test_pflag(obj, flag) ((obj)->pflags & flag)
|
||||||
|
/*!< signaling module specific flags */
|
||||||
#define ftdm_test_sflag(obj, flag) ((obj)->sflags & flag)
|
#define ftdm_test_sflag(obj, flag) ((obj)->sflags & flag)
|
||||||
|
|
||||||
#define ftdm_set_alarm_flag(obj, flag) (obj)->alarm_flags |= (flag)
|
#define ftdm_set_alarm_flag(obj, flag) (obj)->alarm_flags |= (flag)
|
||||||
@ -456,6 +458,7 @@ struct ftdm_channel {
|
|||||||
ftdm_fsk_data_state_t fsk;
|
ftdm_fsk_data_state_t fsk;
|
||||||
uint8_t fsk_buf[80];
|
uint8_t fsk_buf[80];
|
||||||
uint32_t ring_count;
|
uint32_t ring_count;
|
||||||
|
ftdm_polarity_t polarity;
|
||||||
/* Private I/O data. Do not touch unless you are an I/O module */
|
/* Private I/O data. Do not touch unless you are an I/O module */
|
||||||
void *io_data;
|
void *io_data;
|
||||||
/* Private signaling data. Do not touch unless you are a signaling module */
|
/* Private signaling data. Do not touch unless you are a signaling module */
|
||||||
|
@ -123,6 +123,7 @@ typedef enum {
|
|||||||
FTDM_STR2ENUM_P(ftdm_str2ftdm_analog_start_type, ftdm_analog_start_type2str, ftdm_analog_start_type_t)
|
FTDM_STR2ENUM_P(ftdm_str2ftdm_analog_start_type, ftdm_analog_start_type2str, ftdm_analog_start_type_t)
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
FTDM_OOB_NOOP,
|
||||||
FTDM_OOB_ONHOOK,
|
FTDM_OOB_ONHOOK,
|
||||||
FTDM_OOB_OFFHOOK,
|
FTDM_OOB_OFFHOOK,
|
||||||
FTDM_OOB_WINK,
|
FTDM_OOB_WINK,
|
||||||
@ -131,11 +132,11 @@ typedef enum {
|
|||||||
FTDM_OOB_RING_STOP,
|
FTDM_OOB_RING_STOP,
|
||||||
FTDM_OOB_ALARM_TRAP,
|
FTDM_OOB_ALARM_TRAP,
|
||||||
FTDM_OOB_ALARM_CLEAR,
|
FTDM_OOB_ALARM_CLEAR,
|
||||||
FTDM_OOB_NOOP,
|
|
||||||
FTDM_OOB_CAS_BITS_CHANGE,
|
FTDM_OOB_CAS_BITS_CHANGE,
|
||||||
|
FTDM_OOB_POLARITY_REVERSE,
|
||||||
FTDM_OOB_INVALID
|
FTDM_OOB_INVALID
|
||||||
} ftdm_oob_event_t;
|
} ftdm_oob_event_t;
|
||||||
#define OOB_STRINGS "ONHOOK", "OFFHOOK", "WINK", "FLASH", "RING_START", "RING_STOP", "ALARM_TRAP", "ALARM_CLEAR", "NOOP", "CAS_BITS_CHANGE", "INVALID"
|
#define OOB_STRINGS "NOOP", "ONHOOK", "OFFHOOK", "WINK", "FLASH", "RING_START", "RING_STOP", "ALARM_TRAP", "ALARM_CLEAR", "CAS_BITS_CHANGE", "POLARITY_REVERSE", "INVALID"
|
||||||
FTDM_STR2ENUM_P(ftdm_str2ftdm_oob_event, ftdm_oob_event2str, ftdm_oob_event_t)
|
FTDM_STR2ENUM_P(ftdm_str2ftdm_oob_event, ftdm_oob_event2str, ftdm_oob_event_t)
|
||||||
|
|
||||||
/*! \brief Event types */
|
/*! \brief Event types */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user