cleanup for mod_fax

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@9468 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale 2008-09-05 20:34:18 +00:00
parent a4c95c63f6
commit 07198a8416
6 changed files with 405 additions and 440 deletions

View File

@ -14,7 +14,7 @@
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is FreeSWITCH mod_timezone.
* The Original Code is FreeSWITCH mod_fax.
*
* The Initial Developer of the Original Code is
* Massimo Cetra <devel@navynet.it>
@ -27,7 +27,7 @@
* Brian West <brian@freeswitch.org>
* Anthony Minessale II <anthmct@yahoo.com>
* Steve Underwood <steveu@coppice.org>
*
* Antonio Gallo <agx@linux.it>
* mod_fax.c -- Fax applications provided by SpanDSP
*
*/
@ -99,7 +99,8 @@ typedef struct pvt_s pvt_t;
LOGGING AND HELPER FUNCTIONS
*****************************************************************************/
static void counter_increment( void ) {
static void counter_increment(void)
{
switch_mutex_lock(globals.mutex);
globals.total_sessions++;
switch_mutex_unlock(globals.mutex);
@ -109,8 +110,7 @@ static void spanfax_log_message(int level, const char *msg)
{
int fs_log_level;
switch (level)
{
switch (level) {
case SPAN_LOG_NONE:
return;
case SPAN_LOG_ERROR:
@ -129,9 +129,9 @@ static void spanfax_log_message(int level, const char *msg)
break;
}
if ( !switch_strlen_zero(msg) )
if (!switch_strlen_zero(msg)) {
switch_log_printf(SWITCH_CHANNEL_LOG, fs_log_level, "%s", msg);
}
}
/*
@ -144,9 +144,13 @@ static void phase_e_handler(t30_state_t *s, void *user_data, int result)
const char *far_ident;
switch_core_session_t *session;
switch_channel_t *chan;
pvt_t *pvt;
char *tmp;
session = ( switch_core_session_t* ) user_data;
pvt = (pvt_t *) user_data;
switch_assert(pvt);
session = pvt->session;
switch_assert(session);
chan = switch_core_session_get_channel(session);
@ -158,14 +162,19 @@ static void phase_e_handler(t30_state_t *s, void *user_data, int result)
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "==============================================================================\n");
if (result == T30_ERR_OK)
{
if (result == T30_ERR_OK) {
if (pvt->app_mode == FUNCTION_TX) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Fax successfully sent.\n");
switch_channel_set_variable(chan, "fax_success", "1");
} else if (pvt->app_mode == FUNCTION_RX) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Fax successfully received.\n");
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Fax successfully managed. How ?\n");
}
else
{
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Fax processing not successful - result (%d) %s.\n", result, t30_completion_code_to_str(result));
switch_channel_set_variable(chan, "fax_success", "1");
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Fax processing not successful - result (%d) %s.\n", result,
t30_completion_code_to_str(result));
switch_channel_set_variable(chan, "fax_success", "0");
}
@ -255,21 +264,18 @@ static switch_status_t spanfax_init( pvt_t *pvt, transport_mode_t trans_mode )
switch_assert(chan);
switch (trans_mode)
{
switch (trans_mode) {
case AUDIO_MODE:
if ( pvt->fax_state == NULL )
{
if (pvt->fax_state == NULL) {
pvt->fax_state = (fax_state_t *) switch_core_session_alloc(pvt->session, sizeof(fax_state_t));
}
else
} else {
return SWITCH_STATUS_FALSE;
}
fax = pvt->fax_state;
memset(fax, 0, sizeof(fax_state_t));
if ( fax_init(fax, pvt->caller) == NULL )
{
if (fax_init(fax, pvt->caller) == NULL) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot initialize my fax structs\n");
return SWITCH_STATUS_FALSE;
}
@ -279,8 +285,7 @@ static switch_status_t spanfax_init( pvt_t *pvt, transport_mode_t trans_mode )
span_log_set_message_handler(&fax->logging, spanfax_log_message);
span_log_set_message_handler(&fax->t30.logging, spanfax_log_message);
if( pvt->verbose )
{
if (pvt->verbose) {
span_log_set_level(&fax->logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
span_log_set_level(&fax->t30.logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
}
@ -288,7 +293,7 @@ static switch_status_t spanfax_init( pvt_t *pvt, transport_mode_t trans_mode )
t30_set_tx_ident(&fax->t30, pvt->ident);
t30_set_tx_page_header_info(&fax->t30, pvt->header);
t30_set_phase_e_handler(&fax->t30, phase_e_handler, pvt->session);
t30_set_phase_e_handler(&fax->t30, phase_e_handler, pvt);
t30_set_supported_image_sizes(&fax->t30,
T30_SUPPORT_US_LETTER_LENGTH | T30_SUPPORT_US_LEGAL_LENGTH | T30_SUPPORT_UNLIMITED_LENGTH
@ -298,8 +303,7 @@ static switch_status_t spanfax_init( pvt_t *pvt, transport_mode_t trans_mode )
| T30_SUPPORT_R8_RESOLUTION | T30_SUPPORT_R16_RESOLUTION);
if ( pvt->disable_v17 )
{
if (pvt->disable_v17) {
t30_set_supported_modems(&fax->t30, T30_SUPPORT_V29 | T30_SUPPORT_V27TER);
switch_channel_set_variable(chan, "fax_v17_disabled", "1");
} else {
@ -307,24 +311,18 @@ static switch_status_t spanfax_init( pvt_t *pvt, transport_mode_t trans_mode )
switch_channel_set_variable(chan, "fax_v17_disabled", "0");
}
if ( pvt->use_ecm )
{
if (pvt->use_ecm) {
t30_set_supported_compressions(&fax->t30, T30_SUPPORT_T4_1D_COMPRESSION | T30_SUPPORT_T4_2D_COMPRESSION | T30_SUPPORT_T6_COMPRESSION);
t30_set_ecm_capability(&fax->t30, TRUE);
switch_channel_set_variable(chan, "fax_ecm_requested", "1");
}
else
{
} else {
t30_set_supported_compressions(&fax->t30, T30_SUPPORT_T4_1D_COMPRESSION | T30_SUPPORT_T4_2D_COMPRESSION);
switch_channel_set_variable(chan, "fax_ecm_requested", "0");
}
if ( pvt->app_mode == FUNCTION_TX )
{
if (pvt->app_mode == FUNCTION_TX) {
t30_set_tx_file(&fax->t30, pvt->filename, pvt->tx_page_start, pvt->tx_page_end);
}
else
{
} else {
t30_set_rx_file(&fax->t30, pvt->filename, -1);
}
switch_channel_set_variable(chan, "fax_filename", pvt->filename);
@ -343,31 +341,34 @@ static switch_status_t spanfax_init( pvt_t *pvt, transport_mode_t trans_mode )
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t spanfax_destroy( pvt_t *pvt ) {
static switch_status_t spanfax_destroy(pvt_t * pvt)
{
int terminate;
if ( pvt->fax_state )
{
if ( pvt->t38_state )
if (pvt->fax_state) {
if (pvt->t38_state) {
terminate = 0;
else
} else {
terminate = 1;
}
if ( terminate && &pvt->fax_state->t30 )
if (terminate && &pvt->fax_state->t30) {
t30_terminate(&pvt->fax_state->t30);
}
fax_release(pvt->fax_state);
}
if ( pvt->t38_state )
{
if ( pvt->t38_state )
if (pvt->t38_state) {
if (pvt->t38_state) {
terminate = 1;
else
} else {
terminate = 0;
}
if ( terminate && &pvt->t38_state->t30 )
if (terminate && &pvt->t38_state->t30) {
t30_terminate(&pvt->t38_state->t30);
}
t38_terminal_release(pvt->t38_state);
}
@ -398,18 +399,19 @@ void process_fax(switch_core_session_t *session, const char *data, application_m
channel = switch_core_session_get_channel(session);
switch_assert(channel != NULL);
if (!switch_channel_media_ready(channel)) {
switch_channel_answer(channel);
}
/* Allocate our structs */
pvt = switch_core_session_alloc(session, sizeof(pvt_t));
counter_increment();
if ( !pvt )
{
if (!pvt) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot allocate application private data\n");
return;
}
else
{
} else {
memset(pvt, 0, sizeof(pvt_t));
pvt->session = session;
@ -418,13 +420,14 @@ void process_fax(switch_core_session_t *session, const char *data, application_m
pvt->tx_page_start = -1;
pvt->tx_page_end = -1;
if ( pvt->app_mode == FUNCTION_TX )
if (pvt->app_mode == FUNCTION_TX) {
pvt->caller = 1;
else if ( pvt->app_mode == FUNCTION_RX )
} else if (pvt->app_mode == FUNCTION_RX) {
pvt->caller = 0;
else
} else {
assert(0); /* UH ? */
}
}
buf = switch_core_session_alloc(session, SWITCH_RECOMMENDED_BUFFER_SIZE);
@ -434,55 +437,40 @@ void process_fax(switch_core_session_t *session, const char *data, application_m
}
/* Retrieving our settings from the channel variables */
if ((tmp = switch_channel_get_variable(channel, "fax_use_ecm"))) {
if ( switch_true(tmp) )
pvt->use_ecm = 1;
else
pvt->use_ecm = 0;
}
else
pvt->use_ecm = switch_true(tmp);
} else {
pvt->use_ecm = globals.use_ecm;
}
if ((tmp = switch_channel_get_variable(channel, "fax_disable_v17"))) {
if ( switch_true(tmp) )
pvt->disable_v17 = 1;
else
pvt->disable_v17 = 0;
}
else
pvt->disable_v17 = switch_true(tmp);
} else {
pvt->disable_v17 = globals.disable_v17;
}
if ((tmp = switch_channel_get_variable(channel, "fax_verbose"))) {
if ( switch_true(tmp) )
pvt->verbose = 1;
else
pvt->verbose = 0;
}
else
pvt->verbose = switch_true(tmp);
} else {
pvt->verbose = globals.verbose;
if ( (tmp=switch_channel_get_variable(channel, "fax_force_caller")) ) {
if ( switch_true(tmp) )
pvt->caller = 1;
else
pvt->caller = 0;
}
pvt->caller = switch_true(switch_channel_get_variable(channel, "fax_force_caller"));
if ((tmp = switch_channel_get_variable(channel, "fax_ident"))) {
pvt->ident = switch_core_session_strdup(session, tmp);
}
else
} else {
pvt->ident = switch_core_session_strdup(session, globals.ident);
}
if ((tmp = switch_channel_get_variable(channel, "fax_header"))) {
pvt->header = switch_core_session_strdup(session, tmp);
}
else
} else {
pvt->header = switch_core_session_strdup(session, globals.header);
}
if ( pvt->app_mode == FUNCTION_TX )
{
if (pvt->app_mode == FUNCTION_TX) {
if ((tmp = switch_channel_get_variable(channel, "fax_start_page"))) {
pvt->tx_page_start = atoi(tmp);
@ -492,13 +480,18 @@ void process_fax(switch_core_session_t *session, const char *data, application_m
pvt->tx_page_end = atoi(tmp);
}
if ( pvt->tx_page_end < -1 )
if (pvt->tx_page_end < -1) {
pvt->tx_page_end = -1;
if ( pvt->tx_page_start < -1 )
}
if (pvt->tx_page_start < -1) {
pvt->tx_page_start = -1;
if ( (pvt->tx_page_end < pvt->tx_page_start) && ( pvt->tx_page_end != -1 ) )
}
if ((pvt->tx_page_end < pvt->tx_page_start) && (pvt->tx_page_end != -1)) {
pvt->tx_page_end = pvt->tx_page_start;
}
}
if (!switch_strlen_zero(data)) {
pvt->filename = switch_core_session_strdup(session, data);
@ -508,14 +501,11 @@ void process_fax(switch_core_session_t *session, const char *data, application_m
goto done;
}
}
}
else {
} else {
if (pvt->app_mode == FUNCTION_TX) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Fax TX filename not set.\n");
goto done;
}
else if ( pvt->app_mode == FUNCTION_RX )
{
} else if (pvt->app_mode == FUNCTION_RX) {
char *fname;
char *prefix;
switch_time_t time;
@ -527,18 +517,14 @@ void process_fax(switch_core_session_t *session, const char *data, application_m
}
fname = switch_mprintf("%s/%s-%ld-%ld.tif", globals.spool, prefix, globals.total_sessions, time);
if ( fname )
{
if (fname) {
pvt->filename = switch_core_session_strdup(session, fname);
switch_safe_free(fname);
}
else
{
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot automagically set fax RX destination file\n");
goto done;
}
}
else {
} else {
assert(0); /* UH ?? */
}
}
@ -551,23 +537,24 @@ void process_fax(switch_core_session_t *session, const char *data, application_m
bypassing AUDIO_MODE.
*/
if ( (spanfax_init(pvt, AUDIO_MODE)!=SWITCH_STATUS_SUCCESS) )
{
if ((spanfax_init(pvt, AUDIO_MODE) != SWITCH_STATUS_SUCCESS)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot initialize Fax engine\n");
return;
}
/* Note: Disable echocan on the channel, it there is an API call to do that */
/*
Note: We should eventually disable JB before answering. JB is bad for faxing
switch_channel_set_variable(channel, "jitterbuffer_msec", "0" );
Note: Disable echocan on the channel, remember to call app "disable_ec" in the dialplan
before invoking fax applications
*/
/*
Note: we are disabling the Jitterbuffer, here, before we answer.
If you have set it to something else and the channel is pre-answered,
it will have no effect. Make sure that if you want more reliable
faxes, it is disabled.
*/
switch_channel_set_variable(channel, "jitterbuffer_msec", "0");
/* Finally answer the call */
switch_channel_answer(channel);
/* We store the original channel codec before switching both
* legs of the calls to a linear 16 bit codec that is the one
@ -576,56 +563,42 @@ void process_fax(switch_core_session_t *session, const char *data, application_m
*/
orig_read_codec = switch_core_session_get_read_codec(session);
if (switch_core_codec_init(
&read_codec,
if (switch_core_codec_init(&read_codec,
"L16",
NULL,
orig_read_codec->implementation->samples_per_second,
orig_read_codec->implementation->microseconds_per_frame / 1000,
1,
SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
NULL,
switch_core_session_get_pool(session)) == SWITCH_STATUS_SUCCESS
)
{
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Raw read codec activation Success L16\n");
NULL, switch_core_session_get_pool(session)) == SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Raw read codec activation Success L16 %u\n",
read_codec.implementation->microseconds_per_frame);
switch_core_session_set_read_codec(session, &read_codec);
}
else
{
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Raw read codec activation Failed L16\n");
goto done;
}
if (switch_core_codec_init(
&write_codec,
if (switch_core_codec_init(&write_codec,
"L16",
NULL,
orig_read_codec->implementation->samples_per_second,
orig_read_codec->implementation->microseconds_per_frame / 1000,
1,
SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
NULL,
switch_core_session_get_pool(session)) == SWITCH_STATUS_SUCCESS
)
{
NULL, switch_core_session_get_pool(session)) == SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Raw write codec activation Success L16\n");
write_frame.codec = &write_codec;
write_frame.data = buf;
write_frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE;
}
else
{
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Raw write codec activation Failed L16\n");
goto done;
}
switch_ivr_sleep(session, 250, NULL);
/*
* now we enter a loop where we read audio frames to the channels and will pass it to spandsp
*/
while( switch_channel_ready(channel) )
{
while (switch_channel_ready(channel)) {
int tx = 0;
switch_status_t status;
@ -643,56 +616,38 @@ void process_fax(switch_core_session_t *session, const char *data, application_m
/* read new audio frame from the channel */
status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
if ( !SWITCH_READ_ACCEPTABLE(status) )
{
if (!SWITCH_READ_ACCEPTABLE(status)) {
/* Our duty is over */
goto done;
}
/* Note: more analysys on this. RTP timing maybe inaccurate and, if so,
shoule be improved.
agx proposes to add a channel variable to disable this check and don't skip CNG frames
to improve the compatibility with the problems that another (??)famous pbx that
has always had serious problems with timers (or lack of).
*/
/* Skip CNG frames (autogenerated by FreeSWITCH, usually) */
if (switch_test_flag(read_frame, SFF_CNG)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Skipping CNG frame\n" );
continue;
}
if (!switch_test_flag(read_frame, SFF_CNG)) {
/* pass the new incoming audio frame to the fax_rx function */
if( fax_rx(pvt->fax_state, (int16_t *)read_frame->data, read_frame->samples) )
{
if (fax_rx(pvt->fax_state, (int16_t *) read_frame->data, read_frame->samples)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "fax_rx reported an error\n");
goto done;
}
}
if ( (tx = fax_tx(pvt->fax_state, buf, write_codec.implementation->samples_per_frame)) < 0)
{
if ((tx = fax_tx(pvt->fax_state, buf, write_codec.implementation->samples_per_frame)) < 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "fax_tx reported an error\n");
goto done;
}
if ( !tx )
{
if (!tx) {
/* switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "No audio samples to send\n"); */
continue;
}
else
{
} else {
/* Set our write_frame data */
write_frame.datalen = tx * sizeof(int16_t);
write_frame.samples = tx;
}
if ( switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS )
{
if (switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) {
/* something weird has happened */
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
"Cannot write frame [datalen: %d, samples: %d]\n",
write_frame.datalen, write_frame.samples );
"Cannot write frame [datalen: %d, samples: %d]\n", write_frame.datalen, write_frame.samples);
goto done;
}
@ -704,18 +659,15 @@ done:
/* restore the original codecs over the channel */
if ( read_codec.implementation )
{
if (read_codec.implementation) {
switch_core_codec_destroy(&read_codec);
}
if ( write_codec.implementation )
{
if (write_codec.implementation) {
switch_core_codec_destroy(&write_codec);
}
if ( orig_read_codec )
{
if (orig_read_codec) {
switch_core_session_set_read_codec(session, orig_read_codec);
}
@ -729,12 +681,9 @@ void load_configuration(switch_bool_t reload)
{
switch_xml_t xml = NULL, x_lists = NULL, x_list = NULL, cfg = NULL;
if ((xml = switch_xml_open_cfg("fax.conf", &cfg, NULL)))
{
if ((x_lists = switch_xml_child(cfg, "settings")))
{
for (x_list = switch_xml_child(x_lists, "param"); x_list; x_list = x_list->next)
{
if ((xml = switch_xml_open_cfg("fax.conf", &cfg, NULL))) {
if ((x_lists = switch_xml_child(cfg, "settings"))) {
for (x_list = switch_xml_child(x_lists, "param"); x_list; x_list = x_list->next) {
const char *name = switch_xml_attr(x_list, "name");
const char *value = switch_xml_attr(x_list, "value");
@ -751,32 +700,25 @@ void load_configuration(switch_bool_t reload)
globals.use_ecm = 1;
else
globals.use_ecm = 0;
}
else if ( !strcmp(name, "verbose" ) ) {
} else if (!strcmp(name, "verbose")) {
if (switch_true(value))
globals.verbose = 1;
else
globals.verbose = 0;
}
else if ( !strcmp(name, "disable-v17" ) ) {
} else if (!strcmp(name, "disable-v17")) {
if (switch_true(value))
globals.disable_v17 = 1;
else
globals.disable_v17 = 0;
}
else if ( !strcmp(name, "ident" ) ) {
} else if (!strcmp(name, "ident")) {
strncpy(globals.ident, value, sizeof(globals.ident) - 1);
}
else if ( !strcmp(name, "header" ) ) {
} else if (!strcmp(name, "header")) {
strncpy(globals.header, value, sizeof(globals.header) - 1);
}
else if ( !strcmp(name, "spool-dir" ) ) {
} else if (!strcmp(name, "spool-dir")) {
globals.spool = switch_core_strdup(globals.pool, value);
}
else if ( !strcmp(name, "file-prefix" ) ) {
} else if (!strcmp(name, "file-prefix")) {
globals.prepend_string = switch_core_strdup(globals.pool, value);
}
else {
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unknown parameter %s\n", name);
}
@ -821,8 +763,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_fax_init)
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
SWITCH_ADD_APP(app_interface, "rxfax", "FAX Receive Application", "FAX Receive Application", spanfax_rx_function, SPANFAX_RX_USAGE, SAF_NONE);
SWITCH_ADD_APP(app_interface, "txfax", "FAX Transmit Application", "FAX Transmit Application", spanfax_tx_function, SPANFAX_TX_USAGE, SAF_NONE);
SWITCH_ADD_APP(app_interface, "rxfax", "FAX Receive Application", "FAX Receive Application", spanfax_rx_function, SPANFAX_RX_USAGE, SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "txfax", "FAX Transmit Application", "FAX Transmit Application", spanfax_tx_function, SPANFAX_TX_USAGE, SAF_SUPPORT_NOMEDIA);
memset(&globals, 0, sizeof(globals));
switch_core_new_memory_pool(&globals.pool);
@ -839,13 +781,13 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_fax_init)
load_configuration(0);
if ( (switch_event_bind_removable(modname, SWITCH_EVENT_RELOADXML, NULL, event_handler, NULL, &NODE) != SWITCH_STATUS_SUCCESS) )
{
if ((switch_event_bind_removable(modname, SWITCH_EVENT_RELOADXML, NULL, event_handler, NULL, &NODE) != SWITCH_STATUS_SUCCESS)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind our reloadxml handler!\n");
/* Not such severe to prevent loading */
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "mod_fax loaded, using spandsp library version %d [%d]\n", SPANDSP_RELEASE_DATE, SPANDSP_RELEASE_TIME );
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "mod_fax loaded, using spandsp library version %d [%d]\n", SPANDSP_RELEASE_DATE,
SPANDSP_RELEASE_TIME);
return SWITCH_STATUS_SUCCESS;
}

View File

@ -190,7 +190,7 @@ typedef enum {
TFLAG_VAD_IN = (1 << 11),
TFLAG_VAD_OUT = (1 << 12),
TFLAG_VAD = (1 << 13),
TFLAG_TIMER = (1 << 14),
TFLAG_USE_ME = (1 << 14),
TFLAG_READY = (1 << 15),
TFLAG_REINVITE = (1 << 16),
TFLAG_REFER = (1 << 17),

View File

@ -1409,8 +1409,6 @@ switch_status_t config_sofia(int reload, char *profile_name)
if (!strcasecmp(var, "debug")) {
profile->debug = atoi(val);
} else if (!strcasecmp(var, "use-rtp-timer") && switch_true(val)) {
switch_set_flag(profile, TFLAG_TIMER);
} else if (!strcasecmp(var, "sip-trace") && switch_true(val)) {
switch_set_flag(profile, TFLAG_TPORT_LOG);
} else if (!strcasecmp(var, "odbc-dsn") && !switch_strlen_zero(val)) {
@ -1752,10 +1750,6 @@ switch_status_t config_sofia(int reload, char *profile_name)
profile->nonce_ttl = 60;
}
if (switch_test_flag(profile, TFLAG_TIMER) && !profile->timer_name) {
profile->timer_name = switch_core_strdup(profile->pool, "soft");
}
if (!profile->username) {
profile->username = switch_core_strdup(profile->pool, "FreeSWITCH");
}
@ -2381,7 +2375,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
if (tech_pvt && r_sdp) {
sdp_parser_t *parser;
sdp_session_t *sdp;
uint8_t match = 0;
uint8_t match = 0, is_ok = 1;
if (r_sdp) {
if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
@ -2412,6 +2406,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
switch_core_session_rwunlock(other_session);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Re-INVITE to a no-media channel that is not in a bridge.\n");
is_ok = 0;
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
}
goto done;
@ -2432,21 +2427,25 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
switch_set_flag_locked(tech_pvt, TFLAG_REINVITE);
if (sofia_glue_activate_rtp(tech_pvt, 0) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Reinvite RTP Error!\n");
is_ok = 0;
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Processing Reinvite\n");
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Reinvite Codec Error!\n");
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
is_ok = 0;
}
}
if (is_ok) {
nua_respond(tech_pvt->nh, SIP_200_OK,
SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
SOATAG_USER_SDP_STR(tech_pvt->local_sdp_str),
SOATAG_REUSE_REJECTED(1),
SOATAG_ORDERED_USER(1), SOATAG_AUDIO_AUX("cn telephone-event"), NUTAG_INCLUDE_EXTRA_SDP(1), TAG_END());
} else {
nua_respond(tech_pvt->nh, SIP_488_NOT_ACCEPTABLE, TAG_END());
}
}
}
break;

View File

@ -1676,7 +1676,7 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f
char tmp[50];
uint32_t rtp_timeout_sec = tech_pvt->profile->rtp_timeout_sec;
uint32_t rtp_hold_timeout_sec = tech_pvt->profile->rtp_hold_timeout_sec;
char *timer_name;
char *timer_name = NULL;
const char *var;
switch_assert(tech_pvt != NULL);
@ -1807,6 +1807,10 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f
timer_name = tech_pvt->profile->timer_name;
}
if ((var = switch_channel_get_variable(tech_pvt->channel, "rtp_timer_name"))) {
timer_name = (char *) var;
}
tech_pvt->rtp_session = switch_rtp_new(tech_pvt->local_sdp_audio_ip,
tech_pvt->local_sdp_audio_port,
tech_pvt->remote_sdp_audio_ip,

View File

@ -256,6 +256,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
session->raw_read_frame.ssrc = read_frame->ssrc;
session->raw_read_frame.seq = read_frame->seq;
session->raw_read_frame.m = read_frame->m;
session->raw_read_frame.flags = read_frame->flags;
session->raw_read_frame.payload = read_frame->payload;
read_frame = &session->raw_read_frame;
break;
@ -278,6 +279,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
session->raw_read_frame.ssrc = read_frame->ssrc;
session->raw_read_frame.seq = read_frame->seq;
session->raw_read_frame.m = read_frame->m;
session->raw_read_frame.flags = read_frame->flags;
session->raw_read_frame.payload = read_frame->payload;
read_frame = &session->raw_read_frame;
status = SWITCH_STATUS_SUCCESS;
@ -357,12 +359,13 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
}
if ((*frame)->datalen == session->read_codec->implementation->bytes_per_frame) {
if (read_frame->datalen == session->read_codec->implementation->bytes_per_frame) {
perfect = TRUE;
} else {
if (!session->raw_read_buffer) {
switch_size_t bytes = session->read_codec->implementation->bytes_per_frame;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Engaging Read Buffer at %u bytes\n", (uint32_t) bytes);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Engaging Read Buffer at %u bytes vs %u\n",
(uint32_t) bytes, (uint32_t) (*frame)->datalen);
switch_buffer_create_dynamic(&session->raw_read_buffer, bytes * SWITCH_BUFFER_BLOCK_FRAMES, bytes * SWITCH_BUFFER_START_FRAMES, 0);
}
if (!switch_buffer_write(session->raw_read_buffer, read_frame->data, read_frame->datalen)) {
@ -408,6 +411,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
session->enc_read_frame.ssrc = read_frame->ssrc;
session->enc_read_frame.seq = read_frame->seq;
session->enc_read_frame.m = read_frame->m;
session->enc_read_frame.flags = read_frame->flags;
session->enc_read_frame.payload = session->read_codec->implementation->ianacode;
}
*frame = &session->enc_read_frame;
@ -417,6 +421,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
session->raw_read_frame.timestamp = read_frame->timestamp;
session->raw_read_frame.payload = enc_frame->codec->implementation->ianacode;
session->raw_read_frame.m = read_frame->m;
session->enc_read_frame.flags = read_frame->flags;
session->raw_read_frame.ssrc = read_frame->ssrc;
session->raw_read_frame.seq = read_frame->seq;
*frame = &session->raw_read_frame;
@ -616,6 +621,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess
session->raw_write_frame.timestamp = frame->timestamp;
session->raw_write_frame.rate = frame->rate;
session->raw_write_frame.m = frame->m;
session->raw_write_frame.flags = frame->flags;
session->raw_write_frame.ssrc = frame->ssrc;
session->raw_write_frame.seq = frame->seq;
session->raw_write_frame.payload = frame->payload;
@ -768,6 +774,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess
session->enc_write_frame.timestamp = frame->timestamp;
session->enc_write_frame.payload = session->write_codec->implementation->ianacode;
session->enc_write_frame.m = frame->m;
session->enc_write_frame.flags = frame->flags;
session->enc_write_frame.ssrc = frame->ssrc;
session->enc_write_frame.seq = frame->seq;
write_frame = &session->enc_write_frame;
@ -777,6 +784,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess
enc_frame->samples = enc_frame->datalen / sizeof(int16_t);
enc_frame->timestamp = frame->timestamp;
enc_frame->m = frame->m;
enc_frame->flags = frame->flags;
enc_frame->seq = frame->seq;
enc_frame->ssrc = frame->ssrc;
enc_frame->payload = enc_frame->codec->implementation->ianacode;
@ -830,6 +838,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess
session->enc_write_frame.codec = session->write_codec;
session->enc_write_frame.samples = enc_frame->datalen / sizeof(int16_t);
session->enc_write_frame.m = frame->m;
session->enc_write_frame.flags = frame->flags;
session->enc_write_frame.ssrc = frame->ssrc;
session->enc_write_frame.payload = session->write_codec->implementation->ianacode;
write_frame = &session->enc_write_frame;
@ -851,6 +860,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess
session->enc_write_frame.codec = session->write_codec;
session->enc_write_frame.samples = enc_frame->datalen / sizeof(int16_t);
session->enc_write_frame.m = frame->m;
session->enc_write_frame.flags = frame->flags;
session->enc_write_frame.ssrc = frame->ssrc;
session->enc_write_frame.payload = session->write_codec->implementation->ianacode;
write_frame = &session->enc_write_frame;
@ -865,6 +875,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess
enc_frame->codec = session->write_codec;
enc_frame->samples = enc_frame->datalen / sizeof(int16_t);
enc_frame->m = frame->m;
enc_frame->flags = frame->flags;
enc_frame->ssrc = frame->ssrc;
enc_frame->payload = enc_frame->codec->implementation->ianacode;
write_frame = enc_frame;

View File

@ -797,11 +797,16 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_create(switch_rtp_t **new_rtp_session
rtp_session->payload = payload;
rtp_session->ms_per_packet = ms_per_packet;
rtp_session->samples_per_interval = rtp_session->conf_samples_per_interval = samples_per_interval;
rtp_session->timer_name = switch_core_strdup(pool, timer_name);
if (!strcasecmp(timer_name, "none")) {
timer_name = NULL;
}
if (!switch_strlen_zero(timer_name)) {
rtp_session->timer_name = switch_core_strdup(pool, timer_name);
switch_set_flag_locked(rtp_session, SWITCH_RTP_FLAG_USE_TIMER);
switch_clear_flag(rtp_session, SWITCH_RTP_FLAG_USE_TIMER);
switch_clear_flag(rtp_session, SWITCH_RTP_FLAG_NOBLOCK);
}
if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_USE_TIMER) && switch_strlen_zero(timer_name)) {
@ -1238,6 +1243,10 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
goto end;
}
if (bytes == 1) {
continue;
}
if (bytes && switch_test_flag(rtp_session, SWITCH_RTP_FLAG_AUTOADJ) && switch_sockaddr_get_port(rtp_session->from_addr)) {
const char *tx_host;
const char *old_host;