Hi Babak, sorry for the late reply. I've been quite busy here lately.
Your setup seems very complicated, I am not sure if that's for a reason or something that "just happened". One immediate problem is that the call is proxied twice - even before FS is switched in, the RTP already takes 4 hops:
RTP in, ssrc=0x3a8d7fbe: 205.1:4008 -> 205.34:20042/20012 -> 205.34:20068/20020 -> 205.1:4006
RTP out,
ssrc=0x339a275d: 205.1:4006 -> 205.34:20020/20068 -> 205.34:20012/20042 -> 205.1:4008
Two hops in the middle is basically RTPPproxy sending packets to itself between call legs. This of course increases delay and jitter, as well as doubles the work for the RTPProxy. It is a good practice to only pin media once in general, either when the inbound leg comes in or when outbound leg goes out
Now, a little bit later FS comes in and tries to update both legs to make the session like the following. Square brackets indicate the part where packets don't reach:
RTP in, ssrc=0xf7229438: 205.129:18804 -> 205.134:20068 [/20020 -> 205.1:4006]
RTP out, ssrc=0xf71e7468: 205.129:17100 -> 205.134:20012 [/20042 -> 205.1:4008]
The reason this does not really work I think is that the RTPProxy historically and by design treats any IP/port in the re-INVITE with utter suspicion, more like a hint than actual direction by default. This is because it's designed to provide NAT traversal in the majority of cases. Including the weird case of either side to "float" to the new IP:port without any notification from the signalling end (i.e. roaming between hot spots).
So it normally expects the original sender to stop sending packets before it can fully switch over to the new IP/port from the re-INVITE. In your case, however, since original endpoints are shielded from the port change in re-INVITE by the virtue of having rtpproxy essentially in the middle of the call twice on both sides (i.e. you are trying to go from UA1<->RTPP(1)<->RTPP(2)<->UA2 to UA1<->RTPP(1)<->FS<->RTPP(2)<->UA2 and then back when the playback is done) , both sessions in the RTPProxy keep receiving packets from their originally latched sources, i.e. RTPP(1) continues receiving packets from RTPP(2) and new stream comes from FS and RTPP(2) keeps receiving packets from RTPP(1) and FS starts sending, that re-latch never happens on neither end. On top of that, the stream generated by the FS has (obviously) different SSRC, so again it makes RTPProxy a bit suspicious if it's some kind of foul play (google "RTP Bleed" attack) and very reluctant to switch over.
I cannot tell for sure since I am not familiar with its logic and defaults, but I suspect the rtpengine has none of those features, which may explain the difference...
In any case the situation ends up in a stalemate: both RTPP sessions keep happily receiving/sending packets from each other, totally ignoring that additional streams from the FS.
Now, as I said there at least one solution to your particular problem, in fact more like at least 4:
1. Since having two sessions on both ends is wasteful and inefficient, consider straightening that out. So instead make your RTP path look like the following:
UA1<->OPENSIPS/RTPP<->OPENSIPS<->UA2
Then when FS comes in and triggers re-invite on both legs, the UA1 would be shielded from that port change, while UA2 won't (since there is no RTPProxy on the outbound leg). As a result UA2 would start sending RTP directly to FS (as opposed to the RTPProxy), the RTPProxy would stop receiving that traffic from UA2 on its outbound "leg" and latch FS instead, resulting in a proper RTP path being:
UA1<->RTPP<->FS<->UA2
This may or not may be solution to your problem. If you still want for whatever reason shield UA2 from getting RTP traffic directly from the FS, then my next pick is:
2) Only create RTPP(2) session when FS wants to talk and abandon when it stops. This can be accomplished by enabling OpenSIPS on inbound call leg to append a:nortpproxy=yes attribute (default behavior) and OpenSIPS on the outbound leg obey it. Then original session would look like expected, i.e.:
UA1<->RTPP(1)<->UA2
Then when FS intervenes, neither of re-INVITEs has that attribute, so the new RTPP session on outbound leg is allocated and the chain becomes:
UA1<->RTPP(1)<->FS<->RTPP(2)<->UA2
RTPP(1) stops receiving RTP from the UA2 and happily re-latches to FS instead. :)
Then again after FS drops out that should reduce the RTP flow back to the following and RTPP(2) session eventually timeouts:
3) Disable any NAT compensation in the RTPProxy in general. Bit of a hevy-weight, but if you expect both UA1 and UA2 to provide trustworthy IP:port in the SDP i.e. if you are only concerned with the topology hiding and don't have NAT in or out it might be the easiest way to go. This should make RTPProxy obey any IP:port combinations it gets from OpenSIPS verbatim. There was functionality for that in RTPProxy, however turns out it was not exposed, so I've just added a new option for that --force_asymmetric (
https://github.com/sippy/rtpproxy/compare/f18630dfa014...7be7d5598a4e)
4) Disable NAT compensation for the RTP "leg" that goes to/fro FS. This one might be a bit trickier to implement - you'd have to have a logic in both request route and response route to add "A" flag into (re-)INVITE that goes from FS and 200/183 that it generates.
Hope it helps. 😀
-Max