Index: addons/chan_ooh323.c =================================================================== --- addons/chan_ooh323.c (revision 315724) +++ addons/chan_ooh323.c (working copy) @@ -139,6 +139,7 @@ struct ast_rtp_instance *vrtp; /* Placeholder for now */ int t38support; /* T.38 mode - disable, transparent, faxgw */ + int faxdetect; int rtptimeout; struct ast_udptl *udptl; int faxmode; @@ -210,6 +211,7 @@ struct ast_codec_pref prefs; int dtmfmode; int dtmfcodec; + int faxdetect; int t38support; int rtptimeout; int mUseIP; /* Use IP address or H323-ID to search user */ @@ -234,6 +236,7 @@ int amaflags; int dtmfmode; int dtmfcodec; + int faxdetect; int t38support; int mFriend; /* indicates defined as friend */ char ip[20]; @@ -294,6 +297,7 @@ static struct ast_codec_pref gPrefs; static int gDTMFMode = H323_DTMF_RFC2833; static int gDTMFCodec = 101; +static int gFAXdetect = 1; static int gT38Support = T38_FAXGW; static char gGatekeeper[100]; static enum RasGatekeeperMode gRasGkMode = RasNoGatekeeper; @@ -389,18 +393,23 @@ ast_module_ref(myself); /* Allocate dsp for in-band DTMF support */ + i->vad = ast_dsp_new(); if (i->dtmfmode & H323_DTMF_INBAND) { - i->vad = ast_dsp_new(); ast_dsp_set_features(i->vad, DSP_FEATURE_DIGIT_DETECT); ast_dsp_set_features(i->vad, DSP_FEATURE_DIGIT_DETECT | DSP_FEATURE_FAX_DETECT); - ast_dsp_set_faxmode(i->vad, - DSP_FAXMODE_DETECT_CNG | DSP_FAXMODE_DETECT_CED); - - if (i->dtmfmode & H323_DTMF_INBANDRELAX) + if (i->dtmfmode & H323_DTMF_INBANDRELAX) { ast_dsp_set_digitmode(i->vad, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF); + } + } else if (i->faxdetect) { + ast_dsp_set_features(i->vad, DSP_FEATURE_FAX_DETECT); } + if (i->faxdetect) { + ast_dsp_set_faxmode(i->vad, + DSP_FAXMODE_DETECT_CNG | DSP_FAXMODE_DETECT_CED); + } + ast_mutex_lock(&usecnt_lock); usecnt++; ast_mutex_unlock(&usecnt_lock); @@ -516,6 +525,7 @@ ast_udptl_set_error_correction_scheme(pvt->udptl, UDPTL_ERROR_CORRECTION_NONE); ast_udptl_set_far_max_datagram(pvt->udptl, 144); pvt->faxmode = 0; + pvt->faxdetect = gFAXdetect; pvt->t38support = gT38Support; pvt->rtptimeout = gRTPTimeout; pvt->rtdrinterval = gRTDRInterval; @@ -645,6 +655,7 @@ p->g729onlyA = peer->g729onlyA; p->dtmfmode |= peer->dtmfmode; p->dtmfcodec = peer->dtmfcodec; + p->faxdetect = peer->faxdetect; p->t38support = peer->t38support; p->rtptimeout = peer->rtptimeout; p->faststart = peer->faststart; @@ -674,6 +685,7 @@ p->g729onlyA = g729onlyA; p->dtmfmode = gDTMFMode; p->dtmfcodec = gDTMFCodec; + p->faxdetect = gFAXdetect; p->t38support = gT38Support; p->rtptimeout = gRTPTimeout; p->capability = gCapability; @@ -864,7 +876,7 @@ ast_mutex_lock(&p->lock); - if (digit == 'e' && !p->faxmode && p->t38support != T38_DISABLED) { + if ((digit == 'e' || digit == 'f') && !p->faxmode && p->t38support != T38_DISABLED) { if (!p->chmodepend) { if (gH323Debug) ast_verbose("request to change %s to t.38 because fax cng\n", @@ -1784,6 +1796,7 @@ memcpy(&p->prefs, &user->prefs, sizeof(struct ast_codec_pref)); p->dtmfmode |= user->dtmfmode; p->dtmfcodec = user->dtmfcodec; + p->faxdetect = user->faxdetect; p->t38support = user->t38support; p->rtptimeout = user->rtptimeout; p->h245tunneling = user->h245tunneling; @@ -2206,6 +2219,7 @@ user->rtptimeout = gRTPTimeout; user->dtmfmode = gDTMFMode; user->dtmfcodec = gDTMFCodec; + user->faxdetect = gFAXdetect; user->t38support = gT38Support; user->faststart = gFastStart; user->h245tunneling = gTunneling; @@ -2281,6 +2295,12 @@ user->dtmfmode |= ast_true(v->value) ? H323_DTMF_INBANDRELAX : 0; } else if (!strcasecmp(v->name, "dtmfcodec") && atoi(v->value)) { user->dtmfcodec = atoi(v->value); + } else if (!strcasecmp(v->name, "faxdetect")) { + if (ast_true(v->value)) { + user->faxdetect = 1; + } else { + user->faxdetect = 0; + } } else if (!strcasecmp(v->name, "t38support")) { if (!strcasecmp(v->value, "disabled")) user->t38support = T38_DISABLED; @@ -2320,6 +2340,7 @@ peer->amaflags = gAMAFLAGS; peer->dtmfmode = gDTMFMode; peer->dtmfcodec = gDTMFCodec; + peer->faxdetect = gFAXdetect; peer->t38support = gT38Support; peer->faststart = gFastStart; peer->h245tunneling = gTunneling; @@ -2420,6 +2441,12 @@ peer->dtmfmode |= ast_true(v->value) ? H323_DTMF_INBANDRELAX : 0; } else if (!strcasecmp(v->name, "dtmfcodec") && atoi(v->value)) { peer->dtmfcodec = atoi(v->value); + } else if (!strcasecmp(v->name, "faxdetect")) { + if (ast_true(v->value)) { + peer->faxdetect = 1; + } else { + peer->faxdetect = 0; + } } else if (!strcasecmp(v->name, "t38support")) { if (!strcasecmp(v->value, "disabled")) peer->t38support = T38_DISABLED; @@ -2541,6 +2568,7 @@ memset(&gPrefs, 0, sizeof(struct ast_codec_pref)); gDTMFMode = H323_DTMF_RFC2833; gDTMFCodec = 101; + gFAXdetect = 1; gT38Support = T38_FAXGW; gTRCLVL = OOTRCLVLERR; gRasGkMode = RasNoGatekeeper; @@ -2737,6 +2765,12 @@ gDTMFMode |= ast_true(v->value) ? H323_DTMF_INBANDRELAX : 0; } else if (!strcasecmp(v->name, "dtmfcodec") && atoi(v->value)) { gDTMFCodec = atoi(v->value); + } else if (!strcasecmp(v->name, "faxdetect")) { + if (ast_true(v->value)) { + gFAXdetect = 1; + } else { + gFAXdetect = 0; + } } else if (!strcasecmp(v->name, "t38support")) { if (!strcasecmp(v->value, "disabled")) gT38Support = T38_DISABLED; @@ -2871,6 +2905,7 @@ ast_cli(a->fd, "%s\n", "disabled"); else if (peer->t38support == T38_FAXGW) ast_cli(a->fd, "%s\n", "faxgw/chan_sip compatible"); + ast_cli(a->fd,"%-15s%s\n", "FAX Detect:", peer->faxdetect? "Yes" : "No"); ast_cli(a->fd, "%-15.15s%s\n", "AccountCode: ", peer->accountcode); ast_cli(a->fd, "%-15.15s%s\n", "AMA flags: ", @@ -3016,6 +3051,7 @@ ast_cli(a->fd, "%s\n", "disabled"); else if (user->t38support == T38_FAXGW) ast_cli(a->fd, "%s\n", "faxgw/chan_sip compatible"); + ast_cli(a->fd,"%-15s%s\n", "FAX Detect:", user->faxdetect? "Yes" : "No"); ast_cli(a->fd, "%-15.15s%s\n", "AccountCode: ", user->accountcode); ast_cli(a->fd, "%-15.15s%s\n", "AMA flags: ", @@ -3172,10 +3208,10 @@ ast_cli(a->fd, "%-20s", "DTMF Mode: "); if (gDTMFMode & H323_DTMF_CISCO) { ast_cli(a->fd, "%s\n", "cisco"); - ast_cli(a->fd, "%-15.15s%d\n", "DTMF Codec: ", gDTMFCodec); + ast_cli(a->fd, "%-20.15s%d\n", "DTMF Codec: ", gDTMFCodec); } else if (gDTMFMode & H323_DTMF_RFC2833) { ast_cli(a->fd, "%s\n", "rfc2833"); - ast_cli(a->fd, "%-15.15s%d\n", "DTMF Codec: ", gDTMFCodec); + ast_cli(a->fd, "%-20.15s%d\n", "DTMF Codec: ", gDTMFCodec); } else if (gDTMFMode & H323_DTMF_Q931) ast_cli(a->fd, "%s\n", "q931keypad"); else if (gDTMFMode & H323_DTMF_H245ALPHANUMERIC) @@ -3194,9 +3230,10 @@ ast_cli(a->fd, "%s\n", "disabled"); else if (gT38Support == T38_FAXGW) ast_cli(a->fd, "%s\n", "faxgw/chan_sip compatible"); + ast_cli(a->fd,"%-20s%s\n", "FAX Detect:", (gFAXdetect) ? "Yes" : "No"); if (gRTDRCount && gRTDRInterval) - ast_cli(a->fd, "%-15.15s%d,%d\n", "RoundTrip: ", gRTDRCount, gRTDRInterval); + ast_cli(a->fd, "%-20.15s%d,%d\n", "RoundTrip: ", gRTDRCount, gRTDRInterval); ast_cli(a->fd, "%-20s%ld\n", "Call counter: ", callnumber); ast_cli(a->fd, "%-20s%s\n", "AccountCode: ", gAccountcode); @@ -4144,7 +4181,7 @@ p->lastTxT38 = time(NULL); if (p->t38support == T38_ENABLED) { struct ast_control_t38_parameters parameters = { .request_response = 0 }; - parameters.request_response = AST_T38_NEGOTIATED; + parameters.request_response = AST_T38_REQUEST_NEGOTIATE; parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl); parameters.rate = AST_T38_RATE_14400; ast_queue_control_data(p->owner, AST_CONTROL_T38_PARAMETERS, ¶meters, sizeof(parameters)); @@ -4277,12 +4314,21 @@ ast_set_write_format(p->owner, p->owner->writeformat); } - if ((p->dtmfmode & H323_DTMF_INBAND) && p->vad && + if (p->vad && p->faxdetect && (f->subclass.codec == AST_FORMAT_SLINEAR || f->subclass.codec == AST_FORMAT_ALAW || f->subclass.codec == AST_FORMAT_ULAW)) { f = ast_dsp_process(p->owner, p->vad, f); - if (f && (f->frametype == AST_FRAME_DTMF)) + if (f && (f->frametype == AST_FRAME_DTMF)) { + if ((f->subclass.integer == 'f') && !p->faxmode && p->t38support != T38_DISABLED) { + if (!p->chmodepend) { + if (gH323Debug) + ast_verbose("request to change %s to t.38 because fax cng\n", p->callToken); + p->chmodepend = 1; + ooRequestChangeMode(p->callToken, 1); + } + } ast_debug(1, "* Detected inband DTMF '%c'\n", f->subclass.integer); + } } } }