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 * for the specific language governing rights and limitations under the
* License. * License.
* *
* The Original Code is FreeSWITCH mod_timezone. * The Original Code is FreeSWITCH mod_fax.
* *
* The Initial Developer of the Original Code is * The Initial Developer of the Original Code is
* Massimo Cetra <devel@navynet.it> * Massimo Cetra <devel@navynet.it>
@ -27,7 +27,7 @@
* Brian West <brian@freeswitch.org> * Brian West <brian@freeswitch.org>
* Anthony Minessale II <anthmct@yahoo.com> * Anthony Minessale II <anthmct@yahoo.com>
* Steve Underwood <steveu@coppice.org> * Steve Underwood <steveu@coppice.org>
* * Antonio Gallo <agx@linux.it>
* mod_fax.c -- Fax applications provided by SpanDSP * mod_fax.c -- Fax applications provided by SpanDSP
* *
*/ */
@ -38,7 +38,7 @@
/***************************************************************************** /*****************************************************************************
OUR DEFINES AND STRUCTS OUR DEFINES AND STRUCTS
*****************************************************************************/ *****************************************************************************/
typedef enum { typedef enum {
FUNCTION_TX, FUNCTION_TX,
@ -97,9 +97,10 @@ typedef struct pvt_s pvt_t;
/***************************************************************************** /*****************************************************************************
LOGGING AND HELPER FUNCTIONS LOGGING AND HELPER FUNCTIONS
*****************************************************************************/ *****************************************************************************/
static void counter_increment( void ) { static void counter_increment(void)
{
switch_mutex_lock(globals.mutex); switch_mutex_lock(globals.mutex);
globals.total_sessions++; globals.total_sessions++;
switch_mutex_unlock(globals.mutex); switch_mutex_unlock(globals.mutex);
@ -109,8 +110,7 @@ static void spanfax_log_message(int level, const char *msg)
{ {
int fs_log_level; int fs_log_level;
switch (level) switch (level) {
{
case SPAN_LOG_NONE: case SPAN_LOG_NONE:
return; return;
case SPAN_LOG_ERROR: case SPAN_LOG_ERROR:
@ -129,57 +129,66 @@ static void spanfax_log_message(int level, const char *msg)
break; break;
} }
if ( !switch_strlen_zero(msg) ) if (!switch_strlen_zero(msg)) {
switch_log_printf(SWITCH_CHANNEL_LOG, fs_log_level, "%s", msg ); switch_log_printf(SWITCH_CHANNEL_LOG, fs_log_level, "%s", msg);
}
} }
/* /*
* Called at the end of the document * Called at the end of the document
*/ */
static void phase_e_handler(t30_state_t *s, void *user_data, int result) static void phase_e_handler(t30_state_t * s, void *user_data, int result)
{ {
t30_stats_t t; t30_stats_t t;
const char *local_ident; const char *local_ident;
const char *far_ident; const char *far_ident;
switch_core_session_t *session; switch_core_session_t *session;
switch_channel_t *chan; switch_channel_t *chan;
pvt_t *pvt;
char *tmp; char *tmp;
session = ( switch_core_session_t* ) user_data; pvt = (pvt_t *) user_data;
switch_assert(pvt);
session = pvt->session;
switch_assert(session); switch_assert(session);
chan = switch_core_session_get_channel(session); chan = switch_core_session_get_channel(session);
switch_assert(chan); switch_assert(chan);
t30_get_transfer_statistics(s, &t); t30_get_transfer_statistics(s, &t);
local_ident = switch_str_nil( t30_get_tx_ident(s) ); local_ident = switch_str_nil(t30_get_tx_ident(s));
far_ident = switch_str_nil( t30_get_rx_ident(s) ); far_ident = switch_str_nil(t30_get_rx_ident(s));
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "==============================================================================\n"); 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_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_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_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"); switch_channel_set_variable(chan, "fax_success", "0");
} }
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Remote station id: %s\n", far_ident ); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Remote station id: %s\n", far_ident);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Local station id: %s\n", local_ident ); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Local station id: %s\n", local_ident);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Pages transferred: %i\n", t.pages_transferred); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Pages transferred: %i\n", t.pages_transferred);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Total fax pages: %i\n", t.pages_in_file); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Total fax pages: %i\n", t.pages_in_file);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Image resolution: %ix%i\n", t.x_resolution, t.y_resolution); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Image resolution: %ix%i\n", t.x_resolution, t.y_resolution);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Transfer Rate: %i\n", t.bit_rate); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Transfer Rate: %i\n", t.bit_rate);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "ECM status %s\n", (t.error_correcting_mode) ? "on" : "off"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "ECM status %s\n", (t.error_correcting_mode) ? "on" : "off");
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "remote country: %s\n", switch_str_nil( t30_get_rx_country(s)) ); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "remote country: %s\n", switch_str_nil(t30_get_rx_country(s)));
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "remote vendor: %s\n", switch_str_nil( t30_get_rx_vendor(s)) ); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "remote vendor: %s\n", switch_str_nil(t30_get_rx_vendor(s)));
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "remote model: %s\n", switch_str_nil( t30_get_rx_model(s)) ); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "remote model: %s\n", switch_str_nil(t30_get_rx_model(s)));
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "==============================================================================\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "==============================================================================\n");
@ -188,50 +197,50 @@ static void phase_e_handler(t30_state_t *s, void *user_data, int result)
*/ */
tmp = switch_mprintf("%i", result); tmp = switch_mprintf("%i", result);
if ( tmp ) { if (tmp) {
switch_channel_set_variable(chan, "fax_result_code", tmp ); switch_channel_set_variable(chan, "fax_result_code", tmp);
switch_safe_free(tmp); switch_safe_free(tmp);
} }
switch_channel_set_variable(chan, "fax_result_text", t30_completion_code_to_str(result) ); switch_channel_set_variable(chan, "fax_result_text", t30_completion_code_to_str(result));
switch_channel_set_variable(chan, "fax_ecm_used", (t.error_correcting_mode) ? "on" : "off" ); switch_channel_set_variable(chan, "fax_ecm_used", (t.error_correcting_mode) ? "on" : "off");
switch_channel_set_variable(chan, "fax_local_station_id", local_ident ); switch_channel_set_variable(chan, "fax_local_station_id", local_ident);
switch_channel_set_variable(chan, "fax_remote_station_id", far_ident ); switch_channel_set_variable(chan, "fax_remote_station_id", far_ident);
tmp = switch_mprintf("%i", t.pages_transferred); tmp = switch_mprintf("%i", t.pages_transferred);
if ( tmp ) { if (tmp) {
switch_channel_set_variable(chan, "fax_document_transferred_pages", tmp); switch_channel_set_variable(chan, "fax_document_transferred_pages", tmp);
switch_safe_free(tmp); switch_safe_free(tmp);
} }
tmp = switch_mprintf("%i", t.pages_in_file); tmp = switch_mprintf("%i", t.pages_in_file);
if ( tmp ) { if (tmp) {
switch_channel_set_variable(chan, "fax_document_total_pages", tmp ); switch_channel_set_variable(chan, "fax_document_total_pages", tmp);
switch_safe_free(tmp); switch_safe_free(tmp);
} }
tmp = switch_mprintf("%ix%i", t.x_resolution, t.y_resolution); tmp = switch_mprintf("%ix%i", t.x_resolution, t.y_resolution);
if ( tmp ) { if (tmp) {
switch_channel_set_variable(chan, "fax_image_resolution", tmp ); switch_channel_set_variable(chan, "fax_image_resolution", tmp);
switch_safe_free(tmp); switch_safe_free(tmp);
} }
tmp = switch_mprintf("%d", t.image_size); tmp = switch_mprintf("%d", t.image_size);
if ( tmp ) { if (tmp) {
switch_channel_set_variable(chan, "fax_image_size", tmp ); switch_channel_set_variable(chan, "fax_image_size", tmp);
switch_safe_free(tmp); switch_safe_free(tmp);
} }
tmp = switch_mprintf("%d", t.bad_rows); tmp = switch_mprintf("%d", t.bad_rows);
if ( tmp ) { if (tmp) {
switch_channel_set_variable(chan, "fax_bad_rows", tmp ); switch_channel_set_variable(chan, "fax_bad_rows", tmp);
switch_safe_free(tmp); switch_safe_free(tmp);
} }
tmp = switch_mprintf("%i", t.bit_rate); tmp = switch_mprintf("%i", t.bit_rate);
if ( tmp ) { if (tmp) {
switch_channel_set_variable(chan, "fax_transfer_rate", tmp ); switch_channel_set_variable(chan, "fax_transfer_rate", tmp);
switch_safe_free(tmp); switch_safe_free(tmp);
} }
@ -241,35 +250,32 @@ static void phase_e_handler(t30_state_t *s, void *user_data, int result)
} }
static switch_status_t spanfax_init( pvt_t *pvt, transport_mode_t trans_mode ) static switch_status_t spanfax_init(pvt_t * pvt, transport_mode_t trans_mode)
{ {
switch_core_session_t *session; switch_core_session_t *session;
switch_channel_t *chan; switch_channel_t *chan;
fax_state_t *fax; fax_state_t *fax;
session = ( switch_core_session_t* ) pvt->session; session = (switch_core_session_t *) pvt->session;
switch_assert(session); switch_assert(session);
chan = switch_core_session_get_channel(session); chan = switch_core_session_get_channel(session);
switch_assert(chan); switch_assert(chan);
switch (trans_mode) switch (trans_mode) {
{
case AUDIO_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));
pvt->fax_state = (fax_state_t *) switch_core_session_alloc( pvt->session, sizeof(fax_state_t) ); } else {
}
else
return SWITCH_STATUS_FALSE; return SWITCH_STATUS_FALSE;
}
fax = pvt->fax_state; fax = pvt->fax_state;
memset(fax, 0, sizeof(fax_state_t)); 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"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot initialize my fax structs\n");
return SWITCH_STATUS_FALSE; return SWITCH_STATUS_FALSE;
} }
@ -279,16 +285,15 @@ 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->logging, spanfax_log_message);
span_log_set_message_handler(&fax->t30.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->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); span_log_set_level(&fax->t30.logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
} }
t30_set_tx_ident(&fax->t30, pvt->ident ); t30_set_tx_ident(&fax->t30, pvt->ident);
t30_set_tx_page_header_info(&fax->t30, pvt->header ); 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_set_supported_image_sizes(&fax->t30,
T30_SUPPORT_US_LETTER_LENGTH | T30_SUPPORT_US_LEGAL_LENGTH | T30_SUPPORT_UNLIMITED_LENGTH T30_SUPPORT_US_LETTER_LENGTH | T30_SUPPORT_US_LEGAL_LENGTH | T30_SUPPORT_UNLIMITED_LENGTH
@ -298,33 +303,26 @@ static switch_status_t spanfax_init( pvt_t *pvt, transport_mode_t trans_mode )
| T30_SUPPORT_R8_RESOLUTION | T30_SUPPORT_R16_RESOLUTION); | 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); t30_set_supported_modems(&fax->t30, T30_SUPPORT_V29 | T30_SUPPORT_V27TER);
switch_channel_set_variable(chan, "fax_v17_disabled", "1"); switch_channel_set_variable(chan, "fax_v17_disabled", "1");
} else { } else {
t30_set_supported_modems(&fax->t30, T30_SUPPORT_V29 | T30_SUPPORT_V27TER | T30_SUPPORT_V17 ); t30_set_supported_modems(&fax->t30, T30_SUPPORT_V29 | T30_SUPPORT_V27TER | T30_SUPPORT_V17);
switch_channel_set_variable(chan, "fax_v17_disabled", "0"); 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_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); t30_set_ecm_capability(&fax->t30, TRUE);
switch_channel_set_variable(chan, "fax_ecm_requested", "1"); 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);
{
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"); 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); 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); t30_set_rx_file(&fax->t30, pvt->filename, -1);
} }
switch_channel_set_variable(chan, "fax_filename", pvt->filename); 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; return SWITCH_STATUS_SUCCESS;
} }
static switch_status_t spanfax_destroy( pvt_t *pvt ) { static switch_status_t spanfax_destroy(pvt_t * pvt)
{
int terminate; int terminate;
if ( pvt->fax_state ) if (pvt->fax_state) {
{ if (pvt->t38_state) {
if ( pvt->t38_state )
terminate = 0; terminate = 0;
else } else {
terminate = 1; terminate = 1;
}
if ( terminate && &pvt->fax_state->t30 ) if (terminate && &pvt->fax_state->t30) {
t30_terminate(&pvt->fax_state->t30); t30_terminate(&pvt->fax_state->t30);
}
fax_release(pvt->fax_state); fax_release(pvt->fax_state);
} }
if ( pvt->t38_state ) if (pvt->t38_state) {
{ if (pvt->t38_state) {
if ( pvt->t38_state )
terminate = 1; terminate = 1;
else } else {
terminate = 0; terminate = 0;
}
if ( terminate && &pvt->t38_state->t30 ) if (terminate && &pvt->t38_state->t30) {
t30_terminate(&pvt->t38_state->t30); t30_terminate(&pvt->t38_state->t30);
}
t38_terminal_release(pvt->t38_state); t38_terminal_release(pvt->t38_state);
} }
@ -377,7 +378,7 @@ static switch_status_t spanfax_destroy( pvt_t *pvt ) {
/***************************************************************************** /*****************************************************************************
MAIN FAX PROCESSING MAIN FAX PROCESSING
*****************************************************************************/ *****************************************************************************/
void process_fax(switch_core_session_t *session, const char *data, application_mode_t app_mode) void process_fax(switch_core_session_t *session, const char *data, application_mode_t app_mode)
{ {
@ -387,10 +388,10 @@ void process_fax(switch_core_session_t *session, const char *data, application_m
switch_channel_t *channel; switch_channel_t *channel;
switch_codec_t *orig_read_codec = NULL; switch_codec_t *orig_read_codec = NULL;
switch_codec_t read_codec = {0}; switch_codec_t read_codec = { 0 };
switch_codec_t write_codec = {0}; switch_codec_t write_codec = { 0 };
switch_frame_t *read_frame = {0}; switch_frame_t *read_frame = { 0 };
switch_frame_t write_frame = {0}; switch_frame_t write_frame = { 0 };
int16_t *buf = NULL; int16_t *buf = NULL;
@ -398,19 +399,20 @@ void process_fax(switch_core_session_t *session, const char *data, application_m
channel = switch_core_session_get_channel(session); channel = switch_core_session_get_channel(session);
switch_assert(channel != NULL); switch_assert(channel != NULL);
if (!switch_channel_media_ready(channel)) {
switch_channel_answer(channel);
}
/* Allocate our structs */ /* Allocate our structs */
pvt = switch_core_session_alloc(session, sizeof(pvt_t)); pvt = switch_core_session_alloc(session, sizeof(pvt_t));
counter_increment(); counter_increment();
if ( !pvt ) if (!pvt) {
{
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot allocate application private data\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot allocate application private data\n");
return; return;
} } else {
else memset(pvt, 0, sizeof(pvt_t));
{
memset( pvt, 0, sizeof(pvt_t) );
pvt->session = session; pvt->session = session;
pvt->app_mode = app_mode; pvt->app_mode = app_mode;
@ -418,127 +420,111 @@ void process_fax(switch_core_session_t *session, const char *data, application_m
pvt->tx_page_start = -1; pvt->tx_page_start = -1;
pvt->tx_page_end = -1; pvt->tx_page_end = -1;
if ( pvt->app_mode == FUNCTION_TX ) if (pvt->app_mode == FUNCTION_TX) {
pvt->caller = 1; pvt->caller = 1;
else if ( pvt->app_mode == FUNCTION_RX ) } else if (pvt->app_mode == FUNCTION_RX) {
pvt->caller = 0; pvt->caller = 0;
else } else {
assert(0); /* UH ? */ assert(0); /* UH ? */
} }
}
buf = switch_core_session_alloc(session, SWITCH_RECOMMENDED_BUFFER_SIZE); buf = switch_core_session_alloc(session, SWITCH_RECOMMENDED_BUFFER_SIZE);
if ( !buf ) { if (!buf) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot allocate application buffer data\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot allocate application buffer data\n");
return; return;
} }
/* Retrieving our settings from the channel variables */ /* Retrieving our settings from the channel variables */
if ( (tmp=switch_channel_get_variable(channel, "fax_use_ecm")) ) {
if ( switch_true(tmp) ) if ((tmp = switch_channel_get_variable(channel, "fax_use_ecm"))) {
pvt->use_ecm = 1; pvt->use_ecm = switch_true(tmp);
else } else {
pvt->use_ecm = 0;
}
else
pvt->use_ecm = globals.use_ecm; 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
if ((tmp = switch_channel_get_variable(channel, "fax_disable_v17"))) {
pvt->disable_v17 = switch_true(tmp);
} else {
pvt->disable_v17 = globals.disable_v17; 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
if ((tmp = switch_channel_get_variable(channel, "fax_verbose"))) {
pvt->verbose = switch_true(tmp);
} else {
pvt->verbose = globals.verbose; 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;
} }
if ( (tmp=switch_channel_get_variable(channel, "fax_ident")) ) { 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); pvt->ident = switch_core_session_strdup(session, tmp);
} } else {
else
pvt->ident = switch_core_session_strdup(session, globals.ident); 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
if ((tmp = switch_channel_get_variable(channel, "fax_header"))) {
pvt->header = switch_core_session_strdup(session, tmp);
} else {
pvt->header = switch_core_session_strdup(session, globals.header); 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"))) {
{
if ( (tmp=switch_channel_get_variable(channel, "fax_start_page")) ) {
pvt->tx_page_start = atoi(tmp); pvt->tx_page_start = atoi(tmp);
} }
if ( (tmp=switch_channel_get_variable(channel, "fax_end_page")) ) { if ((tmp = switch_channel_get_variable(channel, "fax_end_page"))) {
pvt->tx_page_end = atoi(tmp); pvt->tx_page_end = atoi(tmp);
} }
if ( pvt->tx_page_end < -1 ) if (pvt->tx_page_end < -1) {
pvt->tx_page_end = -1; pvt->tx_page_end = -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 ) )
pvt->tx_page_end = pvt->tx_page_start;
} }
if ( !switch_strlen_zero(data) ) { 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)) {
pvt->tx_page_end = pvt->tx_page_start;
}
}
if (!switch_strlen_zero(data)) {
pvt->filename = switch_core_session_strdup(session, data); pvt->filename = switch_core_session_strdup(session, data);
if ( pvt->app_mode == FUNCTION_TX ) { if (pvt->app_mode == FUNCTION_TX) {
if ( (switch_file_exists( pvt->filename, switch_core_session_get_pool(session) )!=SWITCH_STATUS_SUCCESS) ) { if ((switch_file_exists(pvt->filename, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot send inexistant fax file [%s]\n", switch_str_nil(pvt->filename) ); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot send inexistant fax file [%s]\n", switch_str_nil(pvt->filename));
goto done; goto done;
} }
} }
} } else {
else { if (pvt->app_mode == FUNCTION_TX) {
if ( pvt->app_mode == FUNCTION_TX ) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Fax TX filename not set.\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Fax TX filename not set.\n");
goto done; goto done;
} } else if (pvt->app_mode == FUNCTION_RX) {
else if ( pvt->app_mode == FUNCTION_RX )
{
char *fname; char *fname;
char *prefix; char *prefix;
switch_time_t time; switch_time_t time;
time = switch_time_now(); time = switch_time_now();
if ( !(prefix=switch_channel_get_variable(channel, "fax_prefix")) ) { if (!(prefix = switch_channel_get_variable(channel, "fax_prefix"))) {
prefix = globals.prepend_string; prefix = globals.prepend_string;
} }
fname = switch_mprintf("%s/%s-%ld-%ld.tif", globals.spool, prefix, globals.total_sessions, time); 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); pvt->filename = switch_core_session_strdup(session, fname);
switch_safe_free(fname); switch_safe_free(fname);
} } else {
else
{
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot automagically set fax RX destination file\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot automagically set fax RX destination file\n");
goto done; goto done;
} }
} } else {
else {
assert(0); /* UH ?? */ assert(0); /* UH ?? */
} }
} }
@ -551,23 +537,24 @@ void process_fax(switch_core_session_t *session, const char *data, application_m
bypassing AUDIO_MODE. 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"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot initialize Fax engine\n");
return; 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 Note: Disable echocan on the channel, remember to call app "disable_ec" in the dialplan
before invoking fax applications
switch_channel_set_variable(channel, "jitterbuffer_msec", "0" );
*/ */
/*
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 /* We store the original channel codec before switching both
* legs of the calls to a linear 16 bit codec that is the one * 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); orig_read_codec = switch_core_session_get_read_codec(session);
if (switch_core_codec_init( if (switch_core_codec_init(&read_codec,
&read_codec,
"L16", "L16",
NULL, NULL,
orig_read_codec->implementation->samples_per_second, orig_read_codec->implementation->samples_per_second,
orig_read_codec->implementation->microseconds_per_frame / 1000, orig_read_codec->implementation->microseconds_per_frame / 1000,
1, 1,
SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
NULL, NULL, switch_core_session_get_pool(session)) == SWITCH_STATUS_SUCCESS) {
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_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Raw read codec activation Success L16\n");
switch_core_session_set_read_codec(session, &read_codec); 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"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Raw read codec activation Failed L16\n");
goto done; goto done;
} }
if (switch_core_codec_init( if (switch_core_codec_init(&write_codec,
&write_codec,
"L16", "L16",
NULL, NULL,
orig_read_codec->implementation->samples_per_second, orig_read_codec->implementation->samples_per_second,
orig_read_codec->implementation->microseconds_per_frame / 1000, orig_read_codec->implementation->microseconds_per_frame / 1000,
1, 1,
SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
NULL, NULL, switch_core_session_get_pool(session)) == SWITCH_STATUS_SUCCESS) {
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"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Raw write codec activation Success L16\n");
write_frame.codec = &write_codec; write_frame.codec = &write_codec;
write_frame.data = buf; write_frame.data = buf;
write_frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE; 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"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Raw write codec activation Failed L16\n");
goto done; goto done;
} }
switch_ivr_sleep(session, 250, NULL);
/* while (switch_channel_ready(channel)) {
* now we enter a loop where we read audio frames to the channels and will pass it to spandsp
*/
while( switch_channel_ready(channel) )
{
int tx = 0; int tx = 0;
switch_status_t status; switch_status_t status;
@ -643,79 +616,58 @@ void process_fax(switch_core_session_t *session, const char *data, application_m
/* read new audio frame from the channel */ /* read new audio frame from the channel */
status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0); 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 */ /* Our duty is over */
goto done; 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) */ /* Skip CNG frames (autogenerated by FreeSWITCH, usually) */
if (switch_test_flag(read_frame, SFF_CNG)) { if (!switch_test_flag(read_frame, SFF_CNG)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Skipping CNG frame\n" );
continue;
}
/* pass the new incoming audio frame to the fax_rx function */ /* 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");
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "fax_rx reported an error\n" );
goto done; 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"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "fax_tx reported an error\n");
goto done; goto done;
} }
if ( !tx ) if (!tx) {
{
/* switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "No audio samples to send\n"); */ /* switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "No audio samples to send\n"); */
continue; continue;
} } else {
else
{
/* Set our write_frame data */ /* Set our write_frame data */
write_frame.datalen = tx * sizeof(int16_t); write_frame.datalen = tx * sizeof(int16_t);
write_frame.samples = tx; 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 */ /* something weird has happened */
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
"Cannot write frame [datalen: %d, samples: %d]\n", "Cannot write frame [datalen: %d, samples: %d]\n", write_frame.datalen, write_frame.samples);
write_frame.datalen, write_frame.samples );
goto done; goto done;
} }
} }
done: done:
/* Destroy the SpanDSP structures */ /* Destroy the SpanDSP structures */
spanfax_destroy( pvt ); spanfax_destroy(pvt);
/* restore the original codecs over the channel */ /* restore the original codecs over the channel */
if ( read_codec.implementation ) if (read_codec.implementation) {
{
switch_core_codec_destroy(&read_codec); switch_core_codec_destroy(&read_codec);
} }
if ( write_codec.implementation ) if (write_codec.implementation) {
{
switch_core_codec_destroy(&write_codec); switch_core_codec_destroy(&write_codec);
} }
if ( orig_read_codec ) if (orig_read_codec) {
{
switch_core_session_set_read_codec(session, orig_read_codec); switch_core_session_set_read_codec(session, orig_read_codec);
} }
@ -729,14 +681,11 @@ void load_configuration(switch_bool_t reload)
{ {
switch_xml_t xml = NULL, x_lists = NULL, x_list = NULL, cfg = NULL; switch_xml_t xml = NULL, x_lists = NULL, x_list = NULL, cfg = NULL;
if ((xml = switch_xml_open_cfg("fax.conf", &cfg, NULL))) if ((xml = switch_xml_open_cfg("fax.conf", &cfg, NULL))) {
{ if ((x_lists = switch_xml_child(cfg, "settings"))) {
if ((x_lists = switch_xml_child(cfg, "settings"))) for (x_list = switch_xml_child(x_lists, "param"); x_list; x_list = x_list->next) {
{
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 *name = switch_xml_attr(x_list, "name");
const char *value= switch_xml_attr(x_list, "value"); const char *value = switch_xml_attr(x_list, "value");
if (switch_strlen_zero(name)) { if (switch_strlen_zero(name)) {
continue; continue;
@ -746,38 +695,31 @@ void load_configuration(switch_bool_t reload)
continue; continue;
} }
if ( !strcmp(name, "use-ecm" ) ) { if (!strcmp(name, "use-ecm")) {
if ( switch_true(value) ) if (switch_true(value))
globals.use_ecm = 1; globals.use_ecm = 1;
else else
globals.use_ecm = 0; globals.use_ecm = 0;
} } else if (!strcmp(name, "verbose")) {
else if ( !strcmp(name, "verbose" ) ) { if (switch_true(value))
if ( switch_true(value) )
globals.verbose = 1; globals.verbose = 1;
else else
globals.verbose = 0; globals.verbose = 0;
} } else if (!strcmp(name, "disable-v17")) {
else if ( !strcmp(name, "disable-v17" ) ) { if (switch_true(value))
if ( switch_true(value) )
globals.disable_v17 = 1; globals.disable_v17 = 1;
else else
globals.disable_v17 = 0; globals.disable_v17 = 0;
} } else if (!strcmp(name, "ident")) {
else if ( !strcmp(name, "ident" ) ) { strncpy(globals.ident, value, sizeof(globals.ident) - 1);
strncpy(globals.ident, value, sizeof(globals.ident)-1 ); } else if (!strcmp(name, "header")) {
} strncpy(globals.header, value, sizeof(globals.header) - 1);
else if ( !strcmp(name, "header" ) ) { } else if (!strcmp(name, "spool-dir")) {
strncpy(globals.header, value, sizeof(globals.header)-1 );
}
else if ( !strcmp(name, "spool-dir" ) ) {
globals.spool = switch_core_strdup(globals.pool, value); 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); 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);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unknown parameter %s\n", name );
} }
} }
@ -821,10 +763,10 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_fax_init)
*module_interface = switch_loadable_module_create_module_interface(pool, modname); *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, "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_NONE); 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) ); memset(&globals, 0, sizeof(globals));
switch_core_new_memory_pool(&globals.pool); switch_core_new_memory_pool(&globals.pool);
switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, globals.pool); switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, globals.pool);
@ -834,18 +776,18 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_fax_init)
globals.disable_v17 = 0; globals.disable_v17 = 0;
globals.prepend_string = switch_core_strdup(globals.pool, "fax"); globals.prepend_string = switch_core_strdup(globals.pool, "fax");
globals.spool = switch_core_strdup(globals.pool, "/tmp"); globals.spool = switch_core_strdup(globals.pool, "/tmp");
strncpy(globals.ident, "SpanDSP Fax Ident", sizeof(globals.ident)-1 ); strncpy(globals.ident, "SpanDSP Fax Ident", sizeof(globals.ident) - 1);
strncpy(globals.header, "SpanDSP Fax Header", sizeof(globals.header)-1 ); strncpy(globals.header, "SpanDSP Fax Header", sizeof(globals.header) - 1);
load_configuration(0); 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"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind our reloadxml handler!\n");
/* Not such severe to prevent loading */ /* 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; return SWITCH_STATUS_SUCCESS;
} }

View File

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

View File

@ -1409,8 +1409,6 @@ switch_status_t config_sofia(int reload, char *profile_name)
if (!strcasecmp(var, "debug")) { if (!strcasecmp(var, "debug")) {
profile->debug = atoi(val); 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)) { } else if (!strcasecmp(var, "sip-trace") && switch_true(val)) {
switch_set_flag(profile, TFLAG_TPORT_LOG); switch_set_flag(profile, TFLAG_TPORT_LOG);
} else if (!strcasecmp(var, "odbc-dsn") && !switch_strlen_zero(val)) { } 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; 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) { if (!profile->username) {
profile->username = switch_core_strdup(profile->pool, "FreeSWITCH"); 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) { if (tech_pvt && r_sdp) {
sdp_parser_t *parser; sdp_parser_t *parser;
sdp_session_t *sdp; sdp_session_t *sdp;
uint8_t match = 0; uint8_t match = 0, is_ok = 1;
if (r_sdp) { if (r_sdp) {
if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) { 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); switch_core_session_rwunlock(other_session);
} else { } else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Re-INVITE to a no-media channel that is not in a bridge.\n"); 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); switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
} }
goto done; 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); switch_set_flag_locked(tech_pvt, TFLAG_REINVITE);
if (sofia_glue_activate_rtp(tech_pvt, 0) != SWITCH_STATUS_SUCCESS) { if (sofia_glue_activate_rtp(tech_pvt, 0) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Reinvite RTP Error!\n"); 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_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
} }
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Processing Reinvite\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Processing Reinvite\n");
} else { } else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Reinvite Codec Error!\n"); 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, nua_respond(tech_pvt->nh, SIP_200_OK,
SIPTAG_CONTACT_STR(tech_pvt->reply_contact), SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
SOATAG_USER_SDP_STR(tech_pvt->local_sdp_str), SOATAG_USER_SDP_STR(tech_pvt->local_sdp_str),
SOATAG_REUSE_REJECTED(1), SOATAG_REUSE_REJECTED(1),
SOATAG_ORDERED_USER(1), SOATAG_AUDIO_AUX("cn telephone-event"), NUTAG_INCLUDE_EXTRA_SDP(1), TAG_END()); 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; 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]; char tmp[50];
uint32_t rtp_timeout_sec = tech_pvt->profile->rtp_timeout_sec; uint32_t rtp_timeout_sec = tech_pvt->profile->rtp_timeout_sec;
uint32_t rtp_hold_timeout_sec = tech_pvt->profile->rtp_hold_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; const char *var;
switch_assert(tech_pvt != NULL); 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; 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->rtp_session = switch_rtp_new(tech_pvt->local_sdp_audio_ip,
tech_pvt->local_sdp_audio_port, tech_pvt->local_sdp_audio_port,
tech_pvt->remote_sdp_audio_ip, 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.ssrc = read_frame->ssrc;
session->raw_read_frame.seq = read_frame->seq; session->raw_read_frame.seq = read_frame->seq;
session->raw_read_frame.m = read_frame->m; session->raw_read_frame.m = read_frame->m;
session->raw_read_frame.flags = read_frame->flags;
session->raw_read_frame.payload = read_frame->payload; session->raw_read_frame.payload = read_frame->payload;
read_frame = &session->raw_read_frame; read_frame = &session->raw_read_frame;
break; 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.ssrc = read_frame->ssrc;
session->raw_read_frame.seq = read_frame->seq; session->raw_read_frame.seq = read_frame->seq;
session->raw_read_frame.m = read_frame->m; session->raw_read_frame.m = read_frame->m;
session->raw_read_frame.flags = read_frame->flags;
session->raw_read_frame.payload = read_frame->payload; session->raw_read_frame.payload = read_frame->payload;
read_frame = &session->raw_read_frame; read_frame = &session->raw_read_frame;
status = SWITCH_STATUS_SUCCESS; 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; perfect = TRUE;
} else { } else {
if (!session->raw_read_buffer) { if (!session->raw_read_buffer) {
switch_size_t bytes = session->read_codec->implementation->bytes_per_frame; 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); 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)) { 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.ssrc = read_frame->ssrc;
session->enc_read_frame.seq = read_frame->seq; session->enc_read_frame.seq = read_frame->seq;
session->enc_read_frame.m = read_frame->m; 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; session->enc_read_frame.payload = session->read_codec->implementation->ianacode;
} }
*frame = &session->enc_read_frame; *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.timestamp = read_frame->timestamp;
session->raw_read_frame.payload = enc_frame->codec->implementation->ianacode; session->raw_read_frame.payload = enc_frame->codec->implementation->ianacode;
session->raw_read_frame.m = read_frame->m; 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.ssrc = read_frame->ssrc;
session->raw_read_frame.seq = read_frame->seq; session->raw_read_frame.seq = read_frame->seq;
*frame = &session->raw_read_frame; *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.timestamp = frame->timestamp;
session->raw_write_frame.rate = frame->rate; session->raw_write_frame.rate = frame->rate;
session->raw_write_frame.m = frame->m; 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.ssrc = frame->ssrc;
session->raw_write_frame.seq = frame->seq; session->raw_write_frame.seq = frame->seq;
session->raw_write_frame.payload = frame->payload; 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.timestamp = frame->timestamp;
session->enc_write_frame.payload = session->write_codec->implementation->ianacode; session->enc_write_frame.payload = session->write_codec->implementation->ianacode;
session->enc_write_frame.m = frame->m; 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.ssrc = frame->ssrc;
session->enc_write_frame.seq = frame->seq; session->enc_write_frame.seq = frame->seq;
write_frame = &session->enc_write_frame; 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->samples = enc_frame->datalen / sizeof(int16_t);
enc_frame->timestamp = frame->timestamp; enc_frame->timestamp = frame->timestamp;
enc_frame->m = frame->m; enc_frame->m = frame->m;
enc_frame->flags = frame->flags;
enc_frame->seq = frame->seq; enc_frame->seq = frame->seq;
enc_frame->ssrc = frame->ssrc; enc_frame->ssrc = frame->ssrc;
enc_frame->payload = enc_frame->codec->implementation->ianacode; 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.codec = session->write_codec;
session->enc_write_frame.samples = enc_frame->datalen / sizeof(int16_t); session->enc_write_frame.samples = enc_frame->datalen / sizeof(int16_t);
session->enc_write_frame.m = frame->m; 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.ssrc = frame->ssrc;
session->enc_write_frame.payload = session->write_codec->implementation->ianacode; session->enc_write_frame.payload = session->write_codec->implementation->ianacode;
write_frame = &session->enc_write_frame; 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.codec = session->write_codec;
session->enc_write_frame.samples = enc_frame->datalen / sizeof(int16_t); session->enc_write_frame.samples = enc_frame->datalen / sizeof(int16_t);
session->enc_write_frame.m = frame->m; 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.ssrc = frame->ssrc;
session->enc_write_frame.payload = session->write_codec->implementation->ianacode; session->enc_write_frame.payload = session->write_codec->implementation->ianacode;
write_frame = &session->enc_write_frame; 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->codec = session->write_codec;
enc_frame->samples = enc_frame->datalen / sizeof(int16_t); enc_frame->samples = enc_frame->datalen / sizeof(int16_t);
enc_frame->m = frame->m; enc_frame->m = frame->m;
enc_frame->flags = frame->flags;
enc_frame->ssrc = frame->ssrc; enc_frame->ssrc = frame->ssrc;
enc_frame->payload = enc_frame->codec->implementation->ianacode; enc_frame->payload = enc_frame->codec->implementation->ianacode;
write_frame = enc_frame; 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->payload = payload;
rtp_session->ms_per_packet = ms_per_packet; rtp_session->ms_per_packet = ms_per_packet;
rtp_session->samples_per_interval = rtp_session->conf_samples_per_interval = samples_per_interval; 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)) { 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_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)) { 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; 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)) { 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 *tx_host;
const char *old_host; const char *old_host;