From 857923d9c7129ea7f78cc38d450554a7d61a6697 Mon Sep 17 00:00:00 2001 From: Richard Mudgett Date: Tue, 28 Jul 2015 13:47:31 -0500 Subject: chan_sip.c: Set preferred rx payload type mapping on incoming offers. ASTERISK-25166 Reported by: Kevin Harwell ASTERISK-17410 Reported by: Boris Fox Change-Id: I7f04d5c8bee1126fee5fe6afbc39e45104469f4e --- channels/chan_sip.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) (limited to 'channels/chan_sip.c') diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 5a49392cf..1888091b8 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -1205,7 +1205,7 @@ static void try_suggested_sip_codec(struct sip_pvt *p); static const char *get_sdp_iterate(int* start, struct sip_request *req, const char *name); static char get_sdp_line(int *start, int stop, struct sip_request *req, const char **value); static int find_sdp(struct sip_request *req); -static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action); +static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action, int is_offer); static int process_sdp_o(const char *o, struct sip_pvt *p); static int process_sdp_c(const char *c, struct ast_sockaddr *addr); static int process_sdp_a_sendonly(const char *a, int *sendonly); @@ -9848,7 +9848,7 @@ static int has_media_stream(struct sip_pvt *p, enum media_type m) Return 0 on success, a negative value on errors. Must be called after find_sdp(). */ -static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action) +static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action, int is_offer) { int res = 0; @@ -10539,6 +10539,16 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action change_t38_state(p, T38_DISABLED); } + if (is_offer) { + /* + * Setup rx payload type mapping to prefer the mapping + * from the peer that the RFC says we SHOULD use. + */ + ast_rtp_codecs_payloads_xover(&newaudiortp, &newaudiortp, NULL); + ast_rtp_codecs_payloads_xover(&newvideortp, &newvideortp, NULL); + ast_rtp_codecs_payloads_xover(&newtextrtp, &newtextrtp, NULL); + } + /* Now gather all of the codecs that we are asked for: */ ast_rtp_codecs_payload_formats(&newaudiortp, peercapability, &peernoncodeccapability); ast_rtp_codecs_payload_formats(&newvideortp, vpeercapability, &vpeernoncodeccapability); @@ -23023,7 +23033,7 @@ static void handle_response_invite(struct sip_pvt *p, int resp, const char *rest if (p->invitestate != INV_CANCELLED) { p->invitestate = INV_EARLY_MEDIA; } - res = process_sdp(p, req, SDP_T38_NONE); + res = process_sdp(p, req, SDP_T38_NONE, FALSE); if (!req->ignore && p->owner) { /* Queue a progress frame only if we have SDP in 180 or 182 */ ast_queue_control(p->owner, AST_CONTROL_PROGRESS); @@ -23108,7 +23118,7 @@ static void handle_response_invite(struct sip_pvt *p, int resp, const char *rest if (p->invitestate != INV_CANCELLED) { p->invitestate = INV_EARLY_MEDIA; } - res = process_sdp(p, req, SDP_T38_NONE); + res = process_sdp(p, req, SDP_T38_NONE, FALSE); if (!req->ignore && p->owner) { /* Queue a progress frame */ ast_queue_control(p->owner, AST_CONTROL_PROGRESS); @@ -23134,7 +23144,8 @@ static void handle_response_invite(struct sip_pvt *p, int resp, const char *rest } p->authtries = 0; if (find_sdp(req)) { - if ((res = process_sdp(p, req, SDP_T38_ACCEPT)) && !req->ignore) { + res = process_sdp(p, req, SDP_T38_ACCEPT, FALSE); + if (res && !req->ignore) { if (!reinvite) { /* This 200 OK's SDP is not acceptable, so we need to ack, then hangup */ /* For re-invites, we try to recover */ @@ -24414,7 +24425,7 @@ static void handle_response(struct sip_pvt *p, int resp, const char *rest, struc if (!req->ignore && sip_cancel_destroy(p)) ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); if (find_sdp(req)) - process_sdp(p, req, SDP_T38_NONE); + process_sdp(p, req, SDP_T38_NONE, FALSE); if (p->owner) { /* Queue a progress frame */ ast_queue_control(p->owner, AST_CONTROL_PROGRESS); @@ -25492,7 +25503,7 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, str } /* Handle SDP here if we already have an owner */ if (find_sdp(req)) { - if (process_sdp(p, req, SDP_T38_INITIATE)) { + if (process_sdp(p, req, SDP_T38_INITIATE, TRUE)) { if (!ast_strlen_zero(sip_get_header(req, "Content-Encoding"))) { /* Asterisk does not yet support any Content-Encoding methods. Always * attempt to process the sdp, but return a 415 if a Content-Encoding header @@ -25557,7 +25568,7 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, str /* We have a successful authentication, process the SDP portion if there is one */ if (find_sdp(req)) { - if (process_sdp(p, req, SDP_T38_INITIATE)) { + if (process_sdp(p, req, SDP_T38_INITIATE, TRUE)) { /* Asterisk does not yet support any Content-Encoding methods. Always * attempt to process the sdp, but return a 415 if a Content-Encoding header * was present after processing fails. */ @@ -28163,7 +28174,7 @@ static int handle_incoming(struct sip_pvt *p, struct sip_request *req, struct as p->pendinginvite = 0; acked = __sip_ack(p, seqno, 1 /* response */, 0); if (p->owner && find_sdp(req)) { - if (process_sdp(p, req, SDP_T38_NONE)) { + if (process_sdp(p, req, SDP_T38_NONE, FALSE)) { return -1; } if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) { -- cgit v1.2.3