summaryrefslogtreecommitdiff
path: root/res
diff options
context:
space:
mode:
authorJoshua Colp <jcolp@digium.com>2015-08-28 22:22:45 -0300
committerJoshua Colp <jcolp@digium.com>2015-08-28 22:22:45 -0300
commit1b1561f4c854c37691bd24227b8f722d1dac4291 (patch)
tree2f12192460705eb887030ee7f16dcb6637f6862c /res
parentb5801fe42c37f4a9c075b2e96b108ce2344d23e9 (diff)
res_pjsip_sdp_rtp: Fix multiple keepalive scheduled items.
The keepalive support in res_pjsip_sdp_rtp currently assumes that a stream will only be negotiated once. This is false. If the stream is replaced and later added back it can be negotiated again causing multiple keepalive scheduled items to exist. This change explicitly deletes the existing keepalive scheduled item before adding the new one. The res_pjsip_sdp_rtp module also does not stop RTP keepalives or timeout timer if the stream has been replaced. This change adds a callback to the session media interface to allow a media stream to be stopped without the resources being destroyed. This allows the scheduled items and RTP to be stopped when the stream no longer exists. ASTERISK-25356 #close Change-Id: Ibe6a7cc0927c87326fd5f1c0d4ad889dbfbea1de
Diffstat (limited to 'res')
-rw-r--r--res/res_pjsip_sdp_rtp.c19
-rw-r--r--res/res_pjsip_session.c7
2 files changed, 23 insertions, 3 deletions
diff --git a/res/res_pjsip_sdp_rtp.c b/res/res_pjsip_sdp_rtp.c
index f6c300f1f..df2820479 100644
--- a/res/res_pjsip_sdp_rtp.c
+++ b/res/res_pjsip_sdp_rtp.c
@@ -1307,6 +1307,7 @@ static int apply_negotiated_sdp_stream(struct ast_sip_session *session, struct a
* a NAT. This way there won't be an awkward delay before media starts flowing in some
* scenarios.
*/
+ AST_SCHED_DEL(sched, session_media->keepalive_sched_id);
session_media->keepalive_sched_id = ast_sched_add_variable(sched, 500, send_keepalive,
session_media, 1);
}
@@ -1358,13 +1359,23 @@ static void change_outgoing_sdp_stream_media_address(pjsip_tx_data *tdata, struc
pj_strdup2(tdata->pool, &stream->conn->addr, transport->external_media_address);
}
+/*! \brief Function which stops the RTP instance */
+static void stream_stop(struct ast_sip_session_media *session_media)
+{
+ if (!session_media->rtp) {
+ return;
+ }
+
+ AST_SCHED_DEL(sched, session_media->keepalive_sched_id);
+ AST_SCHED_DEL(sched, session_media->timeout_sched_id);
+ ast_rtp_instance_stop(session_media->rtp);
+}
+
/*! \brief Function which destroys the RTP instance when session ends */
static void stream_destroy(struct ast_sip_session_media *session_media)
{
if (session_media->rtp) {
- AST_SCHED_DEL(sched, session_media->keepalive_sched_id);
- AST_SCHED_DEL(sched, session_media->timeout_sched_id);
- ast_rtp_instance_stop(session_media->rtp);
+ stream_stop(session_media);
ast_rtp_instance_destroy(session_media->rtp);
}
session_media->rtp = NULL;
@@ -1377,6 +1388,7 @@ static struct ast_sip_session_sdp_handler audio_sdp_handler = {
.create_outgoing_sdp_stream = create_outgoing_sdp_stream,
.apply_negotiated_sdp_stream = apply_negotiated_sdp_stream,
.change_outgoing_sdp_stream_media_address = change_outgoing_sdp_stream_media_address,
+ .stream_stop = stream_stop,
.stream_destroy = stream_destroy,
};
@@ -1387,6 +1399,7 @@ static struct ast_sip_session_sdp_handler video_sdp_handler = {
.create_outgoing_sdp_stream = create_outgoing_sdp_stream,
.apply_negotiated_sdp_stream = apply_negotiated_sdp_stream,
.change_outgoing_sdp_stream_media_address = change_outgoing_sdp_stream_media_address,
+ .stream_stop = stream_stop,
.stream_destroy = stream_destroy,
};
diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c
index 16ac640d9..16ed38dd0 100644
--- a/res/res_pjsip_session.c
+++ b/res/res_pjsip_session.c
@@ -362,6 +362,13 @@ static int handle_negotiated_sdp_session_media(void *obj, void *arg, int flags)
}
}
}
+
+ if (session_media->handler && session_media->handler->stream_stop) {
+ ast_debug(1, "Stopping SDP media stream '%s' as it is not currently negotiated\n",
+ session_media->stream_type);
+ session_media->handler->stream_stop(session_media);
+ }
+
return CMP_MATCH;
}