Merged revisions 336307 via svnmerge from

https://origsvn.digium.com/svn/asterisk/branches/10

................
  r336307 | jrose | 2011-09-16 16:09:20 -0500 (Fri, 16 Sep 2011) | 20 lines
  
  Merged revisions 336294 via svnmerge from 
  https://origsvn.digium.com/svn/asterisk/branches/1.8
  
  ........
    r336294 | jrose | 2011-09-16 14:53:40 -0500 (Fri, 16 Sep 2011) | 13 lines
    
    Fix bad RTP media bridges in directmedia calls on peers separated by multiple Asterisk nodes.
    
    In a situation involving devices on separate Asterisk trunks, the remote RTP bridge would
    break when starting a call with directmedia. This patch queues a new type of control frame
    so that our RTP bridge loop can properly detect when these situations occur and check to see
    if peers need to be updated in order to send their media to the proper location.
    
    (Closes issue ASTERISK-18340)
    Reported by: Thomas Arimont
    (Closes issue ASTERISK-17725)
    Reported by: kwk
    Tested by: twilson, jrose
  ........
................


git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@336311 65c4cc65-6c06-0410-ace0-fbb531ad65f3
certified/11.2
Jonathan Rose 14 years ago
parent 9112b5c75d
commit beae2df26e

@ -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;
}

@ -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 {

@ -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;

@ -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)) {

Loading…
Cancel
Save