diff options
-rw-r--r-- | channels/chan_sip.c | 2 | ||||
-rw-r--r-- | include/asterisk/rtp_engine.h | 2 | ||||
-rw-r--r-- | main/rtp_engine.c | 4 | ||||
-rw-r--r-- | res/res_rtp_asterisk.c | 15 |
4 files changed, 21 insertions, 2 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 80a215cc3..3772c5a68 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -6188,7 +6188,7 @@ static int sip_senddigit_end(struct ast_channel *ast, char digit, unsigned int d break; case SIP_DTMF_RFC2833: if (p->rtp) - ast_rtp_instance_dtmf_end(p->rtp, digit); + ast_rtp_instance_dtmf_end_with_duration(p->rtp, digit, duration); break; case SIP_DTMF_INBAND: if (p->rtp && ast_rtp_instance_dtmf_mode_get(p->rtp) == AST_RTP_DTMF_MODE_INBAND) { diff --git a/include/asterisk/rtp_engine.h b/include/asterisk/rtp_engine.h index 0a2fe7726..74ea34668 100644 --- a/include/asterisk/rtp_engine.h +++ b/include/asterisk/rtp_engine.h @@ -324,6 +324,7 @@ struct ast_rtp_engine { int (*dtmf_begin)(struct ast_rtp_instance *instance, char digit); /*! Callback for stopping RFC2833 DTMF transmission */ int (*dtmf_end)(struct ast_rtp_instance *instance, char digit); + int (*dtmf_end_with_duration)(struct ast_rtp_instance *instance, char digit, unsigned int duration); /*! Callback to indicate that we should update the marker bit */ void (*update_source)(struct ast_rtp_instance *instance); /*! Callback to indicate that we should update the marker bit and ssrc */ @@ -1162,6 +1163,7 @@ int ast_rtp_instance_dtmf_begin(struct ast_rtp_instance *instance, char digit); * \since 1.8 */ int ast_rtp_instance_dtmf_end(struct ast_rtp_instance *instance, char digit); +int ast_rtp_instance_dtmf_end_with_duration(struct ast_rtp_instance *instance, char digit, unsigned int duration); /*! * \brief Set the DTMF mode that should be used diff --git a/main/rtp_engine.c b/main/rtp_engine.c index 9fe5c5a62..ff8ebd481 100644 --- a/main/rtp_engine.c +++ b/main/rtp_engine.c @@ -724,6 +724,10 @@ int ast_rtp_instance_dtmf_end(struct ast_rtp_instance *instance, char digit) { return instance->engine->dtmf_end ? instance->engine->dtmf_end(instance, digit) : -1; } +int ast_rtp_instance_dtmf_end_with_duration(struct ast_rtp_instance *instance, char digit, unsigned int duration) +{ + return instance->engine->dtmf_end_with_duration ? instance->engine->dtmf_end_with_duration(instance, digit, duration) : -1; +} int ast_rtp_instance_dtmf_mode_set(struct ast_rtp_instance *instance, enum ast_rtp_dtmf_mode dtmf_mode) { diff --git a/res/res_rtp_asterisk.c b/res/res_rtp_asterisk.c index 643794890..ffd7b2596 100644 --- a/res/res_rtp_asterisk.c +++ b/res/res_rtp_asterisk.c @@ -255,6 +255,7 @@ static int ast_rtp_new(struct ast_rtp_instance *instance, struct sched_context * 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 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); @@ -279,6 +280,7 @@ static struct ast_rtp_engine asterisk_rtp_engine = { .destroy = ast_rtp_destroy, .dtmf_begin = ast_rtp_dtmf_begin, .dtmf_end = ast_rtp_dtmf_end, + .dtmf_end_with_duration = ast_rtp_dtmf_end_with_duration, .update_source = ast_rtp_update_source, .change_source = ast_rtp_change_source, .write = ast_rtp_write, @@ -639,13 +641,14 @@ static int ast_rtp_dtmf_continuation(struct ast_rtp_instance *instance) return 0; } -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) { struct ast_rtp *rtp = ast_rtp_instance_get_data(instance); struct ast_sockaddr remote_address = { {0,} }; int hdrlen = 12, res = 0, i = 0; char data[256]; unsigned int *rtpheader = (unsigned int*)data; + unsigned int measured_samples; ast_rtp_instance_get_remote_address(instance, &remote_address); @@ -672,6 +675,11 @@ static int ast_rtp_dtmf_end(struct ast_rtp_instance *instance, char digit) rtp->dtmfmute = ast_tvadd(ast_tvnow(), ast_tv(0, 500000)); + if (duration > 0 && (measured_samples = duration * rtp_get_rate(rtp->f.subclass.codec) / 1000) > rtp->send_duration) { + ast_debug(2, "Adjusting final end duration from %u to %u\n", rtp->send_duration, measured_samples); + rtp->send_duration = measured_samples; + } + /* Construct the packet we are going to send */ rtpheader[0] = htonl((2 << 30) | (1 << 23) | (rtp->send_payload << 16) | (rtp->seqno)); rtpheader[1] = htonl(rtp->lastdigitts); @@ -703,6 +711,11 @@ static int ast_rtp_dtmf_end(struct ast_rtp_instance *instance, char digit) return 0; } +static int ast_rtp_dtmf_end(struct ast_rtp_instance *instance, char digit) +{ + return ast_rtp_dtmf_end_with_duration(instance, digit, 0); +} + static void ast_rtp_update_source(struct ast_rtp_instance *instance) { struct ast_rtp *rtp = ast_rtp_instance_get_data(instance); |