--- asterisk-11.19.0.o/res/res_fax.c 2015-08-07 18:42:14.000000000 +0200 +++ asterisk-11.19.0/res/res_fax.c 2015-12-08 19:20:16.137717563 +0200 @@ -278,12 +278,12 @@ struct fax_detect { int timeout; /*! \brief DSP Processor */ struct ast_dsp *dsp; - /*! \brief original audio formats */ - struct ast_format orig_format; /*! \brief fax session details */ struct ast_fax_session_details *details; /*! \brief mode */ int flags; + /*! \brief translator path for transcoding to slinear */ + struct ast_trans_pvt* trans; }; /*! \brief FAX Detect flags */ @@ -3256,6 +3256,7 @@ static struct fax_detect *fax_detect_new faxdetect->flags = flags; + faxdetect->timeout = timeout; if (timeout) { faxdetect->timeout_start = ast_tvnow(); } else { @@ -3275,6 +3276,8 @@ static struct fax_detect *fax_detect_new faxdetect->dsp = NULL; } + faxdetect->trans = NULL; + return faxdetect; } @@ -3283,6 +3286,9 @@ static struct fax_detect *fax_detect_new static void fax_detect_framehook_destroy(void *data) { struct fax_detect *faxdetect = data; + if (faxdetect->trans) + ast_translator_free_path(faxdetect->trans); + ao2_ref(faxdetect, -1); } @@ -3301,34 +3307,19 @@ static struct ast_frame *fax_detect_fram struct fax_detect *faxdetect = data; struct ast_fax_session_details *details; struct ast_control_t38_parameters *control_params; - struct ast_channel *peer; + //struct ast_channel *peer; + struct ast_format slin; + struct ast_frame *o; int result = 0; + o = NULL; details = faxdetect->details; + ast_debug(5, "fax_detect_framehook called with event %d.\n", event); + switch (event) { case AST_FRAMEHOOK_EVENT_ATTACHED: - /* Setup format for DSP on ATTACH*/ - ast_format_copy(&faxdetect->orig_format, ast_channel_readformat(chan)); - switch (ast_channel_readformat(chan)->id) { - case AST_FORMAT_SLINEAR: - case AST_FORMAT_ALAW: - case AST_FORMAT_ULAW: - break; - default: - if (ast_set_read_format_by_id(chan, AST_FORMAT_SLINEAR)) { - ast_framehook_detach(chan, details->faxdetect_id); - details->faxdetect_id = -1; - return f; - } - } - return NULL; case AST_FRAMEHOOK_EVENT_DETACHED: - /* restore audio formats when we are detached */ - ast_set_read_format(chan, &faxdetect->orig_format); - if ((peer = ast_bridged_channel(chan))) { - ast_channel_make_compatible(chan, peer); - } return NULL; case AST_FRAMEHOOK_EVENT_READ: if (f) { @@ -3344,6 +3335,7 @@ static struct ast_frame *fax_detect_fram if ((!ast_tvzero(faxdetect->timeout_start) && (ast_tvdiff_ms(ast_tvnow(), faxdetect->timeout_start) > faxdetect->timeout))) { + ast_debug(5, "fax_detect_framehook detaching due to timeout (timeout=%d, timeout_start=%ld.%06lu, elapse=%" PRId64 ".\n", faxdetect->timeout, faxdetect->timeout_start.tv_sec, faxdetect->timeout_start.tv_usec, ast_tvdiff_ms(ast_tvnow(), faxdetect->timeout_start)); ast_framehook_detach(chan, details->faxdetect_id); details->faxdetect_id = -1; return f; @@ -3363,8 +3355,23 @@ static struct ast_frame *fax_detect_fram case AST_FORMAT_ULAW: break; default: + if (!faxdetect->trans) { + ast_debug(5, "Attempt to process %s frame in CNG fax detection.\n", ast_getformatname(&f->subclass.format)); + ast_format_set(&slin, AST_FORMAT_SLINEAR, 0); + faxdetect->trans = ast_translator_build_path(&slin, &f->subclass.format); + } + if (!faxdetect->trans) { + ast_debug(5, "Unable to build translation path to slinear.\n"); return f; } + o = f; + f = ast_translate(faxdetect->trans, f, 0); + if (!f) { + ast_debug(5, "Transcoding failed.\n"); + return o; + } + break; + } break; case AST_FRAME_CONTROL: if ((f->subclass.integer == AST_CONTROL_T38_PARAMETERS) && @@ -3408,8 +3415,8 @@ static struct ast_frame *fax_detect_fram if (ast_async_goto(chan, target_context, "fax", 1)) { ast_log(LOG_NOTICE, "Failed to async goto '%s' into fax of '%s'\n", ast_channel_name(chan), target_context); } - ast_frfree(f); - f = &ast_null_frame; + ast_frfree(o); + o = &ast_null_frame; } else { ast_channel_lock(chan); ast_log(LOG_NOTICE, "FAX %s detected but no fax extension in context (%s)\n", @@ -3420,7 +3427,8 @@ static struct ast_frame *fax_detect_fram details->faxdetect_id = -1; } - return f; + ast_frfree(f); + return o; } /*! \brief Attach a faxdetect framehook object to a channel.