During a pickup/reconnect SEMS answers the picking leg's INVITE with a
(fake) 200 OK and, driven by the reconnect/AA media update, immediately
re-INVITEs the same leg - but the leg has not ACKed the 200 OK yet, so
it gets a re-INVITE on top of an unfinished transaction (overlapping
transactions on its side; the pickup ends up with no audio).
The INVITE transaction is already gone from uas_trans the moment the 2xx
is sent (2xx terminates it, the ACK goes to the TU), so getUASPendingInv()
no longer sees it and both re-INVITE paths fire too early:
- applyPendingUpdate() - the reconnect update queued "for later", gated
by canUpdateSession();
- sendEstablishedReInvite() - the refresh after the other leg's SDP
changed, fired from AmB2BSession::onB2BEvent().
Remember in AmSipDialog the CSeq of the INVITE we answered with a 2xx as
UAS (uas_2xx_ack_cseq) and clear it on the ACK carrying that CSeq, or when
the ACK times out. A plain flag would not be enough: pending_invites is
already decremented and the O/A is complete by the time the 2xx is sent,
so a remote sending its next INVITE before it ACKs is not rejected with
491, and the ACK of the previous INVITE must not open the leg up while
that one is still unacknowledged.
Gate both paths on it - canUpdateSession() returns false while an ACK is
outstanding, and the established refresh is deferred
(pending_established_reinvite) and fired from onTransFinished() once the
ACK finishes the transaction.
Change-Id: I9356c013c813059a2f2c46dcf4cfb9480f3d6f83