--- chan_sip.c_before_dtmf_fix 2012-09-05 17:33:16.000000000 +0200 +++ chan_sip.c 2012-09-10 17:35:19.000000000 +0200 @@ -1289,6 +1289,7 @@ /*---------------------------- Forward declarations of functions in chan_sip.c */ /* Note: This is added to help splitting up chan_sip.c into several files in coming releases. */ +static int _dtmf_timeout(void * data); /*--- PBX interface functions */ static struct ast_channel *sip_request_call(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *dest, int *cause); @@ -3163,6 +3164,11 @@ if (dialog->t38id > -1) { AST_SCHED_DEL_UNREF(sched, dialog->t38id, dialog_unref(dialog, "when you delete the t38id sched, you should dec the refcount for the stored dialog ptr")); } + if (dialog->dtmf_timeout > -1) + { + AST_SCHED_DEL_UNREF(sched, dialog->dtmf_timeout, dialog_unref(dialog, "when you delete the dtmf_timeout timer sched, you should dec the refcount for the stored dialog ptr")); + + } if (dialog->stimer) { stop_session_timer(dialog); @@ -7035,6 +7041,13 @@ res = -1; /* Tell Asterisk to generate inband indications */ break; case SIP_DTMF_RFC2833: + ast_debug (1,"Inside sip_senddigit_begin to emulate DTMF begin"); + if (p->dtmf_timeout > -1) + { + AST_SCHED_DEL_UNREF(sched, p->dtmf_timeout, dialog_unref(p, "when you delete the dtmf_timeout timer sched, you should dec the refcount for the stored dialog ptr")); + + } + p->dtmf_timeout=ast_sched_add(sched, (unsigned int)100 + 10, _dtmf_timeout, dialog_ref(p, "setting ref as passing into ast_sched_add for _dtmf_timeout")); if (p->rtp) ast_rtp_instance_dtmf_begin(p->rtp, digit); break; @@ -8256,6 +8269,7 @@ p->sessionversion_remote = -1; p->session_modify = TRUE; p->stimer = NULL; + p->dtmf_timeout = -1; p->prefs = default_prefs; /* Set default codecs for this call */ ast_copy_string(p->zone, default_zone, sizeof(p->zone)); p->maxforwards = sip_cfg.default_max_forwards; @@ -33213,6 +33227,23 @@ return 0; } +static int _dtmf_timeout(void * data) +{ + ast_debug(1, "Inside _dtmf_timeout"); + struct sip_pvt *p = (struct sip_pvt *)data; + sip_pvt_lock(p); /* It locks both the channel and dialog */ + /* Reset the timer object */ + p->dtmf_timeout = -1; + struct ast_channel* bridged = ast_bridged_channel(p->owner); + sip_pvt_unlock(p); + if (bridged) + { + ast_log(LOG_DTMF, "dtmf timeout, sending null to clear\n"); + ast_queue_frame(bridged, &ast_null_frame); + } + return 0; +} + AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER, "Session Initiation Protocol (SIP)", .load = load_module, .unload = unload_module,