FS-3252 additional fix to this bug and add better fax detect code to mod_spandsp
This commit is contained in:
parent
9227b53872
commit
7fe313cf3d
|
@ -70,11 +70,46 @@ SWITCH_STANDARD_APP(stop_dtmf_session_function)
|
|||
spandsp_stop_inband_dtmf_session(session);
|
||||
}
|
||||
|
||||
|
||||
SWITCH_STANDARD_APP(spandsp_fax_detect_session_function)
|
||||
{
|
||||
int argc = 0;
|
||||
char *argv[3] = { 0 };
|
||||
char *dupdata;
|
||||
const char *app = NULL, *arg = NULL;
|
||||
int timeout = 0;
|
||||
|
||||
if (!zstr(data) && (dupdata = switch_core_session_strdup(session, data))) {
|
||||
if ((argc = switch_split(dupdata, ' ', argv)) == 3) {
|
||||
app = argv[0];
|
||||
arg = argv[1];
|
||||
timeout = atoi(argv[2]);
|
||||
if (timeout < 0) {
|
||||
timeout = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (app) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Enabling fax detection '%s' '%s'\n", argv[0], argv[1]);
|
||||
spandsp_fax_detect_session(session, "rw", timeout, 1, app, arg, NULL);
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot Enable fax detection '%s' '%s'\n", argv[0], argv[1]);
|
||||
}
|
||||
}
|
||||
|
||||
SWITCH_STANDARD_APP(spandsp_stop_fax_detect_session_function)
|
||||
{
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Disabling fax detection\n");
|
||||
spandsp_fax_stop_detect_session(session);
|
||||
}
|
||||
|
||||
static void event_handler(switch_event_t *event)
|
||||
{
|
||||
mod_spandsp_fax_event_handler(event);
|
||||
}
|
||||
|
||||
|
||||
SWITCH_STANDARD_APP(t38_gateway_function)
|
||||
{
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
|
@ -83,10 +118,19 @@ SWITCH_STANDARD_APP(t38_gateway_function)
|
|||
int argc = 0;
|
||||
char *argv[2] = { 0 };
|
||||
char *dupdata;
|
||||
const char *direction = argv[0], *flags = argv[1];
|
||||
const char *direction = NULL, *flags = NULL;
|
||||
|
||||
dupdata = switch_core_session_strdup(session, data);
|
||||
argc = switch_split(dupdata, ' ', argv);
|
||||
if (!zstr(data) && (dupdata = switch_core_session_strdup(session, data))) {
|
||||
if ((argc = switch_split(dupdata, ' ', argv))) {
|
||||
if (argc > 0) {
|
||||
direction = argv[0];
|
||||
}
|
||||
|
||||
if (argc > 1) {
|
||||
flags = argv[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (zstr(direction) || strcasecmp(direction, "self")) {
|
||||
direction = "peer";
|
||||
|
@ -106,7 +150,8 @@ SWITCH_STANDARD_APP(t38_gateway_function)
|
|||
}
|
||||
}
|
||||
|
||||
switch_ivr_tone_detect_session(session, "t38", "1100.0", "rw", timeout, 1, direction, NULL, t38_gateway_start);
|
||||
//switch_ivr_tone_detect_session(session, "t38", "1100.0", "rw", timeout, 1, direction, NULL, t38_gateway_start);
|
||||
spandsp_fax_detect_session(session, "rw", timeout, 1, direction, NULL, t38_gateway_start);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -209,6 +254,12 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_spandsp_init)
|
|||
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);
|
||||
|
||||
SWITCH_ADD_APP(app_interface, "spandsp_start_fax_detect", "start fax detect", "start fax detect", spandsp_fax_detect_session_function,
|
||||
"<app>[ <arg>][ <timeout>]", SAF_NONE);
|
||||
|
||||
SWITCH_ADD_APP(app_interface, "spandsp_stop_fax_detect", "stop fax detect", "stop fax detect", spandsp_stop_fax_detect_session_function, "", SAF_NONE);
|
||||
|
||||
|
||||
mod_spandsp_fax_load(pool);
|
||||
mod_spandsp_codecs_load(module_interface, pool);
|
||||
|
||||
|
|
|
@ -68,3 +68,9 @@ switch_status_t spandsp_inband_dtmf_session(switch_core_session_t *session);
|
|||
|
||||
switch_status_t callprogress_detector_start(switch_core_session_t *session, const char *name);
|
||||
switch_status_t callprogress_detector_stop(switch_core_session_t *session);
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) spandsp_fax_detect_session(switch_core_session_t *session,
|
||||
const char *flags, time_t timeout,
|
||||
int hits, const char *app, const char *data, switch_tone_detect_callback_t callback);
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) spandsp_fax_stop_detect_session(switch_core_session_t *session);
|
||||
|
|
|
@ -1806,6 +1806,250 @@ switch_bool_t t38_gateway_start(switch_core_session_t *session, const char *app,
|
|||
return SWITCH_FALSE;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
char *app;
|
||||
char *data;
|
||||
char *key;
|
||||
int up;
|
||||
int total_hits;
|
||||
int hits;
|
||||
int sleep;
|
||||
int expires;
|
||||
int default_sleep;
|
||||
int default_expires;
|
||||
switch_tone_detect_callback_t callback;
|
||||
modem_connect_tones_rx_state_t rx_tones;
|
||||
|
||||
switch_media_bug_t *bug;
|
||||
switch_core_session_t *session;
|
||||
int bug_running;
|
||||
|
||||
} spandsp_fax_tone_container_t;
|
||||
|
||||
static switch_status_t tone_on_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf, switch_dtmf_direction_t direction)
|
||||
{
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
spandsp_fax_tone_container_t *cont = switch_channel_get_private(channel, "_fax_tone_detect_");
|
||||
|
||||
|
||||
if (!cont || dtmf->digit != 'f') {
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (cont->callback) {
|
||||
cont->callback(cont->session, cont->app, cont->data);
|
||||
} else {
|
||||
switch_channel_execute_on(switch_core_session_get_channel(cont->session), "execute_on_fax_detect");
|
||||
if (cont->app) {
|
||||
switch_core_session_execute_application_async(cont->session, cont->app, cont->data);
|
||||
}
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static switch_bool_t tone_detect_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type)
|
||||
{
|
||||
spandsp_fax_tone_container_t *cont = (spandsp_fax_tone_container_t *) user_data;
|
||||
switch_frame_t *frame = NULL;
|
||||
switch_bool_t rval = SWITCH_TRUE;
|
||||
|
||||
switch (type) {
|
||||
case SWITCH_ABC_TYPE_INIT:
|
||||
if (cont) {
|
||||
cont->bug_running = 1;
|
||||
modem_connect_tones_rx_init(&cont->rx_tones, MODEM_CONNECT_TONES_FAX_CED_OR_PREAMBLE, NULL, NULL);
|
||||
}
|
||||
break;
|
||||
case SWITCH_ABC_TYPE_CLOSE:
|
||||
break;
|
||||
case SWITCH_ABC_TYPE_READ_REPLACE:
|
||||
case SWITCH_ABC_TYPE_WRITE_REPLACE:
|
||||
{
|
||||
int skip = 0;
|
||||
|
||||
if (type == SWITCH_ABC_TYPE_READ_REPLACE) {
|
||||
frame = switch_core_media_bug_get_read_replace_frame(bug);
|
||||
} else {
|
||||
frame = switch_core_media_bug_get_write_replace_frame(bug);
|
||||
}
|
||||
|
||||
if (cont->sleep) {
|
||||
cont->sleep--;
|
||||
if (cont->sleep) {
|
||||
skip = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (cont->expires) {
|
||||
cont->expires--;
|
||||
if (!cont->expires) {
|
||||
cont->hits = 0;
|
||||
cont->sleep = 0;
|
||||
cont->expires = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!cont->up) {
|
||||
skip = 1;
|
||||
}
|
||||
|
||||
if (skip) {
|
||||
return SWITCH_TRUE;
|
||||
}
|
||||
|
||||
cont->hits = 0;
|
||||
modem_connect_tones_rx(&cont->rx_tones, frame->data, frame->samples);
|
||||
cont->hits = modem_connect_tones_rx_get(&cont->rx_tones);
|
||||
|
||||
if (cont->hits) {
|
||||
switch_event_t *event;
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(switch_core_media_bug_get_session(bug)), SWITCH_LOG_DEBUG,
|
||||
"Fax Tone Detected. [%s][%s]\n", cont->app, switch_str_nil(cont->data));
|
||||
|
||||
if (cont->callback) {
|
||||
cont->callback(cont->session, cont->app, cont->data);
|
||||
} else {
|
||||
switch_channel_execute_on(switch_core_session_get_channel(cont->session), "execute_on_fax_detect");
|
||||
if (cont->app) {
|
||||
switch_core_session_execute_application_async(cont->session, cont->app, cont->data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (switch_event_create(&event, SWITCH_EVENT_DETECTED_TONE) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_event_t *dup;
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Detected-Fax-Tone", "true");
|
||||
|
||||
if (switch_event_dup(&dup, event) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_event_fire(&dup);
|
||||
}
|
||||
|
||||
if (switch_core_session_queue_event(cont->session, &event) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(switch_core_media_bug_get_session(bug)), SWITCH_LOG_ERROR,
|
||||
"Event queue failed!\n");
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "delivery-failure", "true");
|
||||
switch_event_fire(&event);
|
||||
}
|
||||
}
|
||||
|
||||
rval = SWITCH_FALSE;
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
case SWITCH_ABC_TYPE_WRITE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (rval == SWITCH_FALSE) {
|
||||
cont->bug_running = 0;
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) spandsp_fax_stop_detect_session(switch_core_session_t *session)
|
||||
{
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
spandsp_fax_tone_container_t *cont = switch_channel_get_private(channel, "_fax_tone_detect_");
|
||||
|
||||
if (cont) {
|
||||
switch_channel_set_private(channel, "_fax_tone_detect_", NULL);
|
||||
cont->up = 0;
|
||||
switch_core_media_bug_remove(session, &cont->bug);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) spandsp_fax_detect_session(switch_core_session_t *session,
|
||||
const char *flags, time_t timeout,
|
||||
int hits, const char *app, const char *data, switch_tone_detect_callback_t callback)
|
||||
{
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
switch_status_t status;
|
||||
spandsp_fax_tone_container_t *cont = switch_channel_get_private(channel, "_fax_tone_detect_");
|
||||
switch_media_bug_flag_t bflags = 0;
|
||||
const char *var;
|
||||
switch_codec_implementation_t read_impl = { 0 };
|
||||
switch_core_session_get_read_impl(session, &read_impl);
|
||||
|
||||
if (cont) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Max Tones Reached!\n");
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
if (!cont && !(cont = switch_core_session_alloc(session, sizeof(*cont)))) {
|
||||
return SWITCH_STATUS_MEMERR;
|
||||
}
|
||||
|
||||
if (app) {
|
||||
cont->app = switch_core_session_strdup(session, app);
|
||||
}
|
||||
|
||||
if (data) {
|
||||
cont->data = switch_core_session_strdup(session, data);
|
||||
}
|
||||
|
||||
cont->callback = callback;
|
||||
cont->up = 1;
|
||||
cont->session = session;
|
||||
|
||||
if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) {
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
cont->default_sleep = 25;
|
||||
cont->default_expires = 250;
|
||||
|
||||
if ((var = switch_channel_get_variable(channel, "fax_tone_detect_sleep"))) {
|
||||
int tmp = atoi(var);
|
||||
if (tmp > 0) {
|
||||
cont->default_sleep = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
if ((var = switch_channel_get_variable(channel, "fax_tone_detect_expires"))) {
|
||||
int tmp = atoi(var);
|
||||
if (tmp > 0) {
|
||||
cont->default_expires = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
if (zstr(flags)) {
|
||||
bflags = SMBF_READ_REPLACE;
|
||||
} else {
|
||||
if (strchr(flags, 'r')) {
|
||||
bflags |= SMBF_READ_REPLACE;
|
||||
} else if (strchr(flags, 'w')) {
|
||||
bflags |= SMBF_WRITE_REPLACE;
|
||||
}
|
||||
}
|
||||
|
||||
bflags |= SMBF_NO_PAUSE;
|
||||
|
||||
|
||||
switch_core_event_hook_add_send_dtmf(session, tone_on_dtmf);
|
||||
switch_core_event_hook_add_recv_dtmf(session, tone_on_dtmf);
|
||||
|
||||
|
||||
if ((status = switch_core_media_bug_add(session, "fax_tone_detect", "",
|
||||
tone_detect_callback, cont, timeout, bflags, &cont->bug)) != SWITCH_STATUS_SUCCESS) {
|
||||
cont->bug_running = 0;
|
||||
return status;
|
||||
}
|
||||
|
||||
switch_channel_set_private(channel, "_fax_tone_detect_", cont);
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* For Emacs:
|
||||
|
|
Loading…
Reference in New Issue