提交 cdfa8bf7 authored 作者: Moises Silva's avatar Moises Silva

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
上级 092d22a2
......@@ -12,31 +12,81 @@ with the signaling protocols that you can run on top of your I/O interfaces.
<settings>
<param name="debug" value="0"/>
<!--<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="3-way"/>-->
</settings>
<!-- Sample analog configuration -->
<!-- Sample analog configuration (The analog_spans tag is for ftmod_analog) -->
<analog_spans>
<!-- The span name must match the name in your freetdm.conf -->
<span name="myAnalog">
<!--<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"/>
<!-- How much time to wait for digits (in FXS lines) -->
<param name="digit-timeout" value="2000"/>
<!-- Maximum number of digits to wait for (in FXS lines) -->
<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"/>
<!-- 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 -->
<!--<param name="dial-regex" value="5555"/>-->
<!-- regex to stop dialing when it does not match -->
<!--<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>
</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
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.
......@@ -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
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.
-->
<r2_spans>
<span name="wp1" cfgprofile="testr2">
......
......@@ -2717,6 +2717,9 @@ static switch_status_t load_config(void)
char *hold_music = NULL;
char *fail_dial_regex = NULL;
const char *enable_callerid = "true";
const char *answer_polarity = "false";
const char *hangup_polarity = "false";
int polarity_delay = 600;
int callwaiting = 1;
uint32_t span_id = 0, to = 0, max = 0;
......@@ -2788,6 +2791,12 @@ static switch_status_t load_config(void)
dial_regex = val;
} else if (!strcasecmp(var, "enable-callerid")) {
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")) {
fail_dial_regex = val;
} else if (!strcasecmp(var, "hold-music")) {
......@@ -2848,6 +2857,9 @@ static switch_status_t load_config(void)
"max_dialstr", &max,
"hotline", hotline ? hotline : "",
"enable_callerid", enable_callerid,
"answer_polarity_reverse", answer_polarity,
"hangup_polarity_reverse", hangup_polarity,
"polarity_delay", &polarity_delay,
"callwaiting", &callwaiting,
FTDM_TAG_END) != FTDM_SUCCESS) {
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);
} 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));
goto done;
}
/* 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_channel_state2str(ftdmchan->last_state), ftdm_channel_state2str(state), DEFAULT_WAIT_TIME);
}
done:
return ok ? FTDM_SUCCESS : FTDM_FAIL;
}
......@@ -2289,8 +2290,15 @@ 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);
} else {
/* the signaling stack did not touch the state,
* core is responsible from clearing flags and stuff */
ftdm_channel_close(&chan);
* 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);
}
}
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)) {
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");
status = FTDM_FAIL;
goto done;
......
......@@ -37,7 +37,9 @@
typedef enum {
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;
#define FTDM_MAX_HOTLINE_STR 20
......@@ -47,11 +49,13 @@ struct ftdm_analog_data {
uint32_t flags;
uint32_t max_dialstr;
uint32_t wait_dialtone_timeout;
uint32_t polarity_delay;
uint32_t digit_timeout;
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);
typedef struct ftdm_analog_data ftdm_analog_data_t;
......
......@@ -784,17 +784,27 @@ static FIO_COMMAND_FUNCTION(wanpipe_command)
err = sangoma_set_tx_queue_sz(ftdmchan->sockfd, &tdm_api, queue_size);
}
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:
err = FTDM_NOTIMPL;
break;
};
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 FTDM_SUCCESS;
}
......@@ -1237,8 +1247,9 @@ FIO_CHANNEL_NEXT_EVENT_FUNCTION(wanpipe_channel_next_event)
wanpipe_tdm_api_t tdm_api;
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);
}
memset(&tdm_api, 0, sizeof(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);
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) {
case WP_TDMAPI_EVENT_LINK_STATUS_CONNECTED:
......@@ -1264,7 +1275,7 @@ FIO_CHANNEL_NEXT_EVENT_FUNCTION(wanpipe_channel_next_event)
}
break;
case WP_TDMAPI_EVENT_RXHOOK:
case WP_API_EVENT_RXHOOK:
{
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;
......@@ -1300,26 +1311,26 @@ FIO_CHANNEL_NEXT_EVENT_FUNCTION(wanpipe_channel_next_event)
}
}
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;
}
break;
/*
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;
}
break;
*/
case WP_TDMAPI_EVENT_RBS:
case WP_API_EVENT_RBS:
{
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);
}
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 };
event_id = FTDM_OOB_NOOP;
......@@ -1342,12 +1353,18 @@ FIO_CHANNEL_NEXT_EVENT_FUNCTION(wanpipe_channel_next_event)
}
}
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);
event_id = FTDM_OOB_ALARM_TRAP;
}
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:
{
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);
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) {
case WP_TDMAPI_EVENT_LINK_STATUS_CONNECTED:
......@@ -1436,7 +1453,7 @@ FIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_span_next_event)
}
break;
case WP_TDMAPI_EVENT_RXHOOK:
case WP_API_EVENT_RXHOOK:
{
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;
......@@ -1472,26 +1489,26 @@ FIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_span_next_event)
}
}
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;
}
break;
/*
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;
}
break;
*/
case WP_TDMAPI_EVENT_RBS:
case WP_API_EVENT_RBS:
{
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);
}
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 };
event_id = FTDM_OOB_NOOP;
......@@ -1514,12 +1531,18 @@ FIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_span_next_event)
}
}
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);
event_id = FTDM_OOB_ALARM_TRAP;
}
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:
{
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_SET_RX_QUEUE_SIZE,
FTDM_COMMAND_SET_TX_QUEUE_SIZE,
FTDM_COMMAND_SET_POLARITY,
} 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 */
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);
......
......@@ -143,7 +143,9 @@ extern "C" {
\return true value if the object has the flags defined
*/
#define ftdm_test_flag(obj, flag) ((obj)->flags & flag)
/*!< Physical (IO) module specific flags */
#define ftdm_test_pflag(obj, flag) ((obj)->pflags & flag)
/*!< signaling module specific flags */
#define ftdm_test_sflag(obj, flag) ((obj)->sflags & 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;
uint8_t fsk_buf[80];
uint32_t ring_count;
ftdm_polarity_t polarity;
/* Private I/O data. Do not touch unless you are an I/O module */
void *io_data;
/* 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)
typedef enum {
FTDM_OOB_NOOP,
FTDM_OOB_ONHOOK,
FTDM_OOB_OFFHOOK,
FTDM_OOB_WINK,
......@@ -131,11 +132,11 @@ typedef enum {
FTDM_OOB_RING_STOP,
FTDM_OOB_ALARM_TRAP,
FTDM_OOB_ALARM_CLEAR,
FTDM_OOB_NOOP,
FTDM_OOB_CAS_BITS_CHANGE,
FTDM_OOB_POLARITY_REVERSE,
FTDM_OOB_INVALID
} 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)
/*! \brief Event types */
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论