diff --git a/src/mod/applications/mod_fax/Makefile.am b/src/mod/applications/mod_fax/Makefile.am
deleted file mode 100644
index c71c5b9da5..0000000000
--- a/src/mod/applications/mod_fax/Makefile.am
+++ /dev/null
@@ -1,24 +0,0 @@
-include $(top_srcdir)/build/modmake.rulesam
-MODNAME=mod_fax
-
-TIFF_DIR=$(switch_srcdir)/libs/tiff-3.8.2
-TIFF_BUILDDIR=$(switch_builddir)/libs/tiff-3.8.2
-TIFF_LA=$(TIFF_BUILDDIR)/libtiff/libtiff.la
-
-SPANDSP_DIR=$(switch_srcdir)/libs/spandsp
-SPANDSP_BUILDDIR=$(switch_builddir)/libs/spandsp
-SPANDSP_LA=$(SPANDSP_BUILDDIR)/src/libspandsp.la
-
-mod_LTLIBRARIES = mod_fax.la
-mod_fax_la_SOURCES = mod_fax.c udptl.c
-mod_fax_la_CFLAGS = $(AM_CFLAGS) -I$(SPANDSP_DIR)/src -I$(TIFF_DIR)/libtiff -I$(SPANDSP_BUILDDIR)/src -I$(TIFF_BUILDDIR)/libtiff -I.
-mod_fax_la_LIBADD = $(switch_builddir)/libfreeswitch.la $(SPANDSP_LA) $(TIFF_LA)
-mod_fax_la_LDFLAGS = -avoid-version -module -no-undefined -shared -ljpeg
-
-$(SPANDSP_LA): $(TIFF_LA) $(SPANDSP_DIR) $(SPANDSP_DIR)/.update
- cd $(SPANDSP_BUILDDIR) && $(MAKE) -j1
- $(TOUCH_TARGET)
-
-$(TIFF_LA): $(TIFF_DIR) $(TIFF_DIR)/.update
- cd $(TIFF_BUILDDIR) && $(MAKE) -j1
- $(TOUCH_TARGET)
diff --git a/src/mod/applications/mod_fax/mod_fax.2008.vcproj b/src/mod/applications/mod_fax/mod_fax.2008.vcproj
deleted file mode 100644
index dd10ca8a93..0000000000
--- a/src/mod/applications/mod_fax/mod_fax.2008.vcproj
+++ /dev/null
@@ -1,299 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/mod/applications/mod_fax/mod_fax.c b/src/mod/applications/mod_fax/mod_fax.c
deleted file mode 100644
index 7eac2520b3..0000000000
--- a/src/mod/applications/mod_fax/mod_fax.c
+++ /dev/null
@@ -1,1945 +0,0 @@
-/*
- * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- * Copyright (C) 2005-2012, Anthony Minessale II
- *
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is FreeSWITCH mod_fax.
- *
- * The Initial Developer of the Original Code is
- * Massimo Cetra
- *
- * Portions created by the Initial Developer are Copyright (C)
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Brian West
- * Anthony Minessale II
- * Steve Underwood
- * Antonio Gallo
- * mod_fax.c -- Fax applications provided by SpanDSP
- *
- */
-
-#include
-#ifdef WIN32
-#define FAX_INVALID_SOCKET INVALID_HANDLE_VALUE
-typedef HANDLE zap_socket_t;
-#else
-#define FAX_INVALID_SOCKET -1
-typedef int zap_socket_t;
-#endif
-
-#define SPANDSP_EXPOSE_INTERNAL_STRUCTURES
-#include
-#include
-
-#include "udptl.h"
-
-#define LOCAL_FAX_MAX_DATAGRAM 400
-#define MAX_FEC_ENTRIES 4
-#define MAX_FEC_SPAN 4
-
-/*****************************************************************************
- OUR DEFINES AND STRUCTS
-*****************************************************************************/
-
-typedef enum {
- FUNCTION_TX,
- FUNCTION_RX,
- FUNCTION_GW
-} application_mode_t;
-
-typedef enum {
- T38_MODE,
- AUDIO_MODE,
- T38_GATEWAY_MODE
-} transport_mode_t;
-
-typedef enum {
- T38_MODE_UNKNOWN = 0,
- T38_MODE_NEGOTIATED = 1,
- T38_MODE_REQUESTED = 2,
- T38_MODE_REFUSED = -1,
-} t38_mode_t;
-
-/* The global stuff */
-static struct {
- switch_memory_pool_t *pool;
- switch_mutex_t *mutex;
-
- uint32_t total_sessions;
-
- short int use_ecm;
- short int verbose;
- short int disable_v17;
- short int enable_t38;
- short int enable_t38_request;
- short int enable_t38_insist;
- char ident[20];
- char header[50];
- char *prepend_string;
- char *spool;
-} globals;
-
-struct pvt_s {
- switch_core_session_t *session;
-
- application_mode_t app_mode;
-
- fax_state_t *fax_state;
- t38_terminal_state_t *t38_state;
- t38_gateway_state_t *t38_gateway_state;
- t38_core_state_t *t38_core;
-
- udptl_state_t *udptl_state;
-
- char *filename;
- char *ident;
- char *header;
-
- int use_ecm;
- int disable_v17;
- int verbose;
- int caller;
-
- int tx_page_start;
- int tx_page_end;
-
- int done;
-
- t38_mode_t t38_mode;
-
- struct pvt_s *next;
-};
-
-typedef struct pvt_s pvt_t;
-
-static void launch_timer_thread(void);
-
-static struct {
- pvt_t *head;
- switch_mutex_t *mutex;
- switch_thread_t *thread;
- int thread_running;
-} t38_state_list;
-
-static int add_pvt(pvt_t *pvt)
-{
- int r = 0;
- uint32_t sanity = 50;
-
- switch_mutex_lock(t38_state_list.mutex);
- if (!t38_state_list.thread_running) {
-
- launch_timer_thread();
-
- while(--sanity && !t38_state_list.thread_running) {
- switch_yield(10000);
- }
- }
- switch_mutex_unlock(t38_state_list.mutex);
-
- if (t38_state_list.thread_running) {
- switch_mutex_lock(t38_state_list.mutex);
- pvt->next = t38_state_list.head;
- t38_state_list.head = pvt;
- switch_mutex_unlock(t38_state_list.mutex);
- }
-
- return r;
-
-}
-
-
-static int del_pvt(pvt_t *del_pvt)
-{
- pvt_t *p, *l = NULL;
- int r = 0;
-
- if (!t38_state_list.thread_running) goto end;
-
- switch_mutex_lock(t38_state_list.mutex);
- for (p = t38_state_list.head; p; p = p->next) {
- if (p == del_pvt) {
- if (l) {
- l->next = p->next;
- } else {
- t38_state_list.head = p->next;
- }
- p->next = NULL;
- r = 1;
- goto end;
- }
-
- l = p;
- }
-
- end:
-
- switch_mutex_unlock(t38_state_list.mutex);
-
- return r;
-
-}
-
-static void *SWITCH_THREAD_FUNC timer_thread_run(switch_thread_t *thread, void *obj)
-{
- switch_timer_t timer = { 0 };
- pvt_t *pvt;
- int samples = 240;
- int ms = 30;
-
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "timer thread started.\n");
-
- if (switch_core_timer_init(&timer, "soft", ms, samples, NULL) != SWITCH_STATUS_SUCCESS) {
- return NULL;
- }
-
- t38_state_list.thread_running = 1;
-
- while(t38_state_list.thread_running) {
-
- switch_mutex_lock(t38_state_list.mutex);
-
- if (!t38_state_list.head) {
- switch_mutex_unlock(t38_state_list.mutex);
- goto end;
- }
-
- for (pvt = t38_state_list.head; pvt; pvt = pvt->next) {
- if (pvt->udptl_state) {
- t38_terminal_send_timeout(pvt->t38_state, samples);
- }
- }
-
- switch_mutex_unlock(t38_state_list.mutex);
-
- switch_core_timer_next(&timer);
- }
-
- end:
-
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "timer thread ended.\n");
-
- t38_state_list.thread_running = 0;
- switch_core_timer_destroy(&timer);
-
- return NULL;
-}
-
-static void launch_timer_thread(void)
-{
-
- switch_threadattr_t *thd_attr = NULL;
-
- switch_threadattr_create(&thd_attr, globals.pool);
- switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
- switch_thread_create(&t38_state_list.thread, thd_attr, timer_thread_run, NULL, globals.pool);
-}
-
-
-/*****************************************************************************
- LOGGING AND HELPER FUNCTIONS
-*****************************************************************************/
-
-static void counter_increment(void)
-{
- switch_mutex_lock(globals.mutex);
- globals.total_sessions++;
- switch_mutex_unlock(globals.mutex);
-}
-
-static void spanfax_log_message(int level, const char *msg)
-{
- int fs_log_level;
-
- switch (level) {
- case SPAN_LOG_NONE:
- return;
- case SPAN_LOG_ERROR:
- case SPAN_LOG_PROTOCOL_ERROR:
- fs_log_level = SWITCH_LOG_ERROR;
- break;
- case SPAN_LOG_WARNING:
- case SPAN_LOG_PROTOCOL_WARNING:
- fs_log_level = SWITCH_LOG_WARNING;
- break;
- case SPAN_LOG_FLOW:
- case SPAN_LOG_FLOW_2:
- case SPAN_LOG_FLOW_3:
- default: /* SPAN_LOG_DEBUG, SPAN_LOG_DEBUG_2, SPAN_LOG_DEBUG_3 */
- fs_log_level = SWITCH_LOG_DEBUG;
- break;
- }
-
- if (!zstr(msg)) {
- switch_log_printf(SWITCH_CHANNEL_LOG, fs_log_level, "%s", msg);
- }
-}
-
-/*
- * Called at the end of the document
- */
-static void phase_e_handler(t30_state_t *s, void *user_data, int result)
-{
- t30_stats_t t;
- const char *local_ident;
- const char *far_ident;
- switch_core_session_t *session;
- switch_channel_t *channel;
- pvt_t *pvt;
- char *tmp;
-
- pvt = (pvt_t *) user_data;
- switch_assert(pvt);
-
- session = pvt->session;
- switch_assert(session);
-
- channel = switch_core_session_get_channel(session);
- switch_assert(channel);
-
- t30_get_transfer_statistics(s, &t);
- local_ident = switch_str_nil(t30_get_tx_ident(s));
- far_ident = switch_str_nil(t30_get_rx_ident(s));
-
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "==============================================================================\n");
-
- if (result == T30_ERR_OK) {
- if (pvt->app_mode == FUNCTION_TX) {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Fax successfully sent.\n");
- } else if (pvt->app_mode == FUNCTION_RX) {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Fax successfully received.\n");
- } else {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Fax successfully managed. How ?\n");
- }
- switch_channel_set_variable(channel, "fax_success", "1");
- } else {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Fax processing not successful - result (%d) %s.\n", result,
- t30_completion_code_to_str(result));
- switch_channel_set_variable(channel, "fax_success", "0");
- }
-
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Remote station id: %s\n", far_ident);
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Local station id: %s\n", local_ident);
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Pages transferred: %i\n",
- pvt->app_mode == FUNCTION_TX ? t.pages_tx : t.pages_rx);
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Total fax pages: %i\n", t.pages_in_file);
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Image resolution: %ix%i\n", t.x_resolution, t.y_resolution);
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Transfer Rate: %i\n", t.bit_rate);
-
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "ECM status %s\n", (t.error_correcting_mode) ? "on" : "off");
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "remote country: %s\n", switch_str_nil(t30_get_rx_country(s)));
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "remote vendor: %s\n", switch_str_nil(t30_get_rx_vendor(s)));
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "remote model: %s\n", switch_str_nil(t30_get_rx_model(s)));
-
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "==============================================================================\n");
-
- /*
- Set our channel variables
- */
-
- tmp = switch_mprintf("%i", result);
- if (tmp) {
- switch_channel_set_variable(channel, "fax_result_code", tmp);
- switch_safe_free(tmp);
- }
-
- switch_channel_set_variable(channel, "fax_result_text", t30_completion_code_to_str(result));
-
- switch_channel_set_variable(channel, "fax_ecm_used", (t.error_correcting_mode) ? "on" : "off");
- switch_channel_set_variable(channel, "fax_local_station_id", local_ident);
- switch_channel_set_variable(channel, "fax_remote_station_id", far_ident);
-
- tmp = switch_mprintf("%i", pvt->app_mode == FUNCTION_TX ? t.pages_tx : t.pages_rx);
- if (tmp) {
- switch_channel_set_variable(channel, "fax_document_transferred_pages", tmp);
- switch_safe_free(tmp);
- }
-
- tmp = switch_mprintf("%i", t.pages_in_file);
- if (tmp) {
- switch_channel_set_variable(channel, "fax_document_total_pages", tmp);
- switch_safe_free(tmp);
- }
-
- tmp = switch_mprintf("%ix%i", t.x_resolution, t.y_resolution);
- if (tmp) {
- switch_channel_set_variable(channel, "fax_image_resolution", tmp);
- switch_safe_free(tmp);
- }
-
- tmp = switch_mprintf("%d", t.image_size);
- if (tmp) {
- switch_channel_set_variable(channel, "fax_image_size", tmp);
- switch_safe_free(tmp);
- }
-
- tmp = switch_mprintf("%d", t.bad_rows);
- if (tmp) {
- switch_channel_set_variable(channel, "fax_bad_rows", tmp);
- switch_safe_free(tmp);
- }
-
- tmp = switch_mprintf("%i", t.bit_rate);
- if (tmp) {
- switch_channel_set_variable(channel, "fax_transfer_rate", tmp);
- switch_safe_free(tmp);
- }
-
- /* switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING); */
-
- pvt->done = 1;
-
- /*
- TODO Fire events
- */
-}
-
-static int t38_tx_packet_handler(t38_core_state_t *s, void *user_data, const uint8_t *buf, int len, int count)
-{
- switch_frame_t out_frame = { 0 };
- switch_core_session_t *session;
- switch_channel_t *channel;
- pvt_t *pvt;
- uint8_t pkt[LOCAL_FAX_MAX_DATAGRAM];
- int x;
- int r = 0;
-
- pvt = (pvt_t *) user_data;
- session = pvt->session;
- channel = switch_core_session_get_channel(session);
-
- /* we need to build a real packet here and make write_frame.packet and write_frame.packetlen point to it */
- out_frame.flags = SFF_UDPTL_PACKET | SFF_PROXY_PACKET;
- out_frame.packet = pkt;
- out_frame.packetlen = udptl_build_packet(pvt->udptl_state, pkt, buf, len);
-
- //switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "WRITE %d udptl bytes\n", out_frame.packetlen);
-
- for (x = 0; x < count; x++) {
- if (switch_core_session_write_frame(session, &out_frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) {
- r = -1;
- break;
- }
- }
-
- return r;
-}
-
-static switch_status_t spanfax_init(pvt_t *pvt, transport_mode_t trans_mode)
-{
-
- switch_core_session_t *session;
- switch_channel_t *channel;
- fax_state_t *fax;
- t38_terminal_state_t *t38;
- t30_state_t *t30;
-
-
- session = (switch_core_session_t *) pvt->session;
- switch_assert(session);
-
- channel = switch_core_session_get_channel(session);
- switch_assert(channel);
-
-
- switch (trans_mode) {
- case AUDIO_MODE:
- if (pvt->fax_state == NULL) {
- pvt->fax_state = (fax_state_t *) switch_core_session_alloc(pvt->session, sizeof(fax_state_t));
- }
- if (pvt->fax_state == NULL) {
- return SWITCH_STATUS_FALSE;
- }
-
- fax = pvt->fax_state;
- t30 = fax_get_t30_state(fax);
-
- memset(fax, 0, sizeof(fax_state_t));
- if (fax_init(fax, pvt->caller) == NULL) {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot initialize my fax structs\n");
- return SWITCH_STATUS_FALSE;
- }
-
- fax_set_transmit_on_idle(fax, TRUE);
-
- span_log_set_message_handler(&fax->logging, spanfax_log_message);
- span_log_set_message_handler(&t30->logging, spanfax_log_message);
-
- if (pvt->verbose) {
- span_log_set_level(&fax->logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
- span_log_set_level(&t30->logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
- }
- break;
- case T38_MODE:
- if (pvt->t38_state == NULL) {
- pvt->t38_state = (t38_terminal_state_t *) switch_core_session_alloc(pvt->session, sizeof(t38_terminal_state_t));
- }
- if (pvt->t38_state == NULL) {
- return SWITCH_STATUS_FALSE;
- }
- if (pvt->udptl_state == NULL) {
- pvt->udptl_state = (udptl_state_t *) switch_core_session_alloc(pvt->session, sizeof(udptl_state_t));
- }
- if (pvt->udptl_state == NULL) {
- t38_terminal_free(pvt->t38_state);
- pvt->t38_state = NULL;
- return SWITCH_STATUS_FALSE;
- }
-
- /* add to timer thread processing */
- add_pvt(pvt);
-
- t38 = pvt->t38_state;
- t30 = t38_terminal_get_t30_state(t38);
-
- memset(t38, 0, sizeof(t38_terminal_state_t));
-
- if (t38_terminal_init(t38, pvt->caller, t38_tx_packet_handler, pvt) == NULL) {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot initialize my T.38 structs\n");
- return SWITCH_STATUS_FALSE;
- }
-
- pvt->t38_core = t38_terminal_get_t38_core_state(pvt->t38_state);
-
- if (udptl_init(pvt->udptl_state, UDPTL_ERROR_CORRECTION_REDUNDANCY, 3, 3,
- (udptl_rx_packet_handler_t *) t38_core_rx_ifp_packet, (void *) pvt->t38_core) == NULL) {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot initialize my UDPTL structs\n");
- return SWITCH_STATUS_FALSE;
- }
-
- span_log_set_message_handler(&t38->logging, spanfax_log_message);
- span_log_set_message_handler(&t30->logging, spanfax_log_message);
-
- if (pvt->verbose) {
- span_log_set_level(&t38->logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
- span_log_set_level(&t30->logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
- }
- break;
- case T38_GATEWAY_MODE:
- if (pvt->t38_gateway_state == NULL) {
- pvt->t38_gateway_state = (t38_gateway_state_t *) switch_core_session_alloc(pvt->session, sizeof(t38_gateway_state_t));
- }
-
- if (pvt->udptl_state == NULL) {
- pvt->udptl_state = (udptl_state_t *) switch_core_session_alloc(pvt->session, sizeof(udptl_state_t));
- }
-
- if (t38_gateway_init(pvt->t38_gateway_state, t38_tx_packet_handler, pvt) == NULL) {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot initialize my T.38 structs\n");
- t38_gateway_free(pvt->t38_gateway_state);
- pvt->t38_gateway_state = NULL;
-
- return SWITCH_STATUS_FALSE;
- }
-
- pvt->t38_core = t38_gateway_get_t38_core_state(pvt->t38_gateway_state);
-
- if (udptl_init(pvt->udptl_state, UDPTL_ERROR_CORRECTION_REDUNDANCY, 3, 3,
- (udptl_rx_packet_handler_t *) t38_core_rx_ifp_packet, (void *) pvt->t38_core) == NULL) {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot initialize my UDPTL structs\n");
- t38_gateway_free(pvt->t38_gateway_state);
- udptl_release(pvt->udptl_state);
- pvt->udptl_state = NULL;
- return SWITCH_STATUS_FALSE;
- }
-
- t38_gateway_set_transmit_on_idle(pvt->t38_gateway_state, TRUE);
-
- if (switch_true(switch_channel_get_variable(channel, "fax_v17_disabled"))) {
- t38_gateway_set_supported_modems(pvt->t38_gateway_state, T30_SUPPORT_V29 | T30_SUPPORT_V27TER);
- } else {
- t38_gateway_set_supported_modems(pvt->t38_gateway_state, T30_SUPPORT_V17 | T30_SUPPORT_V29 | T30_SUPPORT_V27TER);
- }
-
- t38_gateway_set_ecm_capability(pvt->t38_gateway_state, pvt->use_ecm);
- switch_channel_set_variable(channel, "fax_ecm_requested", pvt->use_ecm ? "true" : "false");
-
- if (switch_true(switch_channel_get_variable(channel, "FAX_DISABLE_ECM"))) {
- t38_gateway_set_ecm_capability(pvt->t38_gateway_state, FALSE);
- } else {
- t38_gateway_set_ecm_capability(pvt->t38_gateway_state, TRUE);
- }
-
-
- span_log_set_message_handler(&pvt->t38_gateway_state->logging, spanfax_log_message);
- span_log_set_message_handler(&pvt->t38_core->logging, spanfax_log_message);
-
- if (pvt->verbose) {
- span_log_set_level(&pvt->t38_gateway_state->logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
- span_log_set_level(&pvt->t38_core->logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
- }
-
- t38_set_t38_version(pvt->t38_core, 0);
- t38_gateway_set_ecm_capability(pvt->t38_gateway_state, 1);
-
- return SWITCH_STATUS_SUCCESS;
-
- default:
- assert(0); /* What? */
- return SWITCH_STATUS_SUCCESS;
- } /* Switch trans mode */
-
- /* All the things which are common to audio and T.38 FAX setup */
- t30_set_tx_ident(t30, pvt->ident);
- t30_set_tx_page_header_info(t30, pvt->header);
-
- t30_set_phase_e_handler(t30, phase_e_handler, pvt);
-
- t30_set_supported_image_sizes(t30,
- T30_SUPPORT_US_LETTER_LENGTH | T30_SUPPORT_US_LEGAL_LENGTH | T30_SUPPORT_UNLIMITED_LENGTH
- | T30_SUPPORT_215MM_WIDTH | T30_SUPPORT_255MM_WIDTH | T30_SUPPORT_303MM_WIDTH);
- t30_set_supported_resolutions(t30,
- T30_SUPPORT_STANDARD_RESOLUTION | T30_SUPPORT_FINE_RESOLUTION | T30_SUPPORT_SUPERFINE_RESOLUTION
- | T30_SUPPORT_R8_RESOLUTION | T30_SUPPORT_R16_RESOLUTION);
-
- if (pvt->disable_v17) {
- t30_set_supported_modems(t30, T30_SUPPORT_V29 | T30_SUPPORT_V27TER);
- switch_channel_set_variable(channel, "fax_v17_disabled", "1");
- } else {
- t30_set_supported_modems(t30, T30_SUPPORT_V29 | T30_SUPPORT_V27TER | T30_SUPPORT_V17);
- switch_channel_set_variable(channel, "fax_v17_disabled", "0");
- }
-
- if (pvt->use_ecm) {
- t30_set_supported_compressions(t30, T30_SUPPORT_T4_1D_COMPRESSION | T30_SUPPORT_T4_2D_COMPRESSION | T30_SUPPORT_T6_COMPRESSION);
- t30_set_ecm_capability(t30, TRUE);
- switch_channel_set_variable(channel, "fax_ecm_requested", "1");
- } else {
- t30_set_supported_compressions(t30, T30_SUPPORT_T4_1D_COMPRESSION | T30_SUPPORT_T4_2D_COMPRESSION);
- switch_channel_set_variable(channel, "fax_ecm_requested", "0");
- }
-
- if (pvt->app_mode == FUNCTION_TX) {
- t30_set_tx_file(t30, pvt->filename, pvt->tx_page_start, pvt->tx_page_end);
- } else {
- t30_set_rx_file(t30, pvt->filename, -1);
- }
- switch_channel_set_variable(channel, "fax_filename", pvt->filename);
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status_t spanfax_destroy(pvt_t *pvt)
-{
- int terminate;
- t30_state_t *t30;
-
- if (!pvt) return SWITCH_STATUS_FALSE;
-
- if (pvt->fax_state) {
- if (pvt->t38_state) {
- terminate = 0;
- } else {
- terminate = 1;
- }
-
- t30 = fax_get_t30_state(pvt->fax_state);
- if (terminate && t30) {
- t30_terminate(t30);
- }
-
- fax_release(pvt->fax_state);
- }
-
- if (pvt->t38_state) {
-
- /* remove from timer thread processing */
- del_pvt(pvt);
-
- if (pvt->t38_state) {
- terminate = 1;
- } else {
- terminate = 0;
- }
-
- t30 = t38_terminal_get_t30_state(pvt->t38_state);
-
- if (terminate && t30) {
- t30_terminate(t30);
- }
-
- t38_terminal_release(pvt->t38_state);
- }
-
- if (pvt->t38_gateway_state) {
- t38_gateway_release(pvt->t38_gateway_state);
- }
-
- if (pvt->udptl_state) {
- udptl_release(pvt->udptl_state);
- }
- return SWITCH_STATUS_SUCCESS;
-}
-
-static t38_mode_t configure_t38(pvt_t *pvt)
-{
- switch_core_session_t *session = pvt->session;
- switch_channel_t *channel = switch_core_session_get_channel(session);
- switch_t38_options_t *t38_options = switch_channel_get_private(channel, "t38_options");
- int method = 2;
-
- if (!t38_options || !pvt || !pvt->t38_core) {
- pvt->t38_mode = T38_MODE_REFUSED;
- return pvt->t38_mode;
- }
-
- t38_set_t38_version(pvt->t38_core, t38_options->T38FaxVersion);
- t38_set_max_buffer_size(pvt->t38_core, t38_options->T38FaxMaxBuffer);
- t38_set_fastest_image_data_rate(pvt->t38_core, t38_options->T38MaxBitRate);
- t38_set_fill_bit_removal(pvt->t38_core, t38_options->T38FaxFillBitRemoval);
- t38_set_mmr_transcoding(pvt->t38_core, t38_options->T38FaxTranscodingMMR);
- t38_set_jbig_transcoding(pvt->t38_core, t38_options->T38FaxTranscodingJBIG);
- t38_set_max_datagram_size(pvt->t38_core, t38_options->T38FaxMaxDatagram);
-
- if (t38_options->T38FaxRateManagement) {
- if (!strcasecmp(t38_options->T38FaxRateManagement, "transferredTCF")) {
- method = 2;
- } else {
- method = 1;
- }
- }
-
- t38_set_data_rate_management_method(pvt->t38_core, method);
-
-
- //t38_set_data_transport_protocol(pvt->t38_core, int data_transport_protocol);
- //t38_set_redundancy_control(pvt->t38_core, int category, int setting);
-
- return pvt->t38_mode;
-}
-
-static t38_mode_t negotiate_t38(pvt_t *pvt)
-{
- switch_core_session_t *session = pvt->session;
- switch_channel_t *channel = switch_core_session_get_channel(session);
- switch_core_session_message_t msg = { 0 };
- switch_t38_options_t *t38_options = switch_channel_get_private(channel, "t38_options");
- int enabled = 0, insist = 0;
- const char *v;
-
- pvt->t38_mode = T38_MODE_REFUSED;
-
- if (pvt->app_mode == FUNCTION_GW) {
- enabled = 1;
- } else if ((v = switch_channel_get_variable(channel, "fax_enable_t38"))) {
- enabled = switch_true(v);
- } else {
- enabled = globals.enable_t38;
- }
-
- if (!(enabled && t38_options)) {
- /* if there is no t38_options the endpoint will refuse the transition */
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s NO T38 options detected.\n", switch_channel_get_name(channel));
- switch_channel_set_private(channel, "t38_options", NULL);
- } else {
- pvt->t38_mode = T38_MODE_NEGOTIATED;
-
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "T38FaxVersion = %d\n", t38_options->T38FaxVersion);
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "T38MaxBitRate = %d\n", t38_options->T38MaxBitRate);
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "T38FaxFillBitRemoval = %d\n", t38_options->T38FaxFillBitRemoval);
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "T38FaxTranscodingMMR = %d\n", t38_options->T38FaxTranscodingMMR);
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "T38FaxTranscodingJBIG = %d\n", t38_options->T38FaxTranscodingJBIG);
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "T38FaxRateManagement = '%s'\n", t38_options->T38FaxRateManagement);
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "T38FaxMaxBuffer = %d\n", t38_options->T38FaxMaxBuffer);
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "T38FaxMaxDatagram = %d\n", t38_options->T38FaxMaxDatagram);
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "T38FaxUdpEC = '%s'\n", t38_options->T38FaxUdpEC);
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "T38VendorInfo = '%s'\n", switch_str_nil(t38_options->T38VendorInfo));
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "ip = '%s'\n", t38_options->remote_ip ? t38_options->remote_ip : "Not specified");
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "port = %d\n", t38_options->remote_port);
-
- /* Time to practice our negotiating skills, by editing the t38_options */
-
- if (t38_options->T38FaxVersion > 3) {
- t38_options->T38FaxVersion = 3;
- }
- t38_options->T38MaxBitRate = (pvt->disable_v17) ? 9600 : 14400;
- t38_options->T38FaxFillBitRemoval = 1;
- t38_options->T38FaxTranscodingMMR = 0;
- t38_options->T38FaxTranscodingJBIG = 0;
- t38_options->T38FaxRateManagement = "transferredTCF";
- t38_options->T38FaxMaxBuffer = 2000;
- t38_options->T38FaxMaxDatagram = LOCAL_FAX_MAX_DATAGRAM;
- if (strcasecmp(t38_options->T38FaxUdpEC, "t38UDPRedundancy") == 0
- ||
- strcasecmp(t38_options->T38FaxUdpEC, "t38UDPFEC") == 0) {
- t38_options->T38FaxUdpEC = "t38UDPRedundancy";
- } else {
- t38_options->T38FaxUdpEC = NULL;
- }
- t38_options->T38VendorInfo = "0 0 0";
- }
-
- if ((v = switch_channel_get_variable(channel, "fax_enable_t38_insist"))) {
- insist = switch_true(v);
- } else {
- insist = globals.enable_t38_insist;
- }
-
- /* This will send the options back in a response */
- msg.from = __FILE__;
- msg.message_id = SWITCH_MESSAGE_INDICATE_T38_DESCRIPTION;
- msg.numeric_arg = insist;
- switch_core_session_receive_message(session, &msg);
-
- return pvt->t38_mode;
-}
-
-
-
-static t38_mode_t request_t38(pvt_t *pvt)
-{
- switch_core_session_t *session = pvt->session;
- switch_channel_t *channel = switch_core_session_get_channel(session);
- switch_core_session_message_t msg = { 0 };
- switch_t38_options_t *t38_options = NULL;
- int enabled = 0, insist = 0;
- const char *v;
-
- pvt->t38_mode = T38_MODE_UNKNOWN;
-
- if (pvt->app_mode == FUNCTION_GW) {
- enabled = 1;
- } else if ((v = switch_channel_get_variable(channel, "fax_enable_t38"))) {
- enabled = switch_true(v);
- } else {
- enabled = globals.enable_t38;
- }
-
- if (enabled) {
- if ((v = switch_channel_get_variable(channel, "fax_enable_t38_request"))) {
- enabled = switch_true(v);
- } else {
- enabled = globals.enable_t38_request;
- }
- }
-
-
- if ((v = switch_channel_get_variable(channel, "fax_enable_t38_insist"))) {
- insist = switch_true(v);
- } else {
- insist = globals.enable_t38_insist;
- }
-
- if (enabled) {
- t38_options = switch_core_session_alloc(session, sizeof(*t38_options));
-
- t38_options->T38MaxBitRate = (pvt->disable_v17) ? 9600 : 14400;
- t38_options->T38FaxVersion = 0;
- t38_options->T38FaxFillBitRemoval = 1;
- t38_options->T38FaxTranscodingMMR = 0;
- t38_options->T38FaxTranscodingJBIG = 0;
- t38_options->T38FaxRateManagement = "transferredTCF";
- t38_options->T38FaxMaxBuffer = 2000;
- t38_options->T38FaxMaxDatagram = LOCAL_FAX_MAX_DATAGRAM;
- t38_options->T38FaxUdpEC = "t38UDPRedundancy";
- t38_options->T38VendorInfo = "0 0 0";
-
- switch_channel_set_private(channel, "t38_options", t38_options);
- pvt->t38_mode = T38_MODE_REQUESTED;
-
- /* This will send a request for t.38 mode */
- msg.from = __FILE__;
- msg.message_id = SWITCH_MESSAGE_INDICATE_REQUEST_IMAGE_MEDIA;
- msg.numeric_arg = insist;
- switch_core_session_receive_message(session, &msg);
- }
-
- return pvt->t38_mode;
-}
-
-/*****************************************************************************
- MAIN FAX PROCESSING
-*****************************************************************************/
-
-static pvt_t *pvt_init(switch_core_session_t *session, application_mode_t app_mode)
-{
- switch_channel_t *channel;
- pvt_t *pvt = NULL;
- const char *tmp;
-
- /* Make sure we have a valid channel when starting the FAX application */
- 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));
- pvt->session = session;
-
- pvt->app_mode = app_mode;
-
- pvt->tx_page_start = -1;
- pvt->tx_page_end = -1;
-
-
- switch(pvt->app_mode) {
-
- case FUNCTION_TX:
- pvt->caller = 1;
- break;
- case FUNCTION_RX:
- pvt->caller = 0;
- break;
- case FUNCTION_GW:
- break;
- }
-
- /* Retrieving our settings from the channel variables */
-
- if ((tmp = switch_channel_get_variable(channel, "fax_use_ecm"))) {
- pvt->use_ecm = switch_true(tmp);
- } else {
- pvt->use_ecm = globals.use_ecm;
- }
-
- if ((tmp = switch_channel_get_variable(channel, "fax_disable_v17"))) {
- pvt->disable_v17 = switch_true(tmp);
- } else {
- pvt->disable_v17 = globals.disable_v17;
- }
-
- if ((tmp = switch_channel_get_variable(channel, "fax_verbose"))) {
- 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;
- }
- }
-
- if ((tmp = switch_channel_get_variable(channel, "fax_ident"))) {
- pvt->ident = switch_core_session_strdup(session, tmp);
- } 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 {
- pvt->header = switch_core_session_strdup(session, globals.header);
- }
-
- if (pvt->app_mode == FUNCTION_TX) {
- if ((tmp = switch_channel_get_variable(channel, "fax_start_page"))) {
- pvt->tx_page_start = atoi(tmp);
- }
-
- if ((tmp = switch_channel_get_variable(channel, "fax_end_page"))) {
- pvt->tx_page_end = atoi(tmp);
- }
-
- if (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;
- }
- }
-
- return pvt;
-}
-
-void process_fax(switch_core_session_t *session, const char *data, application_mode_t app_mode)
-{
- pvt_t *pvt;
- switch_channel_t *channel = switch_core_session_get_channel(session);
- switch_codec_t read_codec = { 0 };
- switch_codec_t write_codec = { 0 };
- switch_frame_t *read_frame = { 0 };
- switch_frame_t write_frame = { 0 };
- switch_codec_implementation_t read_impl = { 0 };
- int16_t *buf = NULL;
-
- switch_core_session_get_read_impl(session, &read_impl);
-
- counter_increment();
-
-
- pvt = pvt_init(session, app_mode);
-
-
- buf = switch_core_session_alloc(session, SWITCH_RECOMMENDED_BUFFER_SIZE);
-
- if (!zstr(data)) {
- pvt->filename = switch_core_session_strdup(session, data);
- if (pvt->app_mode == FUNCTION_TX) {
- if ((switch_file_exists(pvt->filename, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS)) {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot send inexistant fax file [%s]\n",
- switch_str_nil(pvt->filename));
- goto done;
- }
- }
- } else {
- if (pvt->app_mode == FUNCTION_TX) {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Fax TX filename not set.\n");
- goto done;
- } else if (pvt->app_mode == FUNCTION_RX) {
- char *fname;
- const char *prefix;
- switch_time_t time;
-
- time = switch_time_now();
-
- if (!(prefix = switch_channel_get_variable(channel, "fax_prefix"))) {
- prefix = globals.prepend_string;
- }
-
- fname = switch_mprintf("%s/%s-%ld-%ld.tif", globals.spool, prefix, globals.total_sessions, time);
- if (fname) {
- pvt->filename = switch_core_session_strdup(session, fname);
- switch_safe_free(fname);
- } else {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot automatically set fax RX destination file\n");
- goto done;
- }
- } else {
- assert(0); /* UH ?? */
- }
- }
-
- /*
- *** Initialize the SpanDSP elements ***
-
- Note: we could analyze if a fax was already detected in previous stages
- and if so, when T.38 will be supported, send a reinvite in T38_MODE,
- bypassing AUDIO_MODE.
- */
-
- if ((spanfax_init(pvt, AUDIO_MODE) != SWITCH_STATUS_SUCCESS)) {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot initialize Fax engine\n");
- return;
- }
-
- /*
- 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");
-
-
- /* We store the original channel codec before switching both
- * legs of the calls to a linear 16 bit codec that is the one
- * used internally by spandsp and FS will do the transcoding
- * from G.711 or any other original codec
- */
- if (switch_core_codec_init(&read_codec,
- "L16",
- NULL,
- read_impl.samples_per_second,
- read_impl.microseconds_per_packet / 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_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Raw read codec activation Success L16 %u\n",
- read_codec.implementation->microseconds_per_packet);
- switch_core_session_set_read_codec(session, &read_codec);
- } else {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Raw read codec activation Failed L16\n");
- goto done;
- }
-
- if (switch_core_codec_init(&write_codec,
- "L16",
- NULL,
- read_impl.samples_per_second,
- read_impl.microseconds_per_packet / 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_SESSION_LOG(session), 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 {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Raw write codec activation Failed L16\n");
- goto done;
- }
-
- switch_ivr_sleep(session, 250, SWITCH_TRUE, NULL);
-
-
- /* If you have the means, I highly recommend picking one up. ...*/
- request_t38(pvt);
-
-
- while (switch_channel_ready(channel)) {
- int tx = 0;
- switch_status_t status;
-
- /*
- if we are in T.38 mode, we should: 1- initialize the ptv->t38_state stuff, if not done
- and then set some callbacks when reading frames.
- The only thing we need, then, in this loop, is:
- - read a frame without blocking
- - eventually feed that frame in spandsp,
- - call t38_terminal_send_timeout(), sleep for a while
-
- The T.38 stuff can be placed here (and the audio stuff can be skipped)
- */
-
- /* 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) || pvt->done) {
- /* Our duty is over */
- goto done;
- }
-
- switch (pvt->t38_mode) {
- case T38_MODE_REQUESTED:
- {
- if (switch_channel_test_app_flag_key("T38", channel, CF_APP_T38)) {
- switch_core_session_message_t msg = { 0 };
- pvt->t38_mode = T38_MODE_NEGOTIATED;
- spanfax_init(pvt, T38_MODE);
- configure_t38(pvt);
-
- /* This will change the rtp stack to udptl mode */
- msg.from = __FILE__;
- msg.message_id = SWITCH_MESSAGE_INDICATE_UDPTL_MODE;
- switch_core_session_receive_message(session, &msg);
- }
- continue;
- }
- break;
- case T38_MODE_UNKNOWN:
- {
- if (switch_channel_test_app_flag_key("T38", channel, CF_APP_T38)) {
- if (negotiate_t38(pvt) == T38_MODE_NEGOTIATED) {
- /* is is safe to call this again, it was already called above in AUDIO_MODE */
- /* but this is the only way to set up the t38 stuff */
- spanfax_init(pvt, T38_MODE);
- continue;
- }
- }
- }
- break;
- case T38_MODE_NEGOTIATED:
- {
- /* do what we need to do when we are in t38 mode */
- if (switch_test_flag(read_frame, SFF_CNG)) {
- /* dunno what to do, most likely you will not get too many of these since we turn off the timer in udptl mode */
- continue;
- }
-
- if (switch_test_flag(read_frame, SFF_UDPTL_PACKET)) {
- /* now we know we can cast frame->packet to a udptl structure */
- //switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "READ %d udptl bytes\n", read_frame->packetlen);
-
- udptl_rx_packet(pvt->udptl_state, read_frame->packet, read_frame->packetlen);
-
-
- }
- }
- continue;
- default:
- break;
- }
-
- /* Skip CNG frames (auto-generated by FreeSWITCH, usually) */
- if (switch_test_flag(read_frame, SFF_CNG)) {
- /* We have no real signal data for the FAX software, but we have a space in time if we have a CNG indication.
- Do a fill-in operation in the FAX machine, to keep things rolling along. */
- if (fax_rx_fillin(pvt->fax_state, read_frame->samples)) {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "fax_rx_fillin reported an error\n");
- goto done;
- }
- } else {
- /* 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)) {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "fax_rx reported an error\n");
- goto done;
- }
- }
-
- if ((tx = fax_tx(pvt->fax_state, buf, write_codec.implementation->samples_per_packet)) < 0) {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "fax_tx reported an error\n");
- goto done;
- }
-
- if (!tx) {
- /* switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "No audio samples to send\n"); */
- continue;
- } 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) {
- goto done;
- }
-
- }
-
- done:
- /* Destroy the SpanDSP structures */
- spanfax_destroy(pvt);
-
- /* restore the original codecs over the channel */
-
- switch_core_session_set_read_codec(session, NULL);
-
- if (switch_core_codec_ready(&read_codec)) {
- switch_core_codec_destroy(&read_codec);
- }
-
- if (switch_core_codec_ready(&write_codec)) {
- switch_core_codec_destroy(&write_codec);
- }
-}
-
-/* **************************************************************************
- CONFIGURATION
- ************************************************************************* */
-
-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) {
- const char *name = switch_xml_attr(x_list, "name");
- const char *value = switch_xml_attr(x_list, "value");
-
- if (zstr(name)) {
- continue;
- }
-
- if (zstr(value)) {
- continue;
- }
-
- if (!strcmp(name, "use-ecm")) {
- if (switch_true(value))
- globals.use_ecm = 1;
- else
- globals.use_ecm = 0;
- } else if (!strcmp(name, "verbose")) {
- if (switch_true(value))
- globals.verbose = 1;
- else
- globals.verbose = 0;
- } else if (!strcmp(name, "disable-v17")) {
- if (switch_true(value))
- globals.disable_v17 = 1;
- else
- globals.disable_v17 = 0;
- } else if (!strcmp(name, "enable-t38")) {
- if (switch_true(value)) {
- globals.enable_t38= 1;
- } else {
- globals.enable_t38 = 0;
- }
- } else if (!strcmp(name, "enable-t38-request")) {
- if (switch_true(value)) {
- globals.enable_t38_request = 1;
- } else {
- globals.enable_t38_request = 0;
- }
- } else if (!strcmp(name, "ident")) {
- 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, "spool-dir")) {
- globals.spool = switch_core_strdup(globals.pool, value);
- } else if (!strcmp(name, "file-prefix")) {
- globals.prepend_string = switch_core_strdup(globals.pool, value);
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unknown parameter %s\n", name);
- }
-
- }
- }
-
- switch_xml_free(xml);
- }
-}
-
-static void event_handler(switch_event_t *event)
-{
- load_configuration(1);
-}
-
-
-
-
-
-
-typedef struct {
- switch_core_session_t *session;
- dtmf_rx_state_t *dtmf_detect;
-} switch_inband_dtmf_t;
-
-static switch_bool_t inband_dtmf_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type)
-{
- switch_inband_dtmf_t *pvt = (switch_inband_dtmf_t *) user_data;
- switch_frame_t *frame = NULL;
- char digit_str[80];
- switch_channel_t *channel = switch_core_session_get_channel(pvt->session);
-
- switch (type) {
- case SWITCH_ABC_TYPE_INIT:
- pvt->dtmf_detect = dtmf_rx_init(NULL, NULL, NULL);
- break;
- case SWITCH_ABC_TYPE_CLOSE:
- if (pvt->dtmf_detect) {
- dtmf_rx_free(pvt->dtmf_detect);
- }
- break;
- case SWITCH_ABC_TYPE_READ_REPLACE:
- if ((frame = switch_core_media_bug_get_read_replace_frame(bug))) {
- dtmf_rx(pvt->dtmf_detect, frame->data, frame->samples);
- dtmf_rx_get(pvt->dtmf_detect, digit_str, sizeof(digit_str));
- if (digit_str[0]) {
- char *p = digit_str;
- while (p && *p) {
- switch_dtmf_t dtmf = {0};
- dtmf.digit = *p;
- dtmf.duration = switch_core_default_dtmf_duration(0);
- switch_channel_queue_dtmf(channel, &dtmf);
- p++;
- }
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(switch_core_media_bug_get_session(bug)), SWITCH_LOG_DEBUG, "DTMF DETECTED: [%s]\n",
- digit_str);
- }
- switch_core_media_bug_set_read_replace_frame(bug, frame);
- }
- break;
- case SWITCH_ABC_TYPE_WRITE:
- default:
- break;
- }
-
- return SWITCH_TRUE;
-}
-
-switch_status_t spandsp_stop_inband_dtmf_session(switch_core_session_t *session)
-{
- switch_media_bug_t *bug;
- switch_channel_t *channel = switch_core_session_get_channel(session);
-
- if ((bug = switch_channel_get_private(channel, "dtmf"))) {
- switch_channel_set_private(channel, "dtmf", NULL);
- switch_core_media_bug_remove(session, &bug);
- return SWITCH_STATUS_SUCCESS;
- }
- return SWITCH_STATUS_FALSE;
-}
-
-switch_status_t spandsp_inband_dtmf_session(switch_core_session_t *session)
-{
- switch_channel_t *channel = switch_core_session_get_channel(session);
- switch_media_bug_t *bug;
- switch_status_t status;
- switch_inband_dtmf_t *pvt;
- switch_codec_implementation_t read_impl = { 0 };
-
- switch_core_session_get_read_impl(session, &read_impl);
-
- if (!(pvt = switch_core_session_alloc(session, sizeof(*pvt)))) {
- return SWITCH_STATUS_MEMERR;
- }
-
-
- pvt->session = session;
-
-
- if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) {
- return SWITCH_STATUS_FALSE;
- }
-
- if ((status = switch_core_media_bug_add(session, "spandsp_dtmf_detect", NULL,
- inband_dtmf_callback, pvt, 0, SMBF_READ_REPLACE, &bug)) != SWITCH_STATUS_SUCCESS) {
- return status;
- }
-
- switch_channel_set_private(channel, "dtmf", bug);
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-/* **************************************************************************
- FREESWITCH MODULE DEFINITIONS
- ************************************************************************* */
-
-#define SPANFAX_RX_USAGE ""
-#define SPANFAX_TX_USAGE ""
-
-SWITCH_MODULE_LOAD_FUNCTION(mod_fax_init);
-SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_fax_shutdown);
-SWITCH_MODULE_DEFINITION(mod_fax, mod_fax_init, mod_fax_shutdown, NULL);
-
-static switch_event_node_t *NODE = NULL;
-
-SWITCH_STANDARD_APP(spanfax_tx_function)
-{
- process_fax(session, data, FUNCTION_TX);
-}
-
-SWITCH_STANDARD_APP(spanfax_rx_function)
-{
- process_fax(session, data, FUNCTION_RX);
-}
-
-
-SWITCH_STANDARD_APP(dtmf_session_function)
-{
- spandsp_inband_dtmf_session(session);
-}
-
-SWITCH_STANDARD_APP(stop_dtmf_session_function)
-{
- spandsp_stop_inband_dtmf_session(session);
-}
-
-static const switch_state_handler_table_t t38_gateway_state_handlers;
-
-static switch_status_t t38_gateway_on_soft_execute(switch_core_session_t *session)
-{
- switch_core_session_t *other_session;
-
- switch_channel_t *other_channel, *channel = switch_core_session_get_channel(session);
- pvt_t *pvt;
- const char *peer_uuid = switch_channel_get_variable(channel, "t38_peer");
- switch_core_session_message_t msg = { 0 };
- switch_status_t status;
- switch_frame_t *read_frame = { 0 };
-
- if (!(other_session = switch_core_session_locate(peer_uuid))) {
- switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s Cannot locate channel with uuid %s",
- switch_channel_get_name(channel), peer_uuid);
- goto end;
- }
-
- other_channel = switch_core_session_get_channel(other_session);
-
- pvt = pvt_init(session, FUNCTION_GW);
- request_t38(pvt);
-
- msg.message_id = SWITCH_MESSAGE_INDICATE_BRIDGE;
- msg.from = __FILE__;
- msg.string_arg = peer_uuid;
- switch_core_session_receive_message(session, &msg);
-
- while (switch_channel_ready(channel) && switch_channel_up(other_channel) && !switch_channel_test_app_flag_key("T38", channel, CF_APP_T38)) {
- status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
-
- if (!SWITCH_READ_ACCEPTABLE(status) || pvt->done) {
- /* Our duty is over */
- goto end_unlock;
- }
-
- if (switch_test_flag(read_frame, SFF_CNG)) {
- continue;
- }
-
- if (switch_core_session_write_frame(other_session, read_frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) {
- goto end_unlock;
- }
- }
-
- if (!(switch_channel_ready(channel) && switch_channel_up(other_channel))) {
- goto end_unlock;
- }
-
- if (!switch_channel_test_app_flag_key("T38", channel, CF_APP_T38)) {
- switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s Could not negotiate T38\n", switch_channel_get_name(channel));
- goto end_unlock;
- }
-
- if (pvt->t38_mode == T38_MODE_REQUESTED) {
- spanfax_init(pvt, T38_GATEWAY_MODE);
- configure_t38(pvt);
- pvt->t38_mode = T38_MODE_NEGOTIATED;
- } else {
- if (negotiate_t38(pvt) != T38_MODE_NEGOTIATED) {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s Could not negotiate T38\n", switch_channel_get_name(channel));
- switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
- goto end_unlock;
- }
-
- spanfax_init(pvt, T38_GATEWAY_MODE);
- }
-
- /* This will change the rtp stack to udptl mode */
- msg.from = __FILE__;
- msg.message_id = SWITCH_MESSAGE_INDICATE_UDPTL_MODE;
- switch_core_session_receive_message(session, &msg);
-
-
- /* wake up the audio side */
- switch_channel_set_private(channel, "_t38_pvt", pvt);
- switch_channel_set_app_flag_key("T38", other_channel, CF_APP_T38);
-
-
- while (switch_channel_ready(channel) && switch_channel_up(other_channel)) {
-
- status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
-
- if (!SWITCH_READ_ACCEPTABLE(status) || pvt->done) {
- /* Our duty is over */
- goto end_unlock;
- }
-
- if (switch_test_flag(read_frame, SFF_CNG)) {
- continue;
- }
-
- if (switch_test_flag(read_frame, SFF_UDPTL_PACKET)) {
- udptl_rx_packet(pvt->udptl_state, read_frame->packet, read_frame->packetlen);
- }
- }
-
- end_unlock:
-
-
- msg.message_id = SWITCH_MESSAGE_INDICATE_UNBRIDGE;
- msg.from = __FILE__;
- msg.string_arg = peer_uuid;
- switch_core_session_receive_message(session, &msg);
-
- switch_channel_hangup(other_channel, SWITCH_CAUSE_NORMAL_CLEARING);
- switch_core_session_rwunlock(other_session);
-
- end:
-
- switch_channel_clear_state_handler(channel, &t38_gateway_state_handlers);
- switch_channel_set_variable(channel, "t38_peer", NULL);
-
- switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status_t t38_gateway_on_consume_media(switch_core_session_t *session)
-{
- switch_core_session_t *other_session;
- switch_channel_t *other_channel, *channel = switch_core_session_get_channel(session);
- const char *peer_uuid = switch_channel_get_variable(channel, "t38_peer");
- pvt_t *pvt = NULL;
- switch_codec_t read_codec = { 0 };
- switch_codec_t write_codec = { 0 };
- switch_frame_t *read_frame = { 0 };
- switch_frame_t write_frame = { 0 };
- switch_codec_implementation_t read_impl = { 0 };
- int16_t *buf = NULL;
- switch_status_t status;
- switch_size_t tx;
- const char *t38_trace = switch_channel_get_variable(channel, "t38_trace");
- char *trace_read, *trace_write;
- zap_socket_t read_fd = FAX_INVALID_SOCKET, write_fd = FAX_INVALID_SOCKET;
- switch_core_session_message_t msg = { 0 };
- switch_event_t *event;
-
- switch_core_session_get_read_impl(session, &read_impl);
-
- buf = switch_core_session_alloc(session, SWITCH_RECOMMENDED_BUFFER_SIZE);
-
- if (!(other_session = switch_core_session_locate(peer_uuid))) {
- switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
- goto end;
- }
-
- other_channel = switch_core_session_get_channel(other_session);
-
- msg.message_id = SWITCH_MESSAGE_INDICATE_BRIDGE;
- msg.from = __FILE__;
- msg.string_arg = peer_uuid;
- switch_core_session_receive_message(session, &msg);
-
- if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_BRIDGE) == SWITCH_STATUS_SUCCESS) {
- switch_channel_event_set_data(channel, event);
- switch_event_fire(&event);
- }
-
- while (switch_channel_ready(channel) && switch_channel_up(other_channel) && !switch_channel_test_app_flag_key("T38", channel, CF_APP_T38)) {
- status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
-
- if (!SWITCH_READ_ACCEPTABLE(status)) {
- /* Our duty is over */
- goto end_unlock;
- }
-
- if (switch_test_flag(read_frame, SFF_CNG)) {
- continue;
- }
-
- if (switch_core_session_write_frame(other_session, read_frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) {
- goto end_unlock;
- }
- }
-
- if (!(switch_channel_ready(channel) && switch_channel_up(other_channel))) {
- goto end_unlock;
- }
-
- if (!switch_channel_test_app_flag_key("T38", channel, CF_APP_T38)) {
- switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
- goto end_unlock;
- }
-
- if (!(pvt = switch_channel_get_private(other_channel, "_t38_pvt"))) {
- switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
- goto end_unlock;
- }
-
- if (switch_core_codec_init(&read_codec,
- "L16",
- NULL,
- read_impl.samples_per_second,
- read_impl.microseconds_per_packet / 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_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Raw read codec activation Success L16 %u\n",
- read_codec.implementation->microseconds_per_packet);
- switch_core_session_set_read_codec(session, &read_codec);
- } else {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Raw read codec activation Failed L16\n");
- goto end_unlock;
- }
-
- if (switch_core_codec_init(&write_codec,
- "L16",
- NULL,
- read_impl.samples_per_second,
- read_impl.microseconds_per_packet / 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_SESSION_LOG(session), 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 {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Raw write codec activation Failed L16\n");
- goto end_unlock;
- }
-
- switch_ivr_sleep(session, 0, SWITCH_TRUE, NULL);
-
- if (switch_true(t38_trace)) {
- trace_read = switch_core_session_sprintf(session, "%s%s%s_read.raw", SWITCH_GLOBAL_dirs.temp_dir,
- SWITCH_PATH_SEPARATOR, switch_core_session_get_uuid(session));
-
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Tracing inbound audio to %s\n", trace_read);
- switch_channel_set_variable(channel, "t38_trace_read", trace_read);
-
- trace_write = switch_core_session_sprintf(session, "%s%s%s_write.raw", SWITCH_GLOBAL_dirs.temp_dir,
- SWITCH_PATH_SEPARATOR, switch_core_session_get_uuid(session));
-
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Tracing outbound audio to %s\n", trace_write);
- switch_channel_set_variable(channel, "t38_trace_read", trace_write);
-
-
- if ((write_fd = open(trace_read, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)) != FAX_INVALID_SOCKET) {
- if ((read_fd = open(trace_write, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)) == FAX_INVALID_SOCKET) {
- close(write_fd);
- write_fd = FAX_INVALID_SOCKET;
- }
- }
- }
-
- while (switch_channel_ready(channel) && switch_channel_up(other_channel)) {
- status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
-
- if (!SWITCH_READ_ACCEPTABLE(status) || pvt->done) {
- /* Our duty is over */
- goto end_unlock;
- }
-
-
- /* Skip CNG frames (auto-generated by FreeSWITCH, usually) */
- if (!switch_test_flag(read_frame, SFF_CNG)) {
-
- if (read_fd != FAX_INVALID_SOCKET) {
- int w = write(read_fd, read_frame->data, read_frame->datalen);
- if (w <= 0) {
- close(read_fd);
- read_fd = FAX_INVALID_SOCKET;
- }
- }
- if (t38_gateway_rx(pvt->t38_gateway_state, (int16_t *) read_frame->data, read_frame->samples)) {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "fax_rx reported an error\n");
- goto end_unlock;
- }
- }
-
- if ((tx = t38_gateway_tx(pvt->t38_gateway_state, buf, write_codec.implementation->samples_per_packet)) < 0) {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "fax_tx reported an error\n");
- goto end_unlock;
- }
-
- if (!tx) {
- /* switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "No audio samples to send\n"); */
- continue;
- } else {
- /* Set our write_frame data */
- write_frame.datalen = tx * sizeof(int16_t);
- write_frame.samples = tx;
- }
-
- if (write_fd != FAX_INVALID_SOCKET) {
- int w = write(write_fd, write_frame.data, write_frame.datalen);
- if (w <= 0) {
- close(write_fd);
- write_fd = FAX_INVALID_SOCKET;
- }
- }
-
- if (switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) {
- goto end_unlock;
- }
- }
-
- end_unlock:
-
- msg.message_id = SWITCH_MESSAGE_INDICATE_UNBRIDGE;
- msg.from = __FILE__;
- msg.string_arg = peer_uuid;
- switch_core_session_receive_message(session, &msg);
-
-
- if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_UNBRIDGE) == SWITCH_STATUS_SUCCESS) {
- switch_channel_event_set_data(channel, event);
- switch_event_fire(&event);
- }
-
- if (read_fd != FAX_INVALID_SOCKET) {
- close(read_fd);
- read_fd = FAX_INVALID_SOCKET;
- }
-
- if (write_fd != FAX_INVALID_SOCKET) {
- close(write_fd);
- write_fd = FAX_INVALID_SOCKET;
- }
-
-
- switch_channel_hangup(other_channel, SWITCH_CAUSE_NORMAL_CLEARING);
- switch_core_session_rwunlock(other_session);
-
- switch_core_session_set_read_codec(session, NULL);
-
- if (switch_core_codec_ready(&read_codec)) {
- switch_core_codec_destroy(&read_codec);
- }
-
- if (switch_core_codec_ready(&write_codec)) {
- switch_core_codec_destroy(&write_codec);
- }
-
-
- end:
-
- switch_channel_clear_state_handler(channel, &t38_gateway_state_handlers);
- switch_channel_set_variable(channel, "t38_peer", NULL);
- switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status_t t38_gateway_on_reset(switch_core_session_t *session)
-{
- switch_channel_t *channel = switch_core_session_get_channel(session);
-
- switch_channel_set_variable(channel, "rtp_autoflush_during_bridge", "false");
-
- switch_channel_clear_flag(channel, CF_REDIRECT);
-
- if (switch_channel_test_app_flag(channel, CF_APP_TAGGED)) {
- switch_channel_clear_app_flag(channel, CF_APP_TAGGED);
- switch_channel_set_state(channel, CS_CONSUME_MEDIA);
- } else {
- switch_channel_set_state(channel, CS_SOFT_EXECUTE);
- }
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-static const switch_state_handler_table_t t38_gateway_state_handlers = {
- /*.on_init */ NULL,
- /*.on_routing */ NULL,
- /*.on_execute */ NULL,
- /*.on_hangup */ NULL,
- /*.on_exchange_media */ NULL,
- /*.on_soft_execute */ t38_gateway_on_soft_execute,
- /*.on_consume_media */ t38_gateway_on_consume_media,
- /*.on_hibernate */ NULL,
- /*.on_reset */ t38_gateway_on_reset,
- /*.on_park */ NULL,
- /*.on_reporting */ NULL,
- /*.on_destroy */ NULL,
- SSH_FLAG_STICKY
-};
-
-static switch_bool_t t38_gateway_start(switch_core_session_t *session, const char *app, const char *data)
-{
- switch_channel_t *other_channel = NULL, *channel = switch_core_session_get_channel(session);
- switch_core_session_t *other_session = NULL;
- int peer = app && !strcasecmp(app, "peer");
-
- if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) {
- other_channel = switch_core_session_get_channel(other_session);
-
- switch_channel_set_variable(channel, "t38_peer", switch_core_session_get_uuid(other_session));
- switch_channel_set_variable(other_channel, "t38_peer", switch_core_session_get_uuid(session));
-
-
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s starting gateway mode to %s\n",
- switch_channel_get_name(peer ? channel : other_channel),
- switch_channel_get_name(peer ? other_channel : channel));
-
-
- switch_channel_clear_state_handler(channel, NULL);
- switch_channel_clear_state_handler(other_channel, NULL);
-
- switch_channel_add_state_handler(channel, &t38_gateway_state_handlers);
- switch_channel_add_state_handler(other_channel, &t38_gateway_state_handlers);
-
- switch_channel_set_app_flag(peer ? channel : other_channel, CF_APP_TAGGED);
- switch_channel_clear_app_flag(peer ? other_channel : channel, CF_APP_TAGGED);
-
- switch_channel_set_flag(channel, CF_REDIRECT);
- switch_channel_set_state(channel, CS_RESET);
-
- switch_channel_set_flag(other_channel, CF_REDIRECT);
- switch_channel_set_state(other_channel, CS_RESET);
-
- switch_core_session_rwunlock(other_session);
-
- }
-
- return SWITCH_FALSE;
-}
-
-
-SWITCH_STANDARD_APP(t38_gateway_function)
-{
- switch_channel_t *channel = switch_core_session_get_channel(session);
- time_t timeout = switch_epoch_time_now(NULL) + 20;
- const char *var;
-
- if (zstr(data) || strcasecmp(data, "self")) {
- data = "peer";
- }
-
- switch_channel_set_variable(channel, "t38_leg", data);
-
- if ((var = switch_channel_get_variable(channel, "t38_gateway_detect_timeout"))) {
- long to = atol(var);
- if (to > -1) {
- timeout = (time_t) (switch_epoch_time_now(NULL) + to);
- } else {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s invalid timeout value.\n", switch_channel_get_name(channel));
- }
- }
-
- switch_ivr_tone_detect_session(session, "t38", "1100.0", "rw", timeout, 1, data, NULL, t38_gateway_start);
-}
-
-
-SWITCH_MODULE_LOAD_FUNCTION(mod_fax_init)
-{
- switch_application_interface_t *app_interface;
-
- *module_interface = switch_loadable_module_create_module_interface(pool, modname);
-
- SWITCH_ADD_APP(app_interface, "t38_gateway", "Convert to T38 Gateway if tones are heard", "Convert to T38 Gateway if tones are heard",
- t38_gateway_function, "", SAF_MEDIA_TAP);
-
- 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);
-
- SWITCH_ADD_APP(app_interface, "spandsp_stop_dtmf", "stop inband dtmf", "Stop detecting inband dtmf.", stop_dtmf_session_function, "", SAF_NONE);
- SWITCH_ADD_APP(app_interface, "spandsp_start_dtmf", "Detect dtmf", "Detect inband dtmf on the session", dtmf_session_function, "", SAF_MEDIA_TAP);
-
- memset(&globals, 0, sizeof(globals));
- memset(&t38_state_list, 0, sizeof(t38_state_list));
- switch_core_new_memory_pool(&globals.pool);
- switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, globals.pool);
- switch_mutex_init(&t38_state_list.mutex, SWITCH_MUTEX_NESTED, globals.pool);
-
- globals.enable_t38 = 1;
- globals.total_sessions = 0;
- globals.verbose = 1;
- globals.use_ecm = 1;
- globals.disable_v17 = 0;
- globals.prepend_string = switch_core_strdup(globals.pool, "fax");
- globals.spool = switch_core_strdup(globals.pool, "/tmp");
- strncpy(globals.ident, "SpanDSP Fax Ident", sizeof(globals.ident) - 1);
- strncpy(globals.header, "SpanDSP Fax Header", sizeof(globals.header) - 1);
-
- load_configuration(0);
-
- 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 [%s]\n", SPANDSP_RELEASE_DATETIME_STRING);
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_fax_shutdown)
-{
- switch_memory_pool_t *pool = globals.pool;
-
- switch_event_unbind(&NODE);
-
- switch_core_destroy_memory_pool(&pool);
- memset(&globals, 0, sizeof(globals));
-
- return SWITCH_STATUS_UNLOAD;
-}
-
-/* For Emacs:
- * Local Variables:
- * mode:c
- * indent-tabs-mode:nil
- * tab-width:4
- * c-basic-offset:4
- * End:
- * For VIM:
- * vim:set softtabstop=4 shiftwidth=4 tabstop=4:
- */
diff --git a/src/mod/applications/mod_fax/udptl.c b/src/mod/applications/mod_fax/udptl.c
deleted file mode 100644
index a2651513f0..0000000000
--- a/src/mod/applications/mod_fax/udptl.c
+++ /dev/null
@@ -1,563 +0,0 @@
-//#define UDPTL_DEBUG
-/*
- * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- * Copyright (C) 2009, Steve Underwood
- *
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * Contributor(s):
- *
- * Steve Underwood
- *
- * udptl.c -- UDPTL handling for T.38
- *
- */
-
-#include
-#include
-#include
-#include
-#include
-
-#include "udptl.h"
-
-#define FALSE 0
-#define TRUE (!FALSE)
-
-static int decode_length(const uint8_t *buf, int limit, int *len, int *pvalue)
-{
- if (*len >= limit)
- return -1;
- if ((buf[*len] & 0x80) == 0) {
- *pvalue = buf[(*len)++];
- return 0;
- }
- if ((buf[*len] & 0x40) == 0) {
- if (*len >= limit - 1)
- return -1;
- *pvalue = (buf[(*len)++] & 0x3F) << 8;
- *pvalue |= buf[(*len)++];
- return 0;
- }
- *pvalue = (buf[(*len)++] & 0x3F) << 14;
- /* Indicate we have a fragment */
- return 1;
-}
-
-/*- End of function --------------------------------------------------------*/
-
-static int decode_open_type(const uint8_t *buf, int limit, int *len, const uint8_t ** p_object, int *p_num_octets)
-{
- int octet_cnt;
- int octet_idx;
- int stat;
- int i;
- const uint8_t **pbuf;
-
- for (octet_idx = 0, *p_num_octets = 0;; octet_idx += octet_cnt) {
- if ((stat = decode_length(buf, limit, len, &octet_cnt)) < 0)
- return -1;
- if (octet_cnt > 0) {
- *p_num_octets += octet_cnt;
-
- pbuf = &p_object[octet_idx];
- i = 0;
- /* Make sure the buffer contains at least the number of bits requested */
- if ((*len + octet_cnt) > limit)
- return -1;
-
- *pbuf = &buf[*len];
- *len += octet_cnt;
- }
- if (stat == 0)
- break;
- }
- return 0;
-}
-
-/*- End of function --------------------------------------------------------*/
-
-static int encode_length(uint8_t *buf, int *len, int value)
-{
- int multiplier;
-
- if (value < 0x80) {
- /* 1 octet */
- buf[(*len)++] = value;
- return value;
- }
- if (value < 0x4000) {
- /* 2 octets */
- /* Set the first bit of the first octet */
- buf[(*len)++] = ((0x8000 | value) >> 8) & 0xFF;
- buf[(*len)++] = value & 0xFF;
- return value;
- }
- /* Fragmentation */
- multiplier = (value < 0x10000) ? (value >> 14) : 4;
- /* Set the first 2 bits of the octet */
- buf[(*len)++] = 0xC0 | multiplier;
- return multiplier << 14;
-}
-
-/*- End of function --------------------------------------------------------*/
-
-static int encode_open_type(uint8_t *buf, int *len, const uint8_t *data, int num_octets)
-{
- int enclen;
- int octet_idx;
- uint8_t zero_byte;
-
- /* If open type is of zero length, add a single zero byte (10.1) */
- if (num_octets == 0) {
- zero_byte = 0;
- data = &zero_byte;
- num_octets = 1;
- }
- /* Encode the open type */
- for (octet_idx = 0;; num_octets -= enclen, octet_idx += enclen) {
- if ((enclen = encode_length(buf, len, num_octets)) < 0)
- return -1;
- if (enclen > 0) {
- memcpy(&buf[*len], &data[octet_idx], enclen);
- *len += enclen;
- }
- if (enclen >= num_octets)
- break;
- }
-
- return 0;
-}
-
-/*- End of function --------------------------------------------------------*/
-
-int udptl_rx_packet(udptl_state_t *s, const uint8_t buf[], int len)
-{
- int stat;
- int stat2;
- int i;
- int j;
- int k;
- int l;
- int m;
- int x;
- int limit;
- int which;
- int ptr;
- int count;
- int total_count;
- int seq_no;
- const uint8_t *msg;
- const uint8_t *data;
- int msg_len;
- int repaired[16];
- const uint8_t *bufs[16];
- int lengths[16];
- int span;
- int entries;
-
- ptr = 0;
- /* Decode seq_number */
- if (ptr + 2 > len)
- return -1;
- seq_no = (buf[0] << 8) | buf[1];
- ptr += 2;
- /* Break out the primary packet */
- if ((stat = decode_open_type(buf, len, &ptr, &msg, &msg_len)) != 0)
- return -1;
- /* Decode error_recovery */
- if (ptr + 1 > len)
- return -1;
- /* Our buffers cannot tolerate overlength packets */
- if (msg_len > LOCAL_FAX_MAX_DATAGRAM)
- return -1;
- /* Update any missed slots in the buffer */
- for (i = s->rx_seq_no; seq_no > i; i++) {
- x = i & UDPTL_BUF_MASK;
- s->rx[x].buf_len = -1;
- s->rx[x].fec_len[0] = 0;
- s->rx[x].fec_span = 0;
- s->rx[x].fec_entries = 0;
- }
- /* Save the new packet. Pure redundancy mode won't use this, but some systems will switch
- into FEC mode after sending some redundant packets. */
- x = seq_no & UDPTL_BUF_MASK;
- memcpy(s->rx[x].buf, msg, msg_len);
- s->rx[x].buf_len = msg_len;
- s->rx[x].fec_len[0] = 0;
- s->rx[x].fec_span = 0;
- s->rx[x].fec_entries = 0;
- if ((buf[ptr++] & 0x80) == 0) {
- /* Secondary packet mode for error recovery */
- /* We might have the packet we want, but we need to check through
- the redundant stuff, and verify the integrity of the UDPTL.
- This greatly reduces our chances of accepting garbage. */
- total_count = 0;
- do {
- if ((stat2 = decode_length(buf, len, &ptr, &count)) < 0)
- return -1;
- for (i = 0; i < count; i++) {
- if ((stat = decode_open_type(buf, len, &ptr, &bufs[total_count + i], &lengths[total_count + i])) != 0)
- return -1;
- }
- total_count += count;
- }
- while (stat2 > 0);
- /* We should now be exactly at the end of the packet. If not, this is a fault. */
- if (ptr != len)
- return -1;
- if (seq_no > s->rx_seq_no) {
- /* We received a later packet than we expected, so we need to check if we can fill in the gap from the
- secondary packets. */
- /* Step through in reverse order, so we go oldest to newest */
- for (i = total_count; i > 0; i--) {
- if (seq_no - i >= s->rx_seq_no) {
- /* This one wasn't seen before */
- /* Decode the secondary packet */
-#if defined(UDPTL_DEBUG)
- fprintf(stderr, "Secondary %d, len %d\n", seq_no - i, lengths[i - 1]);
-#endif
- /* Save the new packet. Redundancy mode won't use this, but some systems will switch into
- FEC mode after sending some redundant packets, and this may then be important. */
- x = (seq_no - i) & UDPTL_BUF_MASK;
- memcpy(s->rx[x].buf, bufs[i - 1], lengths[i - 1]);
- s->rx[x].buf_len = lengths[i - 1];
- s->rx[x].fec_len[0] = 0;
- s->rx[x].fec_span = 0;
- s->rx[x].fec_entries = 0;
- if (s->rx_packet_handler(s->user_data, bufs[i - 1], lengths[i - 1], seq_no - i) < 0)
- fprintf(stderr, "Bad IFP\n");
- }
- }
- }
- } else {
- /* FEC mode for error recovery */
-
- /* Decode the FEC packets */
- /* The span is defined as an unconstrained integer, but will never be more
- than a small value. */
- if (ptr + 2 > len)
- return -1;
- if (buf[ptr++] != 1)
- return -1;
- span = buf[ptr++];
-
- x = seq_no & UDPTL_BUF_MASK;
-
- s->rx[x].fec_span = span;
-
- memset(repaired, 0, sizeof(repaired));
- repaired[x] = TRUE;
-
- /* The number of entries is defined as a length, but will only ever be a small
- value. Treat it as such. */
- if (ptr + 1 > len)
- return -1;
- entries = buf[ptr++];
- s->rx[x].fec_entries = entries;
-
- /* Decode the elements */
- for (i = 0; i < entries; i++) {
- if ((stat = decode_open_type(buf, len, &ptr, &data, &s->rx[x].fec_len[i])) != 0)
- return -1;
- if (s->rx[x].fec_len[i] > LOCAL_FAX_MAX_DATAGRAM)
- return -1;
-
- /* Save the new FEC data */
- memcpy(s->rx[x].fec[i], data, s->rx[x].fec_len[i]);
-#if 0
- fprintf(stderr, "FEC: ");
- for (j = 0; j < s->rx[x].fec_len[i]; j++)
- fprintf(stderr, "%02X ", data[j]);
- fprintf(stderr, "\n");
-#endif
- }
- /* We should now be exactly at the end of the packet. If not, this is a fault. */
- if (ptr != len)
- return -1;
- /* See if we can reconstruct anything which is missing */
- /* TODO: this does not comprehensively hunt back and repair everything that is possible */
- for (l = x; l != ((x - (16 - span * entries)) & UDPTL_BUF_MASK); l = (l - 1) & UDPTL_BUF_MASK) {
- if (s->rx[l].fec_len[0] <= 0)
- continue;
- for (m = 0; m < s->rx[l].fec_entries; m++) {
- limit = (l + m) & UDPTL_BUF_MASK;
- for (which = -1, k = (limit - s->rx[l].fec_span * s->rx[l].fec_entries) & UDPTL_BUF_MASK; k != limit;
- k = (k + s->rx[l].fec_entries) & UDPTL_BUF_MASK) {
- if (s->rx[k].buf_len <= 0)
- which = (which == -1) ? k : -2;
- }
- if (which >= 0) {
- /* Repairable */
- for (j = 0; j < s->rx[l].fec_len[m]; j++) {
- s->rx[which].buf[j] = s->rx[l].fec[m][j];
- for (k = (limit - s->rx[l].fec_span * s->rx[l].fec_entries) & UDPTL_BUF_MASK; k != limit;
- k = (k + s->rx[l].fec_entries) & UDPTL_BUF_MASK)
- s->rx[which].buf[j] ^= (s->rx[k].buf_len > j) ? s->rx[k].buf[j] : 0;
- }
- s->rx[which].buf_len = s->rx[l].fec_len[m];
- repaired[which] = TRUE;
- }
- }
- }
- /* Now play any new packets forwards in time */
- for (l = (x + 1) & UDPTL_BUF_MASK, j = seq_no - UDPTL_BUF_MASK; l != x; l = (l + 1) & UDPTL_BUF_MASK, j++) {
- if (repaired[l]) {
-#if defined(UDPTL_DEBUG)
- fprintf(stderr, "Fixed packet %d, len %d\n", j, l);
-#endif
- if (s->rx_packet_handler(s->user_data, s->rx[l].buf, s->rx[l].buf_len, j) < 0)
- fprintf(stderr, "Bad IFP\n");
- }
- }
- }
- /* If packets are received out of sequence, we may have already processed this packet from the error
- recovery information in a packet already received. */
- if (seq_no >= s->rx_seq_no) {
- /* Decode the primary packet */
-#if defined(UDPTL_DEBUG)
- fprintf(stderr, "Primary packet %d, len %d\n", seq_no, msg_len);
-#endif
- if (s->rx_packet_handler(s->user_data, msg, msg_len, seq_no) < 0)
- fprintf(stderr, "Bad IFP\n");
- }
-
- s->rx_seq_no = (seq_no + 1) & 0xFFFF;
- return 0;
-}
-
-/*- End of function --------------------------------------------------------*/
-
-int udptl_build_packet(udptl_state_t *s, uint8_t buf[], const uint8_t msg[], int msg_len)
-{
- uint8_t fec[LOCAL_FAX_MAX_DATAGRAM];
- int i;
- int j;
- int seq;
- int entry;
- int entries;
- int span;
- int m;
- int len;
- int limit;
- int high_tide;
-
- /* UDPTL cannot cope with zero length messages, and our buffering for redundancy limits their
- maximum length. */
- if (msg_len < 1 || msg_len > LOCAL_FAX_MAX_DATAGRAM)
- return -1;
- seq = s->tx_seq_no & 0xFFFF;
-
- /* Map the sequence number to an entry in the circular buffer */
- entry = seq & UDPTL_BUF_MASK;
-
- /* We save the message in a circular buffer, for generating FEC or
- redundancy sets later on. */
- s->tx[entry].buf_len = msg_len;
- memcpy(s->tx[entry].buf, msg, msg_len);
-
- /* Build the UDPTL packet */
-
- len = 0;
- /* Encode the sequence number */
- buf[len++] = (seq >> 8) & 0xFF;
- buf[len++] = seq & 0xFF;
-
- /* Encode the primary packet */
- if (encode_open_type(buf, &len, msg, msg_len) < 0)
- return -1;
-
- /* Encode the appropriate type of error recovery information */
- switch (s->error_correction_scheme) {
- case UDPTL_ERROR_CORRECTION_NONE:
- /* Encode the error recovery type */
- buf[len++] = 0x00;
- /* The number of entries will always be zero, so it is pointless allowing
- for the fragmented case here. */
- if (encode_length(buf, &len, 0) < 0)
- return -1;
- break;
- case UDPTL_ERROR_CORRECTION_REDUNDANCY:
- /* Encode the error recovery type */
- buf[len++] = 0x00;
- if (s->tx_seq_no > s->error_correction_entries)
- entries = s->error_correction_entries;
- else
- entries = s->tx_seq_no;
- /* The number of entries will always be small, so it is pointless allowing
- for the fragmented case here. */
- if (encode_length(buf, &len, entries) < 0)
- return -1;
- /* Encode the elements */
- for (i = 0; i < entries; i++) {
- j = (entry - i - 1) & UDPTL_BUF_MASK;
- if (encode_open_type(buf, &len, s->tx[j].buf, s->tx[j].buf_len) < 0)
- return -1;
- }
- break;
- case UDPTL_ERROR_CORRECTION_FEC:
- span = s->error_correction_span;
- entries = s->error_correction_entries;
- if (seq < s->error_correction_span * s->error_correction_entries) {
- /* In the initial stages, wind up the FEC smoothly */
- entries = seq / s->error_correction_span;
- if (seq < s->error_correction_span)
- span = 0;
- }
- /* Encode the error recovery type */
- buf[len++] = 0x80;
- /* Span is defined as an inconstrained integer, which it dumb. It will only
- ever be a small value. Treat it as such. */
- buf[len++] = 1;
- buf[len++] = span;
- /* The number of entries is defined as a length, but will only ever be a small
- value. Treat it as such. */
- buf[len++] = entries;
- for (m = 0; m < entries; m++) {
- /* Make an XOR'ed entry the maximum length */
- limit = (entry + m) & UDPTL_BUF_MASK;
- high_tide = 0;
- for (i = (limit - span * entries) & UDPTL_BUF_MASK; i != limit; i = (i + entries) & UDPTL_BUF_MASK) {
- if (high_tide < s->tx[i].buf_len) {
- for (j = 0; j < high_tide; j++)
- fec[j] ^= s->tx[i].buf[j];
- for (; j < s->tx[i].buf_len; j++)
- fec[j] = s->tx[i].buf[j];
- high_tide = s->tx[i].buf_len;
- } else {
- for (j = 0; j < s->tx[i].buf_len; j++)
- fec[j] ^= s->tx[i].buf[j];
- }
- }
- if (encode_open_type(buf, &len, fec, high_tide) < 0)
- return -1;
- }
- break;
- }
-
- if (s->verbose)
- fprintf(stderr, "\n");
- s->tx_seq_no++;
- return len;
-}
-
-/*- End of function --------------------------------------------------------*/
-
-int udptl_set_error_correction(udptl_state_t *s, int ec_scheme, int span, int entries)
-{
- switch (ec_scheme) {
- case UDPTL_ERROR_CORRECTION_FEC:
- case UDPTL_ERROR_CORRECTION_REDUNDANCY:
- case UDPTL_ERROR_CORRECTION_NONE:
- s->error_correction_scheme = ec_scheme;
- break;
- case -1:
- /* Just don't change the scheme */
- break;
- default:
- return -1;
- }
- if (span >= 0)
- s->error_correction_span = span;
- if (entries >= 0)
- s->error_correction_entries = entries;
- return 0;
-}
-
-/*- End of function --------------------------------------------------------*/
-
-int udptl_get_error_correction(udptl_state_t *s, int *ec_scheme, int *span, int *entries)
-{
- if (ec_scheme)
- *ec_scheme = s->error_correction_scheme;
- if (span)
- *span = s->error_correction_span;
- if (entries)
- *entries = s->error_correction_entries;
- return 0;
-}
-
-/*- End of function --------------------------------------------------------*/
-
-int udptl_set_local_max_datagram(udptl_state_t *s, int max_datagram)
-{
- s->local_max_datagram_size = max_datagram;
- return 0;
-}
-
-/*- End of function --------------------------------------------------------*/
-
-int udptl_get_local_max_datagram(udptl_state_t *s)
-{
- return s->local_max_datagram_size;
-}
-
-/*- End of function --------------------------------------------------------*/
-
-int udptl_set_far_max_datagram(udptl_state_t *s, int max_datagram)
-{
- s->far_max_datagram_size = max_datagram;
- return 0;
-}
-
-/*- End of function --------------------------------------------------------*/
-
-int udptl_get_far_max_datagram(udptl_state_t *s)
-{
- return s->far_max_datagram_size;
-}
-
-/*- End of function --------------------------------------------------------*/
-
-udptl_state_t *udptl_init(udptl_state_t *s, int ec_scheme, int span, int entries, udptl_rx_packet_handler_t rx_packet_handler, void *user_data)
-{
- int i;
-
- if (rx_packet_handler == NULL)
- return NULL;
-
- if (s == NULL) {
- if ((s = (udptl_state_t *) malloc(sizeof(*s))) == NULL)
- return NULL;
- }
- memset(s, 0, sizeof(*s));
-
- s->error_correction_scheme = ec_scheme;
- s->error_correction_span = span;
- s->error_correction_entries = entries;
-
- s->far_max_datagram_size = LOCAL_FAX_MAX_DATAGRAM;
- s->local_max_datagram_size = LOCAL_FAX_MAX_DATAGRAM;
-
- memset(&s->rx, 0, sizeof(s->rx));
- memset(&s->tx, 0, sizeof(s->tx));
- for (i = 0; i <= UDPTL_BUF_MASK; i++) {
- s->rx[i].buf_len = -1;
- s->tx[i].buf_len = -1;
- }
-
- s->rx_packet_handler = rx_packet_handler;
- s->user_data = user_data;
-
- return s;
-}
-
-/*- End of function --------------------------------------------------------*/
-
-int udptl_release(udptl_state_t *s)
-{
- return 0;
-}
-
-/*- End of function --------------------------------------------------------*/
-/*- End of file ------------------------------------------------------------*/
diff --git a/src/mod/applications/mod_fax/udptl.h b/src/mod/applications/mod_fax/udptl.h
deleted file mode 100644
index 39740353d1..0000000000
--- a/src/mod/applications/mod_fax/udptl.h
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- * Copyright (C) 2009, Steve Underwood
- *
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * Contributor(s):
- *
- * Steve Underwood
- *
- * udptl.h -- UDPTL handling for T.38
- *
- */
-
-#if !defined(FREESWITCH_UDPTL_H)
-#define FREESWITCH_UDPTL_H
-
-#define LOCAL_FAX_MAX_DATAGRAM 400
-#define LOCAL_FAX_MAX_FEC_PACKETS 5
-
-#define UDPTL_BUF_MASK 15
-
-typedef int (udptl_rx_packet_handler_t) (void *user_data, const uint8_t msg[], int len, int seq_no);
-
-typedef struct {
- int buf_len;
- uint8_t buf[LOCAL_FAX_MAX_DATAGRAM];
-} udptl_fec_tx_buffer_t;
-
-typedef struct {
- int buf_len;
- uint8_t buf[LOCAL_FAX_MAX_DATAGRAM];
- int fec_len[LOCAL_FAX_MAX_FEC_PACKETS];
- uint8_t fec[LOCAL_FAX_MAX_FEC_PACKETS][LOCAL_FAX_MAX_DATAGRAM];
- int fec_span;
- int fec_entries;
-} udptl_fec_rx_buffer_t;
-
-struct udptl_state_s {
- udptl_rx_packet_handler_t *rx_packet_handler;
- void *user_data;
-
- /*! This option indicates the error correction scheme used in transmitted UDPTL
- packets. */
- int error_correction_scheme;
-
- /*! This option indicates the number of error correction entries transmitted in
- UDPTL packets. */
- int error_correction_entries;
-
- /*! This option indicates the span of the error correction entries in transmitted
- UDPTL packets (FEC only). */
- int error_correction_span;
-
- /*! This option indicates the maximum size of a datagram that can be accepted by
- the remote device. */
- int far_max_datagram_size;
-
- /*! This option indicates the maximum size of a datagram that we are prepared to
- accept. */
- int local_max_datagram_size;
-
- int verbose;
-
- int tx_seq_no;
- int rx_seq_no;
- int rx_expected_seq_no;
-
- udptl_fec_tx_buffer_t tx[UDPTL_BUF_MASK + 1];
- udptl_fec_rx_buffer_t rx[UDPTL_BUF_MASK + 1];
-};
-
-enum {
- UDPTL_ERROR_CORRECTION_NONE,
- UDPTL_ERROR_CORRECTION_FEC,
- UDPTL_ERROR_CORRECTION_REDUNDANCY
-};
-
-typedef struct udptl_state_s udptl_state_t;
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-/*! \brief Process an arriving UDPTL packet.
- \param s The UDPTL context.
- \param buf The UDPTL packet buffer.
- \param len The length of the packet.
- \return 0 for OK. */
- int udptl_rx_packet(udptl_state_t *s, const uint8_t buf[], int len);
-
-/*! \brief Construct a UDPTL packet, ready for transmission.
- \param s The UDPTL context.
- \param buf The UDPTL packet buffer.
- \param msg The primary packet.
- \param len The length of the primary packet.
- \return The length of the constructed UDPTL packet. */
- int udptl_build_packet(udptl_state_t *s, uint8_t buf[], const uint8_t msg[], int msg_len);
-
-/*! \brief Change the error correction settings of a UDPTL context.
- \param s The UDPTL context.
- \param ec_scheme One of the optional error correction schemes.
- \param span The packet span over which error correction should be applied.
- \param entries The number of error correction entries to include in packets.
- \return 0 for OK. */
- int udptl_set_error_correction(udptl_state_t *s, int ec_scheme, int span, int entries);
-
-/*! \brief Check the error correction settings of a UDPTL context.
- \param s The UDPTL context.
- \param ec_scheme One of the optional error correction schemes.
- \param span The packet span over which error correction is being applied.
- \param entries The number of error correction being included in packets.
- \return 0 for OK. */
- int udptl_get_error_correction(udptl_state_t *s, int *ec_scheme, int *span, int *entries);
-
- int udptl_set_local_max_datagram(udptl_state_t *s, int max_datagram);
-
- int udptl_get_local_max_datagram(udptl_state_t *s);
-
- int udptl_set_far_max_datagram(udptl_state_t *s, int max_datagram);
-
- int udptl_get_far_max_datagram(udptl_state_t *s);
-
-/*! \brief Initialise a UDPTL context.
- \param s The UDPTL context.
- \param ec_scheme One of the optional error correction schemes.
- \param span The packet span over which error correction should be applied.
- \param entries The number of error correction entries to include in packets.
- \param rx_packet_handler The callback function, used to report arriving IFP packets.
- \param user_data An opaque pointer supplied to rx_packet_handler.
- \return A pointer to the UDPTL context, or NULL if there was a problem. */
- udptl_state_t *udptl_init(udptl_state_t *s, int ec_scheme, int span, int entries, udptl_rx_packet_handler_t rx_packet_handler, void *user_data);
-
-/*! \brief Release a UDPTL context.
- \param s The UDPTL context.
- \return 0 for OK. */
- int udptl_release(udptl_state_t *s);
-
-#if defined(__cplusplus)
-}
-#endif
-#endif
-/*- End of file ------------------------------------------------------------*/