aboutsummaryrefslogtreecommitdiffstats
path: root/channels
diff options
context:
space:
mode:
authorfile <file@f38db490-d61c-443f-a65b-d21fe96a405b>2009-11-23 15:48:54 +0000
committerfile <file@f38db490-d61c-443f-a65b-d21fe96a405b>2009-11-23 15:48:54 +0000
commit0a1fcaeef40f7fbe80235d48941d9363f4d3c811 (patch)
treea388ebee686fab36a553b942733e3564253ac509 /channels
parent41521c90c4079daa54b54752fbb6334ab61d4220 (diff)
Merged revisions 230881 via svnmerge from
https://origsvn.digium.com/svn/asterisk/trunk ........ r230881 | file | 2009-11-23 09:45:45 -0600 (Mon, 23 Nov 2009) | 7 lines Change fax detection in chan_sip so it behaves as one would expect. Internally the way T.38 is negotiated has changed and the option no longer reflects a behavior that is valid. It will now look for a CNG tone on received calls and if present send the call to the 'fax' extension. It is then up to the application or channel to request the switch over to T.38. ........ git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.6.2@230884 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'channels')
-rw-r--r--channels/chan_sip.c93
1 files changed, 59 insertions, 34 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 8da8da7d8..1624d5369 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -1674,7 +1674,7 @@ struct sip_pvt {
int laststate; /*!< SUBSCRIBE: Last known extension state */
int dialogver; /*!< SUBSCRIBE: Version for subscription dialog-info */
- struct ast_dsp *vad; /*!< Inband DTMF Detection dsp */
+ struct ast_dsp *dsp; /*!< A DSP for inband DTMF and fax CNG tone detection */
struct sip_peer *relatedpeer; /*!< If this dialog is related to a peer, which one
Used in peerpoke, mwi subscriptions */
@@ -6032,8 +6032,8 @@ static int sip_hangup(struct ast_channel *ast)
append_history(p, needcancel ? "Cancel" : "Hangup", "Cause %s", p->owner ? ast_cause2str(p->hangupcause) : "Unknown");
/* Disconnect */
- if (p->vad)
- ast_dsp_free(p->vad);
+ if (p->dsp)
+ ast_dsp_free(p->dsp);
p->owner = NULL;
ast->tech_pvt = dialog_unref(ast->tech_pvt, "unref ast->tech_pvt");
@@ -6679,12 +6679,23 @@ static struct ast_channel *sip_new(struct sip_pvt *i, int state, const char *tit
else
ast_debug(3, "This channel will not be able to handle video.\n");
- if ((ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) || (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) {
- i->vad = ast_dsp_new();
- ast_dsp_set_features(i->vad, DSP_FEATURE_DIGIT_DETECT);
+ if ((ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) || (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_AUTO) ||
+ (ast_test_flag(&i->flags[1], SIP_PAGE2_FAX_DETECT))) {
+ int features = 0;
+
+ if ((ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) || (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) {
+ features |= DSP_FEATURE_DIGIT_DETECT;
+ }
+
+ if (ast_test_flag(&i->flags[1], SIP_PAGE2_FAX_DETECT)) {
+ features |= DSP_FEATURE_FAX_DETECT;
+ }
+
+ i->dsp = ast_dsp_new();
+ ast_dsp_set_features(i->dsp, features);
if (global_relaxdtmf)
- ast_dsp_set_digitmode(i->vad, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF);
- }
+ ast_dsp_set_digitmode(i->dsp, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF);
+ }
/* Set file descriptors for audio, video, realtime text and UDPTL as needed */
if (i->rtp) {
@@ -6997,12 +7008,20 @@ static struct ast_frame *sip_rtp_read(struct ast_channel *ast, struct sip_pvt *p
ast_set_write_format(p->owner, p->owner->writeformat);
}
- if (f && (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) && p->vad) {
- f = ast_dsp_process(p->owner, p->vad, f);
- if (f && f->frametype == AST_FRAME_DTMF) {
- if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) && f->subclass == 'f') {
- ast_debug(1, "Fax CNG detected on %s\n", ast->name);
- *faxdetect = 1;
+ if (f && ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) || ast_test_flag(&p->flags[1], SIP_PAGE2_FAX_DETECT)) && p->dsp) {
+ f = ast_dsp_process(p->owner, p->dsp, f);
+ if (f && f->frametype == AST_FRAME_DTMF) {
+ if (f->subclass == 'f') {
+ if (option_debug)
+ ast_log(LOG_DEBUG, "Fax CNG detected on %s\n", ast->name);
+ *faxdetect = 1;
+ /* If we only needed this DSP for fax detection purposes we can just drop it now */
+ if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) {
+ ast_dsp_set_features(p->dsp, DSP_FEATURE_DIGIT_DETECT);
+ } else {
+ ast_dsp_free(p->dsp);
+ p->dsp = NULL;
+ }
} else {
ast_debug(1, "* Detected inband DTMF '%c'\n", f->subclass);
}
@@ -7023,20 +7042,26 @@ static struct ast_frame *sip_read(struct ast_channel *ast)
fr = sip_rtp_read(ast, p, &faxdetected);
p->lastrtprx = time(NULL);
- /* If we are NOT bridged to another channel, and we have detected fax tone we issue T38 re-invite to a peer */
- /* If we are bridged then it is the responsibility of the SIP device to issue T38 re-invite if it detects CNG or fax preamble */
- if (faxdetected && ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) && (p->t38.state == T38_DISABLED) && !(ast_bridged_channel(ast))) {
- if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
- if (!p->pendinginvite) {
- ast_debug(3, "Sending reinvite on SIP (%s) for T.38 negotiation.\n", ast->name);
- change_t38_state(p, T38_LOCAL_REINVITE);
- transmit_reinvite_with_sdp(p, TRUE, FALSE);
- }
- } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
- ast_debug(3, "Deferring reinvite on SIP (%s) - it will be re-negotiated for T.38\n", ast->name);
- ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
- }
- }
+ /* If we detect a CNG tone and fax detection is enabled then send us off to the fax extension */
+ if (faxdetected && ast_test_flag(&p->flags[1], SIP_PAGE2_FAX_DETECT)) {
+ ast_channel_lock(ast);
+ if (strcmp(ast->exten, "fax")) {
+ const char *target_context = S_OR(ast->macrocontext, ast->context);
+ ast_channel_unlock(ast);
+ if (ast_exists_extension(ast, target_context, "fax", 1, ast->cid.cid_num)) {
+ ast_verbose(VERBOSE_PREFIX_2 "Redirecting '%s' to fax extension\n", ast->name);
+ pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast->exten);
+ if (ast_async_goto(ast, target_context, "fax", 1)) {
+ ast_log(LOG_NOTICE, "Failed to async goto '%s' into fax of '%s'\n", ast->name, target_context);
+ }
+ fr = &ast_null_frame;
+ } else {
+ ast_log(LOG_NOTICE, "Fax detected but no fax extension\n");
+ }
+ } else {
+ ast_channel_unlock(ast);
+ }
+ }
/* Only allow audio through if they sent progress with SDP, or if the channel is actually answered */
if (fr && fr->frametype == AST_FRAME_VOICE && p->invitestate != INV_EARLY_MEDIA && ast->_state != AST_STATE_UP) {
@@ -25298,14 +25323,14 @@ static int sip_dtmfmode(struct ast_channel *chan, void *data)
if (p->rtp)
ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) {
- if (!p->vad) {
- p->vad = ast_dsp_new();
- ast_dsp_set_features(p->vad, DSP_FEATURE_DIGIT_DETECT);
+ if (!p->dsp) {
+ p->dsp = ast_dsp_new();
+ ast_dsp_set_features(p->dsp, DSP_FEATURE_DIGIT_DETECT);
}
} else {
- if (p->vad) {
- ast_dsp_free(p->vad);
- p->vad = NULL;
+ if (p->dsp) {
+ ast_dsp_free(p->dsp);
+ p->dsp = NULL;
}
}
sip_pvt_unlock(p);