diff options
author | Joshua Colp <jcolp@digium.com> | 2015-07-20 15:52:38 -0500 |
---|---|---|
committer | Gerrit Code Review <gerrit2@gerrit.digium.api> | 2015-07-20 15:52:38 -0500 |
commit | f7f3ae1815d30a7861dd1d6013996f6d82c32431 (patch) | |
tree | 6e1c1c7c9f87e28c1171779e020798a094ab4a62 /res | |
parent | 6741eedeceba083267a3d8223c911b0b5c6a98d0 (diff) | |
parent | 2b42264e66656f6ab6bc664eec4e93d353c58ffe (diff) |
Merge "res_pjsip: Add rtp_keepalive endpoint option."
Diffstat (limited to 'res')
-rw-r--r-- | res/res_pjsip.c | 8 | ||||
-rw-r--r-- | res/res_pjsip/pjsip_configuration.c | 1 | ||||
-rw-r--r-- | res/res_pjsip_sdp_rtp.c | 47 | ||||
-rw-r--r-- | res/res_pjsip_session.c | 1 | ||||
-rw-r--r-- | res/res_rtp_asterisk.c | 7 |
5 files changed, 63 insertions, 1 deletions
diff --git a/res/res_pjsip.c b/res/res_pjsip.c index 6d7e4f739..fefbff446 100644 --- a/res/res_pjsip.c +++ b/res/res_pjsip.c @@ -790,6 +790,14 @@ have this accountcode set on it. </para></description> </configOption> + <configOption name="rtp_keepalive"> + <synopsis>Number of seconds between RTP comfort noise keepalive packets.</synopsis> + <description><para> + At the specified interval, Asterisk will send an RTP comfort noise frame. This may + be useful for situations where Asterisk is behind a NAT or firewall and must keep + a hole open in order to allow for media to arrive at Asterisk. + </para></description> + </configOption> </configObject> <configObject name="auth"> <synopsis>Authentication type</synopsis> diff --git a/res/res_pjsip/pjsip_configuration.c b/res/res_pjsip/pjsip_configuration.c index e2e5e06b9..31933e352 100644 --- a/res/res_pjsip/pjsip_configuration.c +++ b/res/res_pjsip/pjsip_configuration.c @@ -1880,6 +1880,7 @@ int ast_res_pjsip_initialize_configuration(void) ast_sorcery_object_field_register(sip_sorcery, "endpoint", "use_avpf", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, media.rtp.use_avpf)); ast_sorcery_object_field_register(sip_sorcery, "endpoint", "force_avp", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, media.rtp.force_avp)); ast_sorcery_object_field_register(sip_sorcery, "endpoint", "media_use_received_transport", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, media.rtp.use_received_transport)); + ast_sorcery_object_field_register(sip_sorcery, "endpoint", "rtp_keepalive", "0", OPT_UINT_T, 0, FLDSET(struct ast_sip_endpoint, media.rtp.keepalive)); ast_sorcery_object_field_register(sip_sorcery, "endpoint", "one_touch_recording", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, info.recording.enabled)); ast_sorcery_object_field_register(sip_sorcery, "endpoint", "inband_progress", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, inband_progress)); ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "call_group", "", group_handler, callgroup_to_str, NULL, 0, 0); diff --git a/res/res_pjsip_sdp_rtp.c b/res/res_pjsip_sdp_rtp.c index 22c4529d9..e8654a91f 100644 --- a/res/res_pjsip_sdp_rtp.c +++ b/res/res_pjsip_sdp_rtp.c @@ -107,6 +107,39 @@ static void format_cap_only_type(struct ast_format_cap *caps, enum ast_media_typ } } +static int send_keepalive(const void *data) +{ + struct ast_sip_session_media *session_media = (struct ast_sip_session_media *) data; + struct ast_rtp_instance *rtp = session_media->rtp; + int keepalive; + time_t interval; + int send_keepalive; + + if (!rtp) { + return 0; + } + + keepalive = ast_rtp_instance_get_keepalive(rtp); + + if (!ast_sockaddr_isnull(&session_media->direct_media_addr)) { + ast_debug(3, "Not sending RTP keepalive on RTP instance %p since direct media is in use\n", rtp); + return keepalive * 1000; + } + + interval = time(NULL) - ast_rtp_instance_get_last_tx(rtp); + send_keepalive = interval >= keepalive; + + ast_debug(3, "It has been %d seconds since RTP was last sent on instance %p. %sending keepalive\n", + (int) interval, rtp, send_keepalive ? "S" : "Not s"); + + if (send_keepalive) { + ast_rtp_instance_sendcng(rtp, 0); + return keepalive * 1000; + } + + return (keepalive - interval) * 1000; +} + /*! \brief Internal function which creates an RTP instance */ static int create_rtp(struct ast_sip_session *session, struct ast_sip_session_media *session_media, unsigned int ipv6) { @@ -1228,6 +1261,17 @@ static int apply_negotiated_sdp_stream(struct ast_sip_session *session, struct a /* This purposely resets the encryption to the configured in case it gets added later */ session_media->encryption = session->endpoint->media.rtp.encryption; + if (session->endpoint->media.rtp.keepalive > 0 && + stream_to_media_type(session_media->stream_type) == AST_MEDIA_TYPE_AUDIO) { + ast_rtp_instance_set_keepalive(session_media->rtp, session->endpoint->media.rtp.keepalive); + /* Schedule the initial keepalive early in case this is being used to punch holes through + * a NAT. This way there won't be an awkward delay before media starts flowing in some + * scenarios. + */ + session_media->keepalive_sched_id = ast_sched_add_variable(sched, 500, send_keepalive, + session_media, 1); + } + return 1; } @@ -1257,6 +1301,9 @@ static void change_outgoing_sdp_stream_media_address(pjsip_tx_data *tdata, struc static void stream_destroy(struct ast_sip_session_media *session_media) { if (session_media->rtp) { + if (session_media->keepalive_sched_id != -1) { + AST_SCHED_DEL(sched, session_media->keepalive_sched_id); + } ast_rtp_instance_stop(session_media->rtp); ast_rtp_instance_destroy(session_media->rtp); } diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c index ce5237717..eff8bbb12 100644 --- a/res/res_pjsip_session.c +++ b/res/res_pjsip_session.c @@ -1220,6 +1220,7 @@ static int add_session_media(void *obj, void *arg, int flags) return CMP_STOP; } session_media->encryption = session->endpoint->media.rtp.encryption; + session_media->keepalive_sched_id = -1; /* Safe use of strcpy */ strcpy(session_media->stream_type, handler_list->stream_type); ao2_link(session->media, session_media); diff --git a/res/res_rtp_asterisk.c b/res/res_rtp_asterisk.c index 0a68a2db7..53e9b29c2 100644 --- a/res/res_rtp_asterisk.c +++ b/res/res_rtp_asterisk.c @@ -2166,6 +2166,7 @@ static int __rtp_sendto(struct ast_rtp_instance *instance, void *buf, size_t siz void *temp = buf; struct ast_rtp *rtp = ast_rtp_instance_get_data(instance); struct ast_srtp *srtp = ast_rtp_instance_get_srtp(instance); + int res; *ice = 0; @@ -2184,7 +2185,11 @@ static int __rtp_sendto(struct ast_rtp_instance *instance, void *buf, size_t siz } #endif - return ast_sendto(rtcp ? rtp->rtcp->s : rtp->s, temp, len, flags, sa); + res = ast_sendto(rtcp ? rtp->rtcp->s : rtp->s, temp, len, flags, sa); + if (res > 0) { + ast_rtp_instance_set_last_tx(instance, time(NULL)); + } + return res; } static int rtcp_sendto(struct ast_rtp_instance *instance, void *buf, size_t size, int flags, struct ast_sockaddr *sa, int *ice) |