diff options
-rw-r--r-- | channels/chan_sip.c | 23 | ||||
-rw-r--r-- | configs/sip.conf.sample | 2 | ||||
-rw-r--r-- | include/asterisk/rtp.h | 3 | ||||
-rw-r--r-- | main/rtp.c | 10 |
4 files changed, 36 insertions, 2 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 029c15728..688ff81ef 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -1061,6 +1061,7 @@ struct sip_auth { #define SIP_PAGE2_RTCACHEFRIENDS (1 << 0) /*!< GP: Should we keep RT objects in memory for extended time? */ #define SIP_PAGE2_RTAUTOCLEAR (1 << 2) /*!< GP: Should we clean memory from peers after expiry? */ /* Space for addition of other realtime flags in the future */ +#define SIP_PAGE2_CONSTANT_SSRC (1 << 8) /*!< GDP: Don't change SSRC on reinvite */ #define SIP_PAGE2_STATECHANGEQUEUE (1 << 9) /*!< D: Unsent state pending change exists */ #define SIP_PAGE2_RPORT_PRESENT (1 << 10) /*!< Was rport received in the Via header? */ @@ -1092,7 +1093,7 @@ struct sip_auth { (SIP_PAGE2_ALLOWSUBSCRIBE | SIP_PAGE2_ALLOWOVERLAP | SIP_PAGE2_IGNORESDPVERSION | \ SIP_PAGE2_VIDEOSUPPORT | SIP_PAGE2_T38SUPPORT | SIP_PAGE2_RFC2833_COMPENSATE | \ SIP_PAGE2_BUGGY_MWI | SIP_PAGE2_TEXTSUPPORT | \ - SIP_PAGE2_UDPTL_DESTINATION | SIP_PAGE2_VIDEOSUPPORT_ALWAYS) + SIP_PAGE2_UDPTL_DESTINATION | SIP_PAGE2_VIDEOSUPPORT_ALWAYS | SIP_PAGE2_CONSTANT_SSRC) /*@}*/ @@ -4525,6 +4526,9 @@ static int create_addr_from_peer(struct sip_pvt *dialog, struct sip_peer *peer) ast_rtp_set_rtptimeout(dialog->rtp, peer->rtptimeout); ast_rtp_set_rtpholdtimeout(dialog->rtp, peer->rtpholdtimeout); ast_rtp_set_rtpkeepalive(dialog->rtp, peer->rtpkeepalive); + if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_CONSTANT_SSRC)) { + ast_rtp_set_constantssrc(dialog->rtp); + } /* Set Frame packetization */ ast_rtp_codec_setpref(dialog->rtp, &dialog->prefs); dialog->autoframing = peer->autoframing; @@ -4535,6 +4539,9 @@ static int create_addr_from_peer(struct sip_pvt *dialog, struct sip_peer *peer) ast_rtp_set_rtptimeout(dialog->vrtp, peer->rtptimeout); ast_rtp_set_rtpholdtimeout(dialog->vrtp, peer->rtpholdtimeout); ast_rtp_set_rtpkeepalive(dialog->vrtp, peer->rtpkeepalive); + if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_CONSTANT_SSRC)) { + ast_rtp_set_constantssrc(dialog->vrtp); + } } if (dialog->trtp) { /* Realtime text */ ast_rtp_setdtmf(dialog->trtp, 0); @@ -18501,6 +18508,7 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); return -1; } + ast_queue_control(p->owner, AST_CONTROL_SRCUPDATE); } else { p->jointcapability = p->capability; ast_debug(1, "Hm.... No sdp for the moment\n"); @@ -18549,6 +18557,14 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int ast_debug(1, "No compatible codecs for this SIP call.\n"); return -1; } + if (ast_test_flag(&p->flags[1], SIP_PAGE2_CONSTANT_SSRC)) { + if (p->rtp) { + ast_rtp_set_constantssrc(p->rtp); + } + if (p->vrtp) { + ast_rtp_set_constantssrc(p->vrtp); + } + } } else { /* No SDP in invite, call control session */ p->jointcapability = p->capability; ast_debug(2, "No SDP in Invite, third party call control\n"); @@ -21795,6 +21811,9 @@ static int handle_common_options(struct ast_flags *flags, struct ast_flags *mask } else if (!strcasecmp(v->name, "t38pt_usertpsource")) { ast_set_flag(&mask[1], SIP_PAGE2_UDPTL_DESTINATION); ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_UDPTL_DESTINATION); + } else if (!strcasecmp(v->name, "constantssrc")) { + ast_set_flag(&mask[1], SIP_PAGE2_CONSTANT_SSRC); + ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_CONSTANT_SSRC); } else res = 0; @@ -23173,6 +23192,8 @@ static int reload_config(enum channelreloadreason reason) default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE; } else if (!strcasecmp(v->name, "matchexterniplocally")) { global_matchexterniplocally = ast_true(v->value); + } else if (!strcasecmp(v->name, "constantssrc")) { + ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_CONSTANT_SSRC); } else if (!strcasecmp(v->name, "session-timers")) { int i = (int) str2stmode(v->value); if (i < 0) { diff --git a/configs/sip.conf.sample b/configs/sip.conf.sample index a56941e71..7dd8f2838 100644 --- a/configs/sip.conf.sample +++ b/configs/sip.conf.sample @@ -633,6 +633,8 @@ srvlookup=yes ; Enable DNS SRV lookups on outbound calls ; (observed with Microsoft OCS). By default this option is ; off. +;constantssrc=yes ; Don't change the RTP SSRC when our media stream changes + ;----------------------------------------- REALTIME SUPPORT ------------------------ ; For additional information on ARA, the Asterisk Realtime Architecture, ; please read realtime.txt and extconfig.txt in the /doc directory of the diff --git a/include/asterisk/rtp.h b/include/asterisk/rtp.h index f9076d54b..3037c5e32 100644 --- a/include/asterisk/rtp.h +++ b/include/asterisk/rtp.h @@ -210,6 +210,9 @@ int ast_rtp_sendcng(struct ast_rtp *rtp, int level); int ast_rtp_setqos(struct ast_rtp *rtp, int tos, int cos, char *desc); +/*! \brief When changing sources, don't generate a new SSRC */ +void ast_rtp_set_constantssrc(struct ast_rtp *rtp); + void ast_rtp_new_source(struct ast_rtp *rtp); /*! \brief Setting RTP payload types from lines in a SDP description: */ diff --git a/main/rtp.c b/main/rtp.c index dcd6807b2..de50a0397 100644 --- a/main/rtp.c +++ b/main/rtp.c @@ -181,6 +181,7 @@ struct ast_rtp { struct sockaddr_in strict_rtp_address; /*!< Remote address information for strict RTP purposes */ int set_marker_bit:1; /*!< Whether to set the marker bit or not */ + unsigned int constantssrc:1; struct rtp_red *red; }; @@ -2604,12 +2605,19 @@ int ast_rtp_setqos(struct ast_rtp *rtp, int type_of_service, int class_of_servic return ast_netsock_set_qos(rtp->s, type_of_service, class_of_service, desc); } +void ast_rtp_set_constantssrc(struct ast_rtp *rtp) +{ + rtp->constantssrc = 1; +} + void ast_rtp_new_source(struct ast_rtp *rtp) { if (rtp) { rtp->set_marker_bit = 1; + if (!rtp->constantssrc) { + rtp->ssrc = ast_random(); + } } - return; } void ast_rtp_set_peer(struct ast_rtp *rtp, struct sockaddr_in *them) |