diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 460e30ece24d04d746356117c120725a6a619f5f..9134f4453cb5928a786ffdfc64a2b7b1d48a96c5 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -20141,7 +20141,7 @@ static void handle_response_invite(struct sip_pvt *p, int resp, const char *rest "Channel: %s\r\nChanneltype: %s\r\nUniqueid: %s\r\nSIPcallid: %s\r\nSIPfullcontact: %s\r\nPeername: %s\r\n", p->owner->name, "SIP", p->owner->uniqueid, p->callid, p->fullcontact, p->peername); } else { /* RE-invite */ - ast_queue_frame(p->owner, &ast_null_frame); + ast_queue_control(p->owner, AST_CONTROL_UPDATE_RTP_PEER); } } else { /* It's possible we're getting an 200 OK after we've tried to disconnect @@ -23024,6 +23024,7 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int } else { ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); transmit_response_with_sdp(p, "200 OK", req, (reinvite ? XMIT_RELIABLE : (req->ignore ? XMIT_UNRELIABLE : XMIT_CRITICAL)), p->session_modify == TRUE ? FALSE : TRUE, FALSE); + ast_queue_control(p->owner, AST_CONTROL_UPDATE_RTP_PEER); } } @@ -29286,7 +29287,7 @@ static int sip_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *i memset(&p->tredirip, 0, sizeof(p->tredirip)); changed = 1; } - if (cap && !(ast_format_cap_is_empty(cap) && !(ast_format_cap_identical(p->redircaps, cap)))) { + if (cap && !ast_format_cap_is_empty(cap) && !ast_format_cap_identical(p->redircaps, cap)) { ast_format_cap_copy(p->redircaps, cap); changed = 1; } diff --git a/include/asterisk/frame.h b/include/asterisk/frame.h index f8cb71c6ace3432dcca9a641123afc919f83d92c..4e013534db735b55a70ddcb37f99402c6fd77f0e 100644 --- a/include/asterisk/frame.h +++ b/include/asterisk/frame.h @@ -265,6 +265,7 @@ enum ast_control_frame_type { AST_CONTROL_END_OF_Q = 29, /*!< Indicate that this position was the end of the channel queue for a softhangup. */ AST_CONTROL_INCOMPLETE = 30, /*!< Indication that the extension dialed is incomplete */ AST_CONTROL_MCID = 31, /*!< Indicate that the caller is being malicious. */ + AST_CONTROL_UPDATE_RTP_PEER = 32, /*!< Interrupt the bridge and have it update the peer */ }; enum ast_frame_read_action { diff --git a/main/channel.c b/main/channel.c index 4015e80a1e12cdf39a09fbba21358dbb0b518890..2393b6a0405c3d5f5143f3a5b2e747030e2706f3 100644 --- a/main/channel.c +++ b/main/channel.c @@ -4345,6 +4345,7 @@ static int attribute_const is_visible_indication(enum ast_control_frame_type con case AST_CONTROL_AOC: case AST_CONTROL_END_OF_Q: case AST_CONTROL_MCID: + case AST_CONTROL_UPDATE_RTP_PEER: break; case AST_CONTROL_INCOMPLETE: @@ -4533,6 +4534,7 @@ int ast_indicate_data(struct ast_channel *chan, int _condition, case AST_CONTROL_AOC: case AST_CONTROL_END_OF_Q: case AST_CONTROL_MCID: + case AST_CONTROL_UPDATE_RTP_PEER: /* Nothing left to do for these. */ res = 0; break; diff --git a/main/rtp_engine.c b/main/rtp_engine.c index 9605d62775a68f38ea9fdcec85c9c8b2b85a9e15..730fdcdb2d1245caf43004ea43b9ff22512f6a46 100644 --- a/main/rtp_engine.c +++ b/main/rtp_engine.c @@ -1158,7 +1158,8 @@ static enum ast_bridge_result remote_bridge_loop(struct ast_channel *c0, (fr->subclass.integer == AST_CONTROL_UNHOLD) || (fr->subclass.integer == AST_CONTROL_VIDUPDATE) || (fr->subclass.integer == AST_CONTROL_SRCUPDATE) || - (fr->subclass.integer == AST_CONTROL_T38_PARAMETERS)) { + (fr->subclass.integer == AST_CONTROL_T38_PARAMETERS) || + (fr->subclass.integer == AST_CONTROL_UPDATE_RTP_PEER)) { if (fr->subclass.integer == AST_CONTROL_HOLD) { /* If we someone went on hold we want the other side to reinvite back to us */ if (who == c0) { @@ -1166,8 +1167,10 @@ static enum ast_bridge_result remote_bridge_loop(struct ast_channel *c0, } else { glue0->update_peer(c0, NULL, NULL, NULL, 0, 0); } - } else if (fr->subclass.integer == AST_CONTROL_UNHOLD) { - /* If they went off hold they should go back to being direct */ + } else if (fr->subclass.integer == AST_CONTROL_UNHOLD || + fr->subclass.integer == AST_CONTROL_UPDATE_RTP_PEER) { + /* If they went off hold they should go back to being direct, or if we have + * been told to force a peer update, go ahead and do it. */ if (who == c0) { glue1->update_peer(c1, instance0, vinstance0, tinstance0, cap0, 0); } else { @@ -1193,7 +1196,10 @@ static enum ast_bridge_result remote_bridge_loop(struct ast_channel *c0, glue0->get_codec(c1, cap1); ast_format_cap_append(oldcap1, cap1); } - ast_indicate_data(other, fr->subclass.integer, fr->data.ptr, fr->datalen); + /* Since UPDATE_BRIDGE_PEER is only used by the bridging code, don't forward it */ + if (fr->subclass.integer != AST_CONTROL_UPDATE_RTP_PEER) { + ast_indicate_data(other, fr->subclass.integer, fr->data.ptr, fr->datalen); + } ast_frfree(fr); } else if (fr->subclass.integer == AST_CONTROL_CONNECTED_LINE) { if (ast_channel_connected_line_macro(who, other, fr, other == c0, 1)) {