aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--channels/chan_sip.c2
-rw-r--r--include/asterisk/rtp_engine.h2
-rw-r--r--main/rtp_engine.c4
-rw-r--r--res/res_rtp_asterisk.c15
4 files changed, 21 insertions, 2 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index e1251914d..78d9fe0ae 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -6224,7 +6224,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);