diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 74d328694..0e5d27f79 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -4228,10 +4228,11 @@ static void enable_dsp_detect(struct sip_pvt *p) } if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) || - (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) { - if (!p->rtp || ast_rtp_instance_dtmf_mode_set(p->rtp, AST_RTP_DTMF_MODE_INBAND)) { - features |= DSP_FEATURE_DIGIT_DETECT; - } + (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) { + if (p->rtp) { + ast_rtp_instance_dtmf_mode_set(p->rtp, AST_RTP_DTMF_MODE_INBAND); + } + features |= DSP_FEATURE_DIGIT_DETECT; } if (ast_test_flag(&p->flags[1], SIP_PAGE2_FAX_DETECT_CNG)) { @@ -6932,8 +6933,8 @@ static struct ast_channel *sip_new(struct sip_pvt *i, int state, const char *tit if ((ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) || (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) { - if (!i->rtp || ast_rtp_instance_dtmf_mode_set(i->rtp, AST_RTP_DTMF_MODE_INBAND)) { - enable_dsp_detect(i); + if (i->rtp) { + ast_rtp_instance_dtmf_mode_set(i->rtp, AST_RTP_DTMF_MODE_INBAND); } } else if (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) { if (i->rtp) { diff --git a/include/asterisk/rtp_engine.h b/include/asterisk/rtp_engine.h index e04303ca6..30270ec4a 100644 --- a/include/asterisk/rtp_engine.h +++ b/include/asterisk/rtp_engine.h @@ -349,6 +349,8 @@ struct ast_rtp_engine { void (*alt_remote_address_set)(struct ast_rtp_instance *instance, struct ast_sockaddr *sa); /*! Callback for changing DTMF mode */ int (*dtmf_mode_set)(struct ast_rtp_instance *instance, enum ast_rtp_dtmf_mode dtmf_mode); + /*! Callback for getting DTMF mode */ + enum ast_rtp_dtmf_mode (*dtmf_mode_get)(struct ast_rtp_instance *instance); /*! Callback for retrieving statistics */ int (*get_stat)(struct ast_rtp_instance *instance, struct ast_rtp_instance_stats *stats, enum ast_rtp_instance_stat stat); /*! Callback for setting QoS values */ diff --git a/main/rtp_engine.c b/main/rtp_engine.c index 4ad3c9024..c7d77f809 100644 --- a/main/rtp_engine.c +++ b/main/rtp_engine.c @@ -69,8 +69,6 @@ struct ast_rtp_instance { int holdtimeout; /*! RTP keepalive interval */ int keepalive; - /*! DTMF mode in use */ - enum ast_rtp_dtmf_mode dtmf_mode; /*! Glue currently in use */ struct ast_rtp_glue *glue; /*! Channel associated with the instance */ @@ -745,18 +743,12 @@ int ast_rtp_instance_dtmf_end_with_duration(struct ast_rtp_instance *instance, c int ast_rtp_instance_dtmf_mode_set(struct ast_rtp_instance *instance, enum ast_rtp_dtmf_mode dtmf_mode) { - if (!instance->engine->dtmf_mode_set || instance->engine->dtmf_mode_set(instance, dtmf_mode)) { - return -1; - } - - instance->dtmf_mode = dtmf_mode; - - return 0; + return (!instance->engine->dtmf_mode_set || instance->engine->dtmf_mode_set(instance, dtmf_mode)) ? -1 : 0; } enum ast_rtp_dtmf_mode ast_rtp_instance_dtmf_mode_get(struct ast_rtp_instance *instance) { - return instance->dtmf_mode; + return instance->engine->dtmf_mode_get ? instance->engine->dtmf_mode_get(instance) : 0; } void ast_rtp_instance_update_source(struct ast_rtp_instance *instance) @@ -1291,6 +1283,7 @@ enum ast_bridge_result ast_rtp_instance_bridge(struct ast_channel *c0, struct as enum ast_rtp_glue_result audio_glue0_res = AST_RTP_GLUE_RESULT_FORBID, video_glue0_res = AST_RTP_GLUE_RESULT_FORBID; enum ast_rtp_glue_result audio_glue1_res = AST_RTP_GLUE_RESULT_FORBID, video_glue1_res = AST_RTP_GLUE_RESULT_FORBID; enum ast_bridge_result res = AST_BRIDGE_FAILED; + enum ast_rtp_dtmf_mode dmode; struct ast_format_cap *cap0 = ast_format_cap_alloc_nolock(); struct ast_format_cap *cap1 = ast_format_cap_alloc_nolock(); int unlock_chans = 1; @@ -1352,11 +1345,13 @@ enum ast_bridge_result ast_rtp_instance_bridge(struct ast_channel *c0, struct as } /* If we need to get DTMF see if we can do it outside of the RTP stream itself */ - if ((flags & AST_BRIDGE_DTMF_CHANNEL_0) && instance0->properties[AST_RTP_PROPERTY_DTMF]) { + dmode = ast_rtp_instance_dtmf_mode_get(instance0); + if ((flags & AST_BRIDGE_DTMF_CHANNEL_0) && dmode) { res = AST_BRIDGE_FAILED_NOWARN; goto done; } - if ((flags & AST_BRIDGE_DTMF_CHANNEL_1) && instance1->properties[AST_RTP_PROPERTY_DTMF]) { + dmode = ast_rtp_instance_dtmf_mode_get(instance1); + if ((flags & AST_BRIDGE_DTMF_CHANNEL_1) && dmode) { res = AST_BRIDGE_FAILED_NOWARN; goto done; } diff --git a/res/res_rtp_asterisk.c b/res/res_rtp_asterisk.c index a520cdb16..06af4832d 100644 --- a/res/res_rtp_asterisk.c +++ b/res/res_rtp_asterisk.c @@ -147,6 +147,7 @@ struct ast_rtp { unsigned int dtmf_duration; /*!< Total duration in samples since the digit start event */ unsigned int dtmf_timeout; /*!< When this timestamp is reached we consider END frame lost and forcibly abort digit */ unsigned int dtmfsamples; + enum ast_rtp_dtmf_mode dtmfmode;/*!< The current DTMF mode of the RTP stream */ /* DTMF Transmission Variables */ unsigned int lastdigitts; char sending_digit; /*!< boolean - are we sending digits */ @@ -260,6 +261,8 @@ static int ast_rtp_destroy(struct ast_rtp_instance *instance); static int ast_rtp_dtmf_begin(struct ast_rtp_instance *instance, char digit); static int ast_rtp_dtmf_end(struct ast_rtp_instance *instance, char digit); static int ast_rtp_dtmf_end_with_duration(struct ast_rtp_instance *instance, char digit, unsigned int duration); +static int ast_rtp_dtmf_mode_set(struct ast_rtp_instance *instance, enum ast_rtp_dtmf_mode dtmf_mode); +static enum ast_rtp_dtmf_mode ast_rtp_dtmf_mode_get(struct ast_rtp_instance *instance); static void ast_rtp_update_source(struct ast_rtp_instance *instance); static void ast_rtp_change_source(struct ast_rtp_instance *instance); static int ast_rtp_write(struct ast_rtp_instance *instance, struct ast_frame *frame); @@ -286,6 +289,8 @@ static struct ast_rtp_engine asterisk_rtp_engine = { .dtmf_begin = ast_rtp_dtmf_begin, .dtmf_end = ast_rtp_dtmf_end, .dtmf_end_with_duration = ast_rtp_dtmf_end_with_duration, + .dtmf_mode_set = ast_rtp_dtmf_mode_set, + .dtmf_mode_get = ast_rtp_dtmf_mode_get, .update_source = ast_rtp_update_source, .change_source = ast_rtp_change_source, .write = ast_rtp_write, @@ -534,6 +539,19 @@ static int ast_rtp_destroy(struct ast_rtp_instance *instance) return 0; } +static int ast_rtp_dtmf_mode_set(struct ast_rtp_instance *instance, enum ast_rtp_dtmf_mode dtmf_mode) +{ + struct ast_rtp *rtp = ast_rtp_instance_get_data(instance); + rtp->dtmfmode = dtmf_mode; + return 0; +} + +static enum ast_rtp_dtmf_mode ast_rtp_dtmf_mode_get(struct ast_rtp_instance *instance) +{ + struct ast_rtp *rtp = ast_rtp_instance_get_data(instance); + return rtp->dtmfmode; +} + static int ast_rtp_dtmf_begin(struct ast_rtp_instance *instance, char digit) { struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);