[recon-devel] Some problems occur after session is replaced.
Hi,
I am using resiprocate-1.6.
I tried Transfer-Attended sequence with a sip proxy server(repro) and my SIP-UA applications which using recon.
A...B...C
|...|...|
|<=>|...| two party call between A and B.
|...|<=>| two party call between B and C.
:...:...:
|...|...| B execute recon::ConversationManager::rediretToParticipant(A,C)
|<R-|...| B send REFER(repleces) to A.
|-INV-->| A send INVITE(repleces) to C.
|<-200--| C respond 200OK(INVITE) to A.
:...:...:
see also
I use the recon::ConversationManager::rediretToParticipant().
But my application using RECON acted two motions not intended.
=== 1st problem ===
This may be not problem.
- After receiving INVITE with Replaces header,
my applications which confirmed new session replaced sent re-INVITEs and 491 responses each other.
A...B...C
:...:...:
|...|...| B execute rediretToParticipant(A,C)
|<R-|...| B send REFER(repleces) to A.
|-INV-->| A send INVITE(repleces) to C.
|<-200--| C respond 200OK(INVITE) to A.
|-INV-->| A send re-INVITE to C.
|<-INV--| C send re-INVITE to A.
|-491-->| A respond 491 Request Pending to C.
|<-491--| C respond 491 Request Pending to A.
:...:...:
These re-INVITEs caused by unhold() in RemoteParticipant::stateTransition(Connected);
This unhold() is called because mPendingRequest.mType is Unhold.
mPendingRequest.mType is set according to the following timing.
+ receive INVITE(repleces)
.+ new RemoteParticipant is created. RemoteParticipant::mLocalHold is set true by constructor.
.+ RemoteParticipant::onNewSession(Server)
..+ participantToReplace->replaceWithParticipant(this);
...+ Participant::copyConversationsToParticipant()
....+ RemoteParticipant::addToConversation()
.....+ if(mLocalHold && !conversation->shouldHold())
.....+ unhold()
......+ mPendingRequest.mType = Unhold;
or
+ receive REFER(replaces)
.+ RemoteParticipant::onRefer()
..+ new RemoteParticipant is created. RemoteParticipant::mLocalHold is set true by constructor.
..+ replaceWithParticipant(participant);
...+ Participant::copyConversationsToParticipant()
....+ RemoteParticipant::addToConversation()
.....+ if(mLocalHold && !conversation->shouldHold()) // mLocalHold is true.
.....+ unhold()
......+ mPendingRequest.mType = Unhold;
I have a try to insert tentative code into RemoteParticipant.cxx.
--------
RemoteParticipant::onNewSession(ServerInviteSessionHandle...
{
:
+ mLocalHold = false; // XXX to avoid unhold()
participantToReplace->replaceWithParticipant(this); // adjust conversation mappings
:
}
--------
--------
RemoteParticipant::onRefer(InviteSessionHandle...
{
:
+ participant->mLocalHold = false; // XXX to avoid unhold()
replaceWithParticipant(participant); // adjust conversation mappings - do this after buildSdpOffer, so that we have a bridge port
:
}
--------
Then, the SIP sequence has changed as follows.
A...B...C
:...:...:
|...|...| B execute rediretToParticipant(A,C)
|<R-|...| B send REFER(repleces) to A.
|-INV-->| A send INVITE(repleces) to C.
|<-200--| C respond 200OK(INVITE) to A.
But, I am suspecting that my tentative source code is impropriety.
=== 2nd problem ===
- After receiving INVITE with Replaces header,
my applications established a new session between A and C, nevertheless they became silent.
A...B...C
:...:...:
|...|...| B execute rediretToParticipant(A,C)
|<R-|...| B send REFER(repleces) to A.
|-INV-->| A send INVITE(repleces) to C.
|<-200--| C respond 200OK(INVITE) to A.
|-INV-->| A send re-INVITE to C.
|<-INV--| C send re-INVITE to A.
|-491-->| A respond 491 Request Pending to C.
|<-491--| C respond 491 Request Pending to A.
:...:...:
|-RTP-->|
|-RTP-->| RTP packets flowed only to one direction.
|-RTP-->|
:...:...:
Not only A but also C are silent.
I am thinking that RemoteParticipant::adjustRTPStreams() and RemoteParticipant::replaceWithParticipant() may be correlating with this problem.
But, I am puzzled.
Following is a part of the log of adjustRTPStreams and RemoteParticipant handles.
Could anyone help me?
A...B...C
|...|...|
|<=>|...| two party call between A and B.
:...:...:
|...|-->| B send initial INVITE to C.
DEBUG and INFO Logs in C:
RemoteParticipant.cxx:71 | RemoteParticipant created (UAS or forked leg), handle=14
RemoteParticipant.cxx:1786 | onNewSession(Server): handle=14
RemoteParticipant.cxx:1989 | onOffer: handle=14
:
Conversation.cxx:224 | Participant handle=14 added to conversation handle=5 (BridgePort=3)
BridgeMixer.cxx:37 | calculatingMixWeigthsForParticipant, handle=14, bridgePort=3
RemoteParticipant.cxx:565 | RemoteParticipant::unhold request: handle=14
RemoteParticipant.cxx:1466 | adjustRTPStreams: handle=14, found media line in local sdp, mediaType=2, transportType=3, numConnections=1, port=51010
RemoteParticipant.cxx:1698 | adjustRTPStreams: handle=14
RemoteParticipant.cxx:1746 | adjustRTPStreams: handle=14
RemoteParticipant.cxx:1756 | adjustRTPStreams: handle=14, receiving...
A...B...C
:...:...:
|...|<--| C respond 200OK(INVITE) to B
RemoteParticipant.cxx:1891 | onConnected: handle=14, SipResp: 200
RemoteParticipant.cxx:253 | RemoteParticipant::stateTransition of handle=14 to state=Connected
A...B...C
:...:...:
|...|...| B execute recon::ConversationManager::rediretToParticipant(A,C)
|<R-|...| B send REFER(repleces) to A.
|-INV-->| A send INVITE(repleces) to C.
DEBUG and INFO Logs in C:
RemoteParticipant.cxx:71 | RemoteParticipant created (UAS or forked leg), handle=16
RemoteParticipant.cxx:1786 | onNewSession(Server): handle=16
RemoteParticipant.cxx:1798 | onNewSession(Server): handle=16, to replace handle=14
:
Conversation.cxx:224 | Participant handle=14 added to conversation handle=5 (BridgePort=-1)//////// bridgePort=-1 is correct value ??
BridgeMixer.cxx:37 | calculatingMixWeigthsForParticipant, handle=14, bridgePort=-1 //////// bridgePort=-1 is correct value ??
RemoteParticipant.cxx:565 | RemoteParticipant::unhold request: handle=14
:
RemoteParticipant.cxx:253 | RemoteParticipant::stateTransition of handle=14 to state=Replacing
RemoteParticipant.cxx:1989 | onOffer: handle=14, SipReq:
:
RemoteParticipant.cxx:1466 | adjustRTPStreams: handle=14, found media line in local sdp, mediaType=2, transportType=3, numConnections=1, port=51012
RemoteParticipant.cxx:1698 | adjustRTPStreams: handle=14
RemoteParticipant.cxx:1746 | adjustRTPStreams: handle=14
RemoteParticipant.cxx:1756 | adjustRTPStreams: handle=14, receiving...
RemoteParticipant.cxx:253 | RemoteParticipant::stateTransition of handle=14 to state=Connecting
A...B...C
:...:...:
|<-200--| C respond 200OK(INVITE) to A.
DEBUG and INFO Logs in C:
RemoteParticipant.cxx:1891 | onConnected: handle=14, SipResp: 200
RemoteParticipant.cxx:253 | RemoteParticipant::stateTransition of handle=14 to state=Connected
RemoteParticipant.cxx:565 | RemoteParticipant::unhold request: handle=14
RemoteParticipantDialogSet.cxx:601 | setProposedSdp: handle=14, proposedSdp=v=0
RemoteParticipant.cxx:1466 | adjustRTPStreams: handle=14, found media line in local sdp, mediaType=2, transportType=3, numConnections=1, port=51012
RemoteParticipant.cxx:1631 | adjustRTPStreams: handle=14, mediaDirection=3, remoteIp=, remotePort=0
RemoteParticipant.cxx:1722 | adjustRTPStreams: handle=14, stop sending.
RemoteParticipant.cxx:1756 | adjustRTPStreams: handle=14, receiving...
RemoteParticipant.cxx:253 | RemoteParticipant::stateTransition of handle=14 to state=Unholding
A...B...C
:...:...:
|-INV-->| A send re-INVITE to C.
|<-INV--| C send re-INVITE to A.
|-491-->| A respond 491 Request Pending to C.
|<-491--| C respond 491 Request Pending to A.
:...:...:
|-RTP-->|
|-RTP-->| RTP packets flowed only to one direction.
|-RTP-->|
:...:...:
RemoteParticipant.cxx:1975 | onAnswer: handle=14, SipResp: 200
RemoteParticipant.cxx:1466 | adjustRTPStreams: handle=14, found media line in local sdp, mediaType=2, transportType=3, numConnections=1, port=51012
RemoteParticipant.cxx:1698 | adjustRTPStreams: handle=14
RemoteParticipant.cxx:1756 | adjustRTPStreams: handle=14, receiving...
RemoteParticipant.cxx:253 | RemoteParticipant::stateTransition of handle=14 to state=Connected
Regards,