From 3f44b08b7bf589e393e0f373ec4725c4f4bff21b Mon Sep 17 00:00:00 2001 From: Matthew Nicholson Date: Tue, 12 Jul 2011 15:23:24 +0000 Subject: do v21 detection instead of CED detection for the fax gateway git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@327769 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- res/res_fax.c | 65 +++++++++++++++++++---------------------------------------- 1 file changed, 21 insertions(+), 44 deletions(-) (limited to 'res/res_fax.c') diff --git a/res/res_fax.c b/res/res_fax.c index 18f3fa133..31aede8a6 100644 --- a/res/res_fax.c +++ b/res/res_fax.c @@ -246,8 +246,6 @@ struct fax_gateway { struct ast_fax_tech_token *token; /*! \brief the start of our timeout counter */ struct timeval timeout_start; - /*! \brief the start of our ced timeout */ - struct timeval ced_timeout_start; /*! \brief DSP Processor */ struct ast_dsp *chan_dsp; struct ast_dsp *peer_dsp; @@ -255,8 +253,8 @@ struct fax_gateway { int framehook; /*! \brief bridged */ int bridged:1; - /*! \brief 1 if the ced tone came from chan, 0 if it came from peer */ - int ced_chan:1; + /*! \brief 1 if a v21 preamble has been detected */ + int detected_v21:1; /*! \brief a flag to track the state of our negotiation */ enum ast_t38_state t38_state; /*! \brief original audio formats */ @@ -273,7 +271,6 @@ static int fax_logger_level = -1; #define RES_FAX_TIMEOUT 10000 #define FAX_GATEWAY_TIMEOUT RES_FAX_TIMEOUT -#define FAX_GATEWAY_CED_TIMEOUT 3000 /*! \brief The faxregistry is used to manage information and statistics for all FAX sessions. */ static struct { @@ -2412,10 +2409,10 @@ static struct fax_gateway *fax_gateway_new(struct ast_fax_session_details *detai gateway->framehook = -1; ast_dsp_set_features(gateway->chan_dsp, DSP_FEATURE_FAX_DETECT); - ast_dsp_set_faxmode(gateway->chan_dsp, DSP_FAXMODE_DETECT_CED); + ast_dsp_set_faxmode(gateway->chan_dsp, DSP_FAXMODE_DETECT_V21); ast_dsp_set_features(gateway->peer_dsp, DSP_FEATURE_FAX_DETECT); - ast_dsp_set_faxmode(gateway->peer_dsp, DSP_FAXMODE_DETECT_CED); + ast_dsp_set_faxmode(gateway->peer_dsp, DSP_FAXMODE_DETECT_V21); details->caps = AST_FAX_TECH_GATEWAY; if (!(gateway->s = fax_session_reserve(details, &gateway->token))) { @@ -2503,21 +2500,17 @@ static struct ast_frame *fax_gateway_request_t38(struct fax_gateway *gateway, st gateway->t38_state = T38_STATE_NEGOTIATING; gateway->timeout_start = ast_tvnow(); - gateway->ced_timeout_start.tv_sec = 0; - gateway->ced_timeout_start.tv_usec = 0; - ast_debug(1, "requesting T.38 for gateway session for %s\n", chan->name); return fp; } -static struct ast_frame *fax_gateway_detect_ced(struct fax_gateway *gateway, struct ast_channel *chan, struct ast_channel *peer, struct ast_channel *active, struct ast_frame *f) +static struct ast_frame *fax_gateway_detect_v21(struct fax_gateway *gateway, struct ast_channel *chan, struct ast_channel *peer, struct ast_channel *active, struct ast_frame *f) { struct ast_frame *dfr = ast_frdup(f); struct ast_dsp *active_dsp = (active == chan) ? gateway->chan_dsp : gateway->peer_dsp; struct ast_channel *other = (active == chan) ? peer : chan; - /* if we have already detected a CED tone, don't waste time here */ - if (!ast_tvzero(gateway->ced_timeout_start)) { + if (gateway->detected_v21) { return f; } @@ -2529,17 +2522,13 @@ static struct ast_frame *fax_gateway_detect_ced(struct fax_gateway *gateway, str return f; } - if (dfr->frametype == AST_FRAME_DTMF && dfr->subclass.integer == 'e') { + if (dfr->frametype == AST_FRAME_DTMF && dfr->subclass.integer == 'g') { + gateway->detected_v21 = 1; if (ast_channel_get_t38_state(other) == T38_STATE_UNKNOWN) { - if (ast_channel_get_t38_state(active) == T38_STATE_UNKNOWN) { - gateway->ced_timeout_start = ast_tvnow(); - gateway->ced_chan = (active == chan); - ast_debug(1, "detected CED tone from %s; will schedule T.38 request on %s\n", active->name, other->name); - } else { - return fax_gateway_request_t38(gateway, chan, f); - } + ast_debug(1, "detected v21 preamble from %s\n", active->name); + return fax_gateway_request_t38(gateway, chan, f); } else { - ast_debug(1, "detected CED tone on %s, but %s does not support T.38 for T.38 gateway session\n", active->name, other->name); + ast_debug(1, "detected v21 preamble on %s, but %s does not support T.38 for T.38 gateway session\n", active->name, other->name); } } @@ -2593,9 +2582,6 @@ static struct ast_frame *fax_gateway_detect_t38(struct fax_gateway *gateway, str if (control_params->request_response == AST_T38_REQUEST_NEGOTIATE) { enum ast_t38_state state = ast_channel_get_t38_state(other); - gateway->ced_timeout_start.tv_sec = 0; - gateway->ced_timeout_start.tv_usec = 0; - if (state == T38_STATE_UNKNOWN) { /* we detected a request to negotiate T.38 and the * other channel appears to support T.38, we'll pass @@ -2635,7 +2621,7 @@ static struct ast_frame *fax_gateway_detect_t38(struct fax_gateway *gateway, str return &ast_null_frame; } else if (gateway->t38_state == T38_STATE_NEGOTIATING) { /* we got a request to negotiate T.38 after we already - * sent one to the other party based on CED tone + * sent one to the other party based on v21 preamble * detection. We'll just pretend we passed this request * through in the first place. */ @@ -2643,12 +2629,12 @@ static struct ast_frame *fax_gateway_detect_t38(struct fax_gateway *gateway, str gateway->t38_state = T38_STATE_UNKNOWN; gateway->timeout_start = ast_tvnow(); - ast_debug(1, "%s is attempting to negotiate T.38 after we already sent a negotiation request based on CED detection\n", active->name); + ast_debug(1, "%s is attempting to negotiate T.38 after we already sent a negotiation request based on v21 preamble detection\n", active->name); ao2_ref(details, -1); return &ast_null_frame; } else if (gateway->t38_state == T38_STATE_NEGOTIATED) { /* we got a request to negotiate T.38 after we already - * sent one to the other party based on CED tone + * sent one to the other party based on v21 preamble * detection and received a response. We need to * respond to this and shut down the gateway. */ @@ -2869,7 +2855,8 @@ static struct ast_frame *fax_gateway_framehook(struct ast_channel *chan, struct gateway->timeout_start = ast_tvnow(); - /* we are bridged, change r/w formats to SLIN for CED detection and T.30 */ + /* we are bridged, change r/w formats to SLIN for v21 preamble + * detection and T.30 */ ast_format_copy(&gateway->chan_read_format, &chan->readformat); ast_format_copy(&gateway->chan_write_format, &chan->readformat); @@ -2944,20 +2931,10 @@ static struct ast_frame *fax_gateway_framehook(struct ast_channel *chan, struct return fax_gateway_detect_t38(gateway, chan, peer, active, f); } - /* handle the ced timeout delay */ - if (!ast_tvzero(gateway->ced_timeout_start)) { - if (ast_tvdiff_ms(ast_tvnow(), gateway->ced_timeout_start) > FAX_GATEWAY_CED_TIMEOUT) { - if (gateway->ced_chan && chan == active) { - return fax_gateway_request_t38(gateway, chan, f); - } else if (!gateway->ced_chan && peer == active) { - return fax_gateway_request_t38(gateway, chan, f); - } - } - } else if (gateway->t38_state == T38_STATE_UNAVAILABLE && f->frametype == AST_FRAME_VOICE) { - /* not in gateway mode and have not detected CED yet, listen - * for CED */ - /* XXX this should detect a v21 preamble instead of CED */ - return fax_gateway_detect_ced(gateway, chan, peer, active, f); + if (!gateway->detected_v21 && gateway->t38_state == T38_STATE_UNAVAILABLE && f->frametype == AST_FRAME_VOICE) { + /* not in gateway mode and have not detected v21 yet, listen + * for v21 */ + return fax_gateway_detect_v21(gateway, chan, peer, active, f); } /* in gateway mode, gateway some packets */ @@ -2981,7 +2958,7 @@ static struct ast_frame *fax_gateway_framehook(struct ast_channel *chan, struct } /* force silence on the line if T.38 negotiation might be taking place */ - if (!ast_tvzero(gateway->ced_timeout_start) || (gateway->t38_state != T38_STATE_UNAVAILABLE && gateway->t38_state != T38_STATE_REJECTED)) { + if (gateway->t38_state != T38_STATE_UNAVAILABLE && gateway->t38_state != T38_STATE_REJECTED) { if (f->frametype == AST_FRAME_VOICE && f->subclass.format.id == AST_FORMAT_SLINEAR) { short silence_buf[f->samples]; struct ast_frame silence_frame = { -- cgit v1.2.3