<p>George Joseph <strong>uploaded patch set #2</strong> to this change.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/14912">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">res_pjsip_session: Handle multi-stream re-invites better<br><br>When both Asterisk and a UA send re-invites at the same time, both<br>send 491 "Transaction in progress" responses to each other and back<br>off a specified amount of time before retrying. When Asterisk<br>prepares to send its re-invite, it sets up the session's pending<br>media state with the new topology it wants, then sends the<br>re-invite. Unfortunately, when it received the re-invite from the<br>UA, it partially processed the media in the re-invite and reset<br>the pending media state before sending the 491 losing the state it<br>set in its own re-invite.<br><br>Asterisk also was not tracking re-invites received while an existing<br>re-invite was queued resulting in sending stale SDP with missing<br>or duplicated streams, or no re-invite at all because we erroneously<br>determined that a re-invite wasn't needed.<br><br>There was also an issue in bridge_softmix where we were using a stream<br>from the wrong topology to determine if a stream was added. This also<br>caused us to erroneously determine that a re-invite wasn't needed.<br><br>Regardless of how the delayed re-invite was triggered, we need to<br>reconcile the topology that was active at the time the delayed<br>request was queued, the pending topology of the queued request,<br>and the topology currently active on the session. To do this we<br>need a topology resolver AND we need to make stream named unique<br>so we can accurately tell what a stream has been added or removed<br>and if we can re-use a slot in the topology.<br><br>Summary of changes:<br><br> * bridge_softmix:<br> * We no longer reset the stream name to "removed" in<br> remove_all_original_streams(). That was causing multiple streams<br> to have the same name and wrecked the checks for duplicate streams.<br><br> * softmix_bridge_stream_sources_update() was checking the old_stream<br> to see if it had the softmix prefix and not considering the stream<br> as "new" if it did. If the stream in that slot has something in it<br> because another re-invite happened, then that slot in old might<br> have a softmix stream but the same stream in new might actually<br> be a new one. Now we check the new_stream's name instead of<br> the old_stream's.<br><br> * stream:<br> * Instead of using plain media type name ("audio", "video", etc) as<br> the default stream name, we now append the stream position to it<br> to make it unique. We need to do this so we can distinguish multiple<br> streams of the same type from each other.<br><br> * When we set a stream's state to REMOVED, we no longer reset its<br> name to "removed" or destroy its metadata. Again, we need to<br> do this so we can distinguish multiple streams of the same<br> type from each other.<br><br> * res_pjsip_session:<br> * Added resolve_refresh_media_states() that takes in 3 media states<br> and creates an up-to-date pending media state that includes the changes<br> that might have happened while a delayed session refresh was in the<br> delayed queue.<br><br> * Added is_media_state_valid() that checks the consistency of<br> a media state and returns a true/false value. A valid state has:<br> * The same number of stream entries as media session entries.<br> Some media session entries can be NULL however.<br> * No duplicate streams.<br> * A valid stream for each non-NULL media session.<br> * A stream that matches each media session's stream_num<br> and media type.<br><br> * Updated handle_incoming_sdp() to set the stream name to include the<br> stream position number in the name to make it unique.<br><br> * Updated the ast_sip_session_delayed_request structure to include both<br> the pending and active media states and updated the associated delay<br> functions to process them.<br><br> * Updated sip_session_refresh() to accept both the pending and active<br> media states that were in effect when the request was originally queued<br> and to pass them on should the request need to be delayed again.<br><br> * Updated sip_session_refresh() to call resolve_refresh_media_states()<br> and substitute its results for the pending state passed in.<br><br> * Updated sip_session_refresh() with additional debugging.<br><br> * Updated session_reinvite_on_rx_request() to simply return PJ_FALSE<br> to pjproject if a transaction is in progress. This stops us from<br> creating a partial pending media state that would be invalid later on.<br><br> * Updated reschedule_reinvite() to clone both the current pending and<br> active media states and pass them to delay_request() so the resolver<br> can tell what the original intention of the re-invite was.<br><br> * Added a large unit test for the resolver.<br><br>ASTERISK-29014<br><br>Change-Id: Id3440972943c611a15f652c6c569fa0e4536bfcb<br>---<br>M bridges/bridge_softmix.c<br>M include/asterisk/stream.h<br>M main/stream.c<br>M res/res_pjsip_session.c<br>4 files changed, 1,253 insertions(+), 122 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/12/14912/2</pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/14912">change 14912</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/c/asterisk/+/14912"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 18 </div>
<div style="display:none"> Gerrit-Change-Id: Id3440972943c611a15f652c6c569fa0e4536bfcb </div>
<div style="display:none"> Gerrit-Change-Number: 14912 </div>
<div style="display:none"> Gerrit-PatchSet: 2 </div>
<div style="display:none"> Gerrit-Owner: George Joseph <gjoseph@digium.com> </div>
<div style="display:none"> Gerrit-CC: Friendly Automation </div>
<div style="display:none"> Gerrit-MessageType: newpatchset </div>