Merge branch 'master' into arnaldo.zt_chan_next_event

This commit is contained in:
Arnaldo Pereira 2010-12-22 19:09:53 -02:00
commit 818887f9d3
21 changed files with 466 additions and 108 deletions

View File

@ -204,6 +204,8 @@
<X-PRE-PROCESS cmd="set" data="fr-ring=%(1500,3500,440.0,0.0)"/>
<X-PRE-PROCESS cmd="set" data="rs-ring=%(1000,4000,425.0,0.0)"/>
<X-PRE-PROCESS cmd="set" data="ru-ring=%(800,3200,425,0)"/>
<X-PRE-PROCESS cmd="set" data="de-ring=%(1000,4000,425,0)"/>
<X-PRE-PROCESS cmd="set" data="dz-ring=%(1500,3500,425.0,0.0)"/>
<X-PRE-PROCESS cmd="set" data="bong-ring=v=-7;%(100,0,941.0,1477.0);v=-7;>=2;+=.1;%(1400,0,350,440)"/>
<X-PRE-PROCESS cmd="set" data="sit=%(274,0,913.8);%(274,0,1370.6);%(380,0,1776.7)"/>
<!--

View File

@ -656,7 +656,7 @@ static int process_command(esl_handle_t *handle, const char *cmd)
"-----------------------------------------------\n"
"/help \tHelp\n"
"/exit, /quit, /bye, ... \tExit the program.\n"
"/event, /noevent, /nixevent\tEvent commands.\n"
"/event, /noevents, /nixevent\tEvent commands.\n"
"/log, /nolog \tLog commands.\n"
"/uuid \tFilter logs for a single call uuid\n"
"/filter \tFilter commands.\n"
@ -692,7 +692,7 @@ static int process_command(esl_handle_t *handle, const char *cmd)
} else if (
!strncasecmp(cmd, "event", 5) ||
!strncasecmp(cmd, "noevent", 7) ||
!strncasecmp(cmd, "noevents", 8) ||
!strncasecmp(cmd, "nixevent", 8) ||
!strncasecmp(cmd, "log", 3) ||
!strncasecmp(cmd, "nolog", 5) ||

View File

@ -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">

View File

@ -103,7 +103,7 @@
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalDependencies>FreeSwitch.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>FreeSwitchCore.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>../../../$(PlatformName)\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
@ -127,7 +127,7 @@
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalDependencies>FreeSwitch.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>FreeSwitchCore.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>../../../$(PlatformName)\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>

View File

@ -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));

View File

@ -63,7 +63,7 @@ ftdm_time_t time_last_throttle_log = 0;
ftdm_time_t time_current_throttle_log = 0;
static ftdm_iterator_t *get_iterator(ftdm_iterator_type_t type, ftdm_iterator_t *iter);
static ftdm_status_t ftdm_call_set_call_id(ftdm_caller_data_t *caller_data);
static ftdm_status_t ftdm_call_set_call_id(ftdm_channel_t *fchan, ftdm_caller_data_t *caller_data);
static ftdm_status_t ftdm_call_clear_call_id(ftdm_caller_data_t *caller_data);
static ftdm_status_t ftdm_channel_clear_vars(ftdm_channel_t *ftdmchan);
static ftdm_status_t ftdm_channel_done(ftdm_channel_t *ftdmchan);
@ -1546,6 +1546,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
@ -1575,7 +1576,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;
}
@ -2294,8 +2295,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;
}
@ -2519,7 +2527,7 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_place(const char *file, const char
if (status == FTDM_SUCCESS) {
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_CALL_STARTED);
ftdm_call_set_call_id(&ftdmchan->caller_data);
ftdm_call_set_call_id(ftdmchan, &ftdmchan->caller_data);
ftdm_wait_for_flag_cleared(ftdmchan, FTDM_CHANNEL_STATE_CHANGE, 100);
}
@ -2603,10 +2611,11 @@ FT_DECLARE(ftdm_status_t) ftdm_span_get_sig_status(ftdm_span_t *span, ftdm_signa
}
}
/* this function must be called with the channel lock */
static ftdm_status_t ftdm_channel_done(ftdm_channel_t *ftdmchan)
{
ftdm_assert_return(ftdmchan != NULL, FTDM_FAIL, "Null channel can't be done!\n");
ftdm_mutex_lock(ftdmchan->mutex);
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_OPEN);
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_DTMF_DETECT);
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_SUPRESS_DTMF);
@ -2691,7 +2700,6 @@ static ftdm_status_t ftdm_channel_done(ftdm_channel_t *ftdmchan)
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_TRANSCODE);
}
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "channel done\n");
ftdm_mutex_unlock(ftdmchan->mutex);
return FTDM_SUCCESS;
}
@ -3938,7 +3946,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;
@ -4394,6 +4402,16 @@ static void print_channels_by_state(ftdm_stream_handle_t *stream, ftdm_channel_s
ftdm_mutex_unlock(globals.mutex);
}
static void print_core_usage(ftdm_stream_handle_t *stream)
{
stream->write_function(stream,
"--------------------------------------------------------------------------------\n"
"ftdm core state [!]<state_name> - List all channels in or not in the given state\n"
"ftdm core flag <flag-int-value> - List all channels with the fiven flag value set\n"
"ftdm core calls - List all known calls to the FreeTDM core\n"
"--------------------------------------------------------------------------------\n");
}
static char *handle_core_command(const char *cmd)
{
char *mycmd = NULL;
@ -4404,22 +4422,31 @@ static char *handle_core_command(const char *cmd)
char *state = NULL;
char *flag = NULL;
uint32_t flagval = 0;
uint32_t current_call_id = 0;
ftdm_caller_data_t *calldata = NULL;
ftdm_channel_t *fchan = NULL;
ftdm_channel_state_t i = FTDM_CHANNEL_STATE_INVALID;
ftdm_stream_handle_t stream = { 0 };
FTDM_STANDARD_STREAM(stream);
if (cmd) {
if (cmd && strlen(cmd)) {
mycmd = ftdm_strdup(cmd);
argc = ftdm_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
} else {
stream.write_function(&stream, "invalid core command\n");
print_core_usage(&stream);
goto done;
}
if (!argc) {
print_core_usage(&stream);
goto done;
}
if (!strcasecmp(argv[0], "state")) {
if (argc < 2) {
stream.write_function(&stream, "core state command requires an argument\n");
print_core_usage(&stream);
goto done;
}
state = argv[1];
@ -4440,7 +4467,8 @@ static char *handle_core_command(const char *cmd)
stream.write_function(&stream, "\nTotal channels %s %s: %d\n", not ? "not in state" : "in state", ftdm_channel_state2str(i), count);
} else if (!strcasecmp(argv[0], "flag")) {
if (argc < 2) {
stream.write_function(&stream, "core state command requires an argument\n");
stream.write_function(&stream, "core flag command requires an argument\n");
print_core_usage(&stream);
goto done;
}
flag = argv[1];
@ -4451,8 +4479,28 @@ static char *handle_core_command(const char *cmd)
flagval = atoi(flag);
print_channels_by_flag(&stream, flagval, not, &count);
stream.write_function(&stream, "\nTotal channels %s %d: %d\n", not ? "without flag" : "with flag", flagval, count);
} else if (!strcasecmp(argv[0], "calls")) {
ftdm_mutex_lock(globals.call_id_mutex);
current_call_id = globals.last_call_id;
for (current_call_id = 0; current_call_id <= MAX_CALLIDS; current_call_id++) {
if (!globals.call_ids[current_call_id]) {
continue;
}
calldata = globals.call_ids[current_call_id];
fchan = calldata->fchan;
if (fchan) {
stream.write_function(&stream, "Call %d on channel %d:%d\n", current_call_id,
fchan->span_id, fchan->chan_id);
} else {
stream.write_function(&stream, "Call %d without a channel?\n", current_call_id);
}
count++;
}
ftdm_mutex_unlock(globals.call_id_mutex);
stream.write_function(&stream, "\nTotal calls: %d\n", count);
} else {
stream.write_function(&stream, "invalid core command %s\n", argv[0]);
print_core_usage(&stream);
}
done:
@ -4472,6 +4520,8 @@ FT_DECLARE(char *) ftdm_api_execute(const char *cmd)
if ((p = strchr(dup, ' '))) {
*p++ = '\0';
cmd = p;
} else {
cmd = "";
}
type = dup;
@ -5444,7 +5494,7 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t
case FTDM_SIGEVENT_START:
{
ftdm_set_flag(sigmsg->channel, FTDM_CHANNEL_CALL_STARTED);
ftdm_call_set_call_id(&sigmsg->channel->caller_data);
ftdm_call_set_call_id(sigmsg->channel, &sigmsg->channel->caller_data);
ftdm_set_echocancel_call_begin(sigmsg->channel);
if (sigmsg->channel->dtmfdbg.requested) {
ftdm_channel_command(sigmsg->channel, FTDM_COMMAND_ENABLE_DEBUG_DTMF, NULL);
@ -6086,27 +6136,35 @@ FT_DECLARE(char *) ftdm_channel_get_history_str(const ftdm_channel_t *fchan)
return stream.data;
}
static ftdm_status_t ftdm_call_set_call_id(ftdm_caller_data_t *caller_data)
static ftdm_status_t ftdm_call_set_call_id(ftdm_channel_t *fchan, ftdm_caller_data_t *caller_data)
{
uint32_t current_call_id;
ftdm_assert_return(!caller_data->call_id, FTDM_FAIL, "Overwriting non-cleared call-id");
ftdm_assert_return(!caller_data->call_id, FTDM_FAIL, "Overwriting non-cleared call-id\n");
ftdm_mutex_lock(globals.call_id_mutex);
current_call_id = globals.last_call_id;
do {
if (++current_call_id > MAX_CALLIDS) {
for (current_call_id = globals.last_call_id + 1;
current_call_id != globals.last_call_id;
current_call_id++ ) {
if (current_call_id > MAX_CALLIDS) {
current_call_id = 1;
}
if (globals.call_ids[current_call_id] != NULL) {
continue;
if (globals.call_ids[current_call_id] == NULL) {
break;
}
} while (0);
}
ftdm_assert_return(globals.call_ids[current_call_id] == NULL, FTDM_FAIL, "We ran out of call ids\n");
globals.last_call_id = current_call_id;
caller_data->call_id = current_call_id;
globals.call_ids[current_call_id] = caller_data;
caller_data->fchan = fchan;
ftdm_mutex_unlock(globals.call_id_mutex);
return FTDM_SUCCESS;
}
@ -6123,8 +6181,8 @@ static ftdm_status_t ftdm_call_clear_call_id(ftdm_caller_data_t *caller_data)
ftdm_mutex_lock(globals.call_id_mutex);
if (globals.call_ids[caller_data->call_id]) {
ftdm_log(FTDM_LOG_DEBUG, "Cleared call with id %u\n", caller_data->call_id);
caller_data->call_id = 0;
globals.call_ids[caller_data->call_id] = NULL;
caller_data->call_id = 0;
} else {
ftdm_log(FTDM_LOG_CRIT, "call-id did not exist %u\n", caller_data->call_id);
}

View File

@ -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;

View File

@ -184,6 +184,7 @@ static FIO_SIG_CONFIGURE_FUNCTION(ftdm_analog_configure_span)
uint32_t digit_timeout = 10;
uint32_t wait_dialtone_timeout = 30000;
uint32_t max_dialstr = MAX_DTMF;
uint32_t polarity_delay = 600;
const char *var, *val;
int *intval;
uint32_t flags = FTDM_ANALOG_CALLERID;
@ -236,6 +237,29 @@ static FIO_SIG_CONFIGURE_FUNCTION(ftdm_analog_configure_span)
} else {
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")) {
if (!(intval = va_arg(ap, int *))) {
break;
@ -276,6 +300,7 @@ static FIO_SIG_CONFIGURE_FUNCTION(ftdm_analog_configure_span)
analog_data->flags = flags;
analog_data->digit_timeout = digit_timeout;
analog_data->wait_dialtone_timeout = wait_dialtone_timeout;
analog_data->polarity_delay = polarity_delay;
analog_data->max_dialstr = max_dialstr;
span->signal_cb = sig_cb;
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_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 answer_on_polarity_counter = 0;
ftdm_sigmsg_t sig;
ftdm_status_t status;
@ -470,7 +496,12 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
if (ftdmchan->needed_tones[FTDM_TONEMAP_DIAL]) {
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_BUSY);
} else {
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP);
/* 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 {
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP);
}
}
}
}
@ -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_RING:
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
{
ftdm_sleep(interval);
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);
}
continue;
}
break;
@ -615,6 +668,18 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
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);
continue;
}
@ -639,6 +704,22 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
continue;
}
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:
{
sig.event_id = FTDM_SIGEVENT_STOP;
@ -847,6 +928,9 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
done:
closed_chan = ftdmchan;
ftdm_channel_lock(closed_chan);
if (ftdmchan->type == FTDM_CHAN_TYPE_FXO && ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OFFHOOK)) {
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_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_clear_flag(closed_chan, FTDM_CHANNEL_INTHREAD);
ftdm_channel_unlock(closed_chan);
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);
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) {
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);
}
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;
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);
}
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:
{
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));

View File

@ -40,11 +40,12 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="&quot;C:\Program Files\libsng_isdn\include&quot;;&quot;C:\Program Files\libsng_isdn\include\sng_isdn&quot;;../../include;&quot;C:\Program Files\Sangoma\include&quot;"
AdditionalIncludeDirectories="&quot;C:\Program Files\sangoma\sng_isdn\include&quot;;../../include;&quot;C:\Program Files\Sangoma\include&quot;"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;"
MinimalRebuild="true"
ExceptionHandling="0"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@ -63,7 +64,7 @@
Name="VCLinkerTool"
AdditionalDependencies="freetdm.lib libsng_isdn.lib"
LinkIncremental="2"
AdditionalLibraryDirectories="&quot;$(OutDir)&quot;;&quot;C:\Program Files\libsng_isdn\lib&quot;;&quot;C:\Program Files\Sangoma\api\lib\x86&quot;"
AdditionalLibraryDirectories="&quot;$(OutDir)&quot;;&quot;C:\Program Files\sangoma\sng_isdn\lib&quot;;&quot;C:\Program Files\Sangoma\api\lib\x86&quot;"
GenerateDebugInformation="true"
SubSystem="1"
RandomizedBaseAddress="1"
@ -116,10 +117,11 @@
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;C:\Program Files\sangoma\sng_isdn\include&quot;;../../include;&quot;C:\Program Files\Sangoma\include&quot;"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@ -136,7 +138,9 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="freetdm.lib libsng_isdn.lib"
LinkIncremental="2"
AdditionalLibraryDirectories="&quot;$(OutDir)&quot;;&quot;C:\Program Files\sangoma\sng_isdn\lib&quot;;&quot;C:\Program Files\Sangoma\api\lib\x86&quot;"
GenerateDebugInformation="true"
SubSystem="2"
OptimizeReferences="2"

View File

@ -85,7 +85,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>C:\Program Files\libsng_isdn\include;C:\Program Files\libsng_isdn\include\sng_isdn;../../include;C:\Program Files\Sangoma\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>C:\Program Files\sangoma\sng_isdn\include;../../include;C:\Program Files\Sangoma\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<ExceptionHandling>
@ -95,10 +95,11 @@
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
</ClCompile>
<Link>
<AdditionalDependencies>freetdm.lib;libsng_isdn.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(OutDir);C:\Program Files\libsng_isdn\lib;C:\Program Files\Sangoma\api\lib\x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>$(OutDir);C:\Program Files\sangoma\sng_isdn\lib;C:\Program Files\Sangoma\api\lib\x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
@ -110,7 +111,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>C:\Program Files\libsng_isdn\include;C:\Program Files\libsng_isdn\include\sng_isdn;../../include;C:\Program Files\Sangoma\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>C:\Program Files\sangoma\sng_isdn\include;../../include;C:\Program Files\Sangoma\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ExceptionHandling>
</ExceptionHandling>
@ -119,6 +120,7 @@
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
</ClCompile>
<Link>
<AdditionalDependencies>freetdm.lib;libsng_isdn.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -135,11 +137,13 @@
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>C:\Program Files\sangoma\sng_isdn\include;../../include;C:\Program Files\Sangoma\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<Optimization>Disabled</Optimization>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
@ -147,23 +151,27 @@
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<TargetMachine>MachineX86</TargetMachine>
<AdditionalDependencies>freetdm.lib;libsng_isdn.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(OutDir);C:\Program Files\sangoma\sng_isdn\lib;C:\Program Files\Sangoma\api\lib\x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>C:\Program Files\sangoma\sng_isdn\include;../../include;C:\Program Files\Sangoma\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<AdditionalDependencies>freetdm.lib;libsng_isdn.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>

View File

@ -100,7 +100,7 @@
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalDependencies>freetdm.lib;libsangoma.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>libsangoma.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(OutDir);C:\Program Files\Sangoma\api\lib\x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
@ -127,7 +127,7 @@
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalDependencies>freetdm.lib;libsangoma.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>libsangoma.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(OutDir);C:\Program Files\Sangoma\api\lib\x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
@ -148,7 +148,7 @@
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalDependencies>freetdm.lib;libsangoma.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>libsangoma.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(OutDir);C:\Program Files\Sangoma\api\lib\x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
@ -174,7 +174,7 @@
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalDependencies>freetdm.lib;libsangoma.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>libsangoma.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(OutDir);C:\Program Files\Sangoma\api\lib\x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>

View File

@ -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);

View File

@ -320,6 +320,7 @@ typedef struct ftdm_caller_data {
* that the user can use caller_data.call_id to obtain the call_id. The user
* should use the call_id from sigmsg otherwise */
uint32_t call_id; /*!< Unique call ID for this call */
ftdm_channel_t *fchan; /*!< FreeTDM channel associated (can be NULL) */
} ftdm_caller_data_t;
/*! \brief Tone type */
@ -557,8 +558,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);

View File

@ -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 */

View File

@ -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 */

View File

@ -191,7 +191,8 @@ typedef enum {
EFLAG_TRANSFER = (1 << 23),
EFLAG_BGDIAL_RESULT = (1 << 24),
EFLAG_FLOOR_CHANGE = (1 << 25),
EFLAG_MUTE_DETECT = (1 << 26)
EFLAG_MUTE_DETECT = (1 << 26),
EFLAG_RECORD = (1 << 27)
} event_type_t;
typedef struct conference_file_node {
@ -270,6 +271,7 @@ typedef struct conference_obj {
uint32_t not_talking_buf_len;
int comfort_noise_level;
int is_recording;
int record_count;
int video_running;
uint32_t eflags;
uint32_t verbose_events;
@ -283,6 +285,7 @@ typedef struct conference_obj {
uint32_t avg_score;
uint32_t avg_itt;
uint32_t avg_tally;
switch_time_t run_time;
} conference_obj_t;
/* Relationship with another member */
@ -468,6 +471,7 @@ static switch_status_t conference_add_event_member_data(conference_member_t *mem
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Hear", "%s", switch_test_flag(member, MFLAG_CAN_HEAR) ? "true" : "false" );
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Speak", "%s", switch_test_flag(member, MFLAG_CAN_SPEAK) ? "true" : "false" );
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Talking", "%s", switch_test_flag(member, MFLAG_TALKING) ? "true" : "false" );
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Mute-Detect", "%s", switch_test_flag(member, MFLAG_MUTE_DETECT) ? "true" : "false" );
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Member-ID", "%u", member->id);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Member-Type", "%s", switch_test_flag(member, MFLAG_MOD) ? "moderator" : "member");
@ -563,6 +567,7 @@ static switch_status_t conference_record_stop(conference_obj_t *conference, char
return count;
}
/* Add a custom relationship to a member */
static conference_relationship_t *member_add_relationship(conference_member_t *member, uint32_t id)
{
@ -1035,6 +1040,7 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, v
switch_mutex_unlock(globals.hash_mutex);
conference->is_recording = 0;
conference->record_count = 0;
while (globals.running && !switch_test_flag(conference, CFLAG_DESTRUCT)) {
switch_size_t file_sample_len = samples;
@ -1099,6 +1105,7 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, v
/* Start recording if there's more than one participant. */
if (conference->auto_record && !conference->is_recording && conference->count > 1) {
conference->is_recording = 1;
conference->record_count++;
imember = conference->members;
if (imember) {
switch_channel_t *channel = switch_core_session_get_channel(imember->session);
@ -2623,6 +2630,7 @@ static void *SWITCH_THREAD_FUNC conference_record_thread_run(switch_thread_t *th
switch_timer_t timer = { 0 };
uint32_t rlen;
switch_size_t data_buf_len;
switch_event_t *event;
data_buf_len = samples * sizeof(int16_t);
@ -2701,6 +2709,15 @@ static void *SWITCH_THREAD_FUNC conference_record_thread_run(switch_thread_t *th
switch_core_file_set_string(&fh, SWITCH_AUDIO_COL_STR_ARTIST, "FreeSWITCH mod_conference Software Conference Module");
if (test_eflag(conference, EFLAG_RECORD) &&
switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
conference_add_event_data(conference, event);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "start-recording");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Path", rec->path);
switch_event_fire(&event);
}
while (switch_test_flag(member, MFLAG_RUNNING) && switch_test_flag(conference, CFLAG_RUNNING) && conference->count) {
switch_size_t len = 0;
mux_used = (uint32_t) switch_buffer_inuse(member->mux_buffer);
@ -3759,6 +3776,13 @@ static void conference_xlist(conference_obj_t *conference, switch_xml_t x_confer
switch_xml_set_attr_d(x_conference, "dynamic", "true");
}
if (conference->record_count > 0) {
switch_xml_set_attr_d(x_conference, "recording", "true");
}
switch_snprintf(i, sizeof(i), "%d", switch_epoch_time_now(NULL) - conference->run_time);
switch_xml_set_attr_d(x_conference, "run_time", ival);
if (conference->agc_level) {
char tmp[30] = "";
switch_snprintf(tmp, sizeof(tmp), "%d", conference->agc_level);
@ -3825,6 +3849,9 @@ static void conference_xlist(conference_obj_t *conference, switch_xml_t x_confer
x_tag = switch_xml_add_child_d(x_flags, "can_speak", count++);
switch_xml_set_txt_d(x_tag, switch_test_flag(member, MFLAG_CAN_SPEAK) ? "true" : "false");
x_tag = switch_xml_add_child_d(x_flags, "mute_detect", count++);
switch_xml_set_txt_d(x_tag, switch_test_flag(member, MFLAG_MUTE_DETECT) ? "true" : "false");
x_tag = switch_xml_add_child_d(x_flags, "talking", count++);
switch_xml_set_txt_d(x_tag, switch_test_flag(member, MFLAG_TALKING) ? "true" : "false");
@ -4414,6 +4441,7 @@ static switch_status_t conf_api_sub_record(conference_obj_t *conference, switch_
return SWITCH_STATUS_GENERR;
stream->write_function(stream, "Record file %s\n", argv[2]);
conference->record_count++;
launch_conference_record_thread(conference, argv[2]);
return SWITCH_STATUS_SUCCESS;
}
@ -4421,6 +4449,7 @@ static switch_status_t conf_api_sub_record(conference_obj_t *conference, switch_
static switch_status_t conf_api_sub_norecord(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv)
{
int all;
switch_event_t *event;
switch_assert(conference != NULL);
switch_assert(stream != NULL);
@ -4432,6 +4461,20 @@ static switch_status_t conf_api_sub_norecord(conference_obj_t *conference, switc
stream->write_function(stream, "Stop recording file %s\n", argv[2]);
if (!conference_record_stop(conference, all ? NULL : argv[2]) && !all) {
stream->write_function(stream, "non-existant recording '%s'\n", argv[2]);
} else {
if (all) {
conference->record_count = 0;
} else {
conference->record_count--;
}
if (test_eflag(conference, EFLAG_RECORD) &&
switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
conference_add_event_data(conference, event);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "stop-recording");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Path", all ? "all" : argv[2]);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Other-Recordings", conference->record_count ? "true" : "false");
switch_event_fire(&event);
}
}
return SWITCH_STATUS_SUCCESS;
@ -5138,6 +5181,8 @@ static void clear_eflags(char *events, uint32_t *f)
*f &= ~EFLAG_BGDIAL_RESULT;
} else if (!strcmp(event, "floor-change")) {
*f &= ~EFLAG_FLOOR_CHANGE;
} else if (!strcmp(event, "record")) {
*f &= ~EFLAG_RECORD;
}
event = next;
@ -6121,6 +6166,7 @@ static conference_obj_t *conference_new(char *name, conf_xml_cfg_t cfg, switch_m
conference->caller_id_name = switch_core_strdup(conference->pool, caller_id_name);
conference->caller_id_number = switch_core_strdup(conference->pool, caller_id_number);
conference->caller_controls = switch_core_strdup(conference->pool, caller_controls);
conference->run_time = switch_epoch_time_now(NULL);
if (!zstr(perpetual_sound)) {

View File

@ -1761,27 +1761,28 @@ static void *SWITCH_THREAD_FUNC node_thread_run(switch_thread_t *thread, void *o
for (hi = switch_hash_first(NULL, globals.fifo_hash); hi; hi = switch_hash_next(hi)) {
switch_hash_this(hi, &var, NULL, &val);
if ((node = (fifo_node_t *) val)) {
int x = 0;
switch_event_t *pop;
if (node->ready == FIFO_DELAY_DESTROY) {
int doit = 0;
switch_mutex_lock(node->update_mutex);
doit = node->consumer_count == 0 && node_caller_count(node) == 0;
switch_mutex_unlock(node->update_mutex);
if (doit) {
if (switch_thread_rwlock_trywrlock(node->rwlock) == SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "%s removed.\n", node->name);
switch_core_hash_delete(globals.fifo_hash, node->name);
for (x = 0; x < MAX_PRI; x++) {
while (fifo_queue_pop(node->fifo_list[x], &pop, 2) == SWITCH_STATUS_SUCCESS) {
switch_event_destroy(&pop);
}
}
node->ready = 0;
switch_mutex_lock(node->mutex);
switch_core_hash_destroy(&node->consumer_hash);
switch_mutex_unlock(node->mutex);
switch_mutex_unlock(node->update_mutex);
switch_thread_rwlock_unlock(node->rwlock);
switch_core_destroy_memory_pool(&node->pool);
goto restart;
}
}
@ -2172,7 +2173,7 @@ SWITCH_STANDARD_APP(fifo_function)
char *mydata = NULL, *argv[5] = { 0 };
fifo_node_t *node = NULL, *node_list[MAX_NODES_PER_CONSUMER + 1] = { 0 };
switch_channel_t *channel = switch_core_session_get_channel(session);
int do_wait = 1, node_count = 0, i = 0;
int do_destroy = 0, do_wait = 1, node_count = 0, i = 0;
const char *moh = NULL;
const char *announce = NULL;
switch_event_t *event = NULL;
@ -2247,13 +2248,10 @@ SWITCH_STANDARD_APP(fifo_function)
if (!(node = switch_core_hash_find(globals.fifo_hash, nlist[i]))) {
node = create_node(nlist[i], importance, globals.sql_mutex);
node->ready = 1;
switch_thread_rwlock_rdlock(node->rwlock);
}
node_list[node_count++] = node;
}
if (switch_true(switch_channel_get_variable(channel, "fifo_destroy_after_use")) && node->ready == 1) {
node->ready = FIFO_DELAY_DESTROY;
switch_thread_rwlock_rdlock(node->rwlock);
node_list[node_count++] = node;
}
switch_mutex_unlock(globals.mutex);
@ -3103,10 +3101,22 @@ SWITCH_STANDARD_APP(fifo_function)
done:
if (node) {
switch_thread_rwlock_unlock(node->rwlock);
if (switch_true(switch_channel_get_variable(channel, "fifo_destroy_after_use"))) {
do_destroy = 1;
}
switch_mutex_lock(globals.mutex);
for (i = 0; i < node_count; i++) {
if (!(node = node_list[i])) {
continue;
}
switch_thread_rwlock_unlock(node->rwlock);
if (node->ready == 1 && do_destroy) {
node->ready = FIFO_DELAY_DESTROY;
}
}
switch_mutex_unlock(globals.mutex);
switch_channel_clear_app_flag_key(FIFO_APP_KEY, channel, FIFO_APP_BRIDGE_TAG);
switch_core_media_bug_resume(session);

View File

@ -55,6 +55,7 @@ static void sync_sla(sofia_profile_t *profile, const char *to_user, const char *
struct dialog_helper {
char status[512];
char rpid[512];
char presence_id[1024];
};
struct resub_helper {
@ -479,9 +480,10 @@ static int sofia_presence_dialog_callback(void *pArg, int argc, char **argv, cha
{
struct dialog_helper *helper = (struct dialog_helper *) pArg;
if (argc == 2) {
if (argc == 3) {
switch_set_string(helper->status, argv[0]);
switch_set_string(helper->rpid, argv[1]);
switch_set_string(helper->presence_id, argv[2]);
}
return -1;
@ -638,7 +640,8 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
}
if (probe_euser && probe_host && (profile = sofia_glue_find_profile(probe_host))) {
sql = switch_mprintf("select status,rpid from sip_dialogs where ((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q')",
sql = switch_mprintf("select status,rpid,presence_id from sip_dialogs "
"where ((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q')",
probe_euser, probe_host, probe_euser, probe_host);
sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_presence_dialog_callback, &dh);
@ -656,16 +659,16 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
"sip_dialogs.direction, "
"sip_dialogs.sip_to_user, "
"sip_dialogs.sip_to_host, "
"sip_presence.status,"
"sip_presence.rpid,"
"sip_dialogs.presence_id, "
"sip_presence.open_closed,"
"'%q','%q' "
"from sip_registrations "
"from sip_registrations left join sip_dialogs on "
"left join sip_dialogs on "
"sip_dialogs.presence_id = sip_registrations.sip_user || '@' || sip_registrations.sip_host "
"or (sip_dialogs.sip_from_user = sip_registrations.sip_user "
"and sip_dialogs.sip_from_host = sip_registrations.sip_host) "
@ -813,7 +816,7 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
}
sql = switch_mprintf("select status,rpid from sip_dialogs where ((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q')",
sql = switch_mprintf("select status,rpid,presence_id from sip_dialogs where ((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q')",
euser, host, euser, host);
sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_presence_dialog_callback, &dh);
switch_safe_free(sql);
@ -824,25 +827,19 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
"sip_subscriptions.full_via,sip_subscriptions.expires,sip_subscriptions.user_agent,"
"sip_subscriptions.accept,sip_subscriptions.profile_name"
",'%q','%q','%q',sip_presence.status,sip_presence.rpid,sip_presence.open_closed,'%q','%q',"
"sip_subscriptions.version, sip_dialogs.presence_id "
"sip_subscriptions.version, '%q' "
"from sip_subscriptions "
"left join sip_presence on "
"(sip_subscriptions.sub_to_user=sip_presence.sip_user and sip_subscriptions.sub_to_host=sip_presence.sip_host and "
"sip_subscriptions.profile_name=sip_presence.profile_name) "
"left join sip_dialogs on "
"sip_dialogs.presence_id = sip_subscriptions.sub_to_user || '@' || sip_subscriptions.sub_to_host or "
"(sip_dialogs.sip_from_user = sip_subscriptions.sub_to_user "
"and sip_dialogs.sip_from_host = sip_subscriptions.sub_to_host) "
"where sip_subscriptions.expires > -1 and "
"(event='%q' or event='%q') and sub_to_user='%q' "
"and (sub_to_host='%q' or presence_hosts like '%%%q%%') "
"and (sip_subscriptions.profile_name = '%q' or sip_subscriptions.presence_hosts != sip_subscriptions.sub_to_host)",
switch_str_nil(status), switch_str_nil(rpid), host,
dh.status,dh.rpid,
"and (sip_subscriptions.profile_name = '%q' or sip_subscriptions.presence_hosts != sip_subscriptions.sub_to_host) ",
switch_str_nil(status), switch_str_nil(rpid), host,
dh.status,dh.rpid,dh.presence_id,
event_type, alt_event_type, euser, host, host, profile->name))) {
struct presence_helper helper = { 0 };

View File

@ -1052,8 +1052,6 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_signal_bridge(switch_core_session_t *
switch_channel_set_variable(caller_channel, "signal_bridge", "true");
switch_channel_set_variable(peer_channel, "signal_bridge", "true");
switch_channel_sort_cid(peer_channel, SWITCH_FALSE);
/* fire events that will change the data table from "show channels" */
if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_EXECUTE) == SWITCH_STATUS_SUCCESS) {
switch_channel_event_set_data(caller_channel, event);
@ -1119,8 +1117,6 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_multi_threaded_bridge(switch_core_ses
switch_channel_set_flag_recursive(caller_channel, CF_BRIDGE_ORIGINATOR);
switch_channel_clear_flag(peer_channel, CF_BRIDGE_ORIGINATOR);
switch_channel_sort_cid(peer_channel, SWITCH_FALSE);
b_leg->session = peer_session;
switch_copy_string(b_leg->b_uuid, switch_core_session_get_uuid(session), sizeof(b_leg->b_uuid));
b_leg->stream_id = stream_id;

View File

@ -2410,6 +2410,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
}
}
new_profile->callee_id_name = switch_core_strdup(new_profile->pool, "Outbound Call");
new_profile->callee_id_number = switch_core_strdup(new_profile->pool, new_profile->destination_number);
originate_status[i].caller_profile = NULL;
originate_status[i].peer_channel = NULL;
originate_status[i].peer_session = NULL;

View File

@ -120,8 +120,7 @@
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
<ImportLibrary>
</ImportLibrary>
<ImportLibrary>$(OutDir)FreeSwitchCore.lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
<ShowProgress>
</ShowProgress>