Currently I use Janus with its (amazing) SIP plugin to bridge my PBX to WebRTC devices running my app. This works great, even over LTE connections. We use a coturn TURN server to relay RTP traffic.
Suppose that I want to “transfer” a WebRTC “call” to another WebRTC peer. I am not talking about a SIP transfer here, I am talking about a WebRTC “transfer”. I am aware of the fact that WebRTC does not implement such things by design; application and signalling layer have to be built by the developer.
Normally, in such a scenario, I would try to use ICE restart. I have tested this method without Janus (that is, two browsers calling each other, one browser “transfers” the call to another third browser using the ICE restart mechanism).
How would I approach such a scenario (WebRTC “transfers”) using the Janus SIP plugin. Is ICE restart a viable method? If so, how would that workout when Janus is the offerer (the PBX is being called)?
Maybe I am missing something completely, but I am stuck in the thought process. Any ideas on how to approach this particular scenario? Any help would be greatly appreciated.
Setting up the green line (1) is no problem; this works fine (Smarthpone A initiates the call, he is the SDP offerer). Now suppose that during the call, the far end (i.e., extension 6001) wants to be transferred to speak with Smartphone B (the blue dashed line (2)).
A logical approach would be to create a new PeerConnection (as you suggested) on Smartphone B (this can be signalled through my proprietary protocol). How should I “inform” Janus that the local description has changed from Smartphone A to Smartphone B? (This is what I mean by “transferring”).
When reading the docs, one option looks viable: the “update” command of the SIP plugin. However, I cannot get this working with a simple browser and the janus.js file… After an ICE restart, the ICE connection goes to disconnected.
Okay, maybe I have to rephrase the issue… I would like to focus on the ICE restart part, let’s forget about the “transfer” part.
The last few days I have been working on a working ICE transfer example. I have made a test setup where I use a browser to call a SIP extension using Janus and my PBX. I do not use trickle ICE and I have set the “iceTransportPolicy” set to relay (using my TURN server in the iceServers configuration of course). The call always works fine, I have bidirectional audio.
When I use the “iceRestart” parameter set to true when recreating my local SDP offer, I can see that the ufrag and pwd elements change, as well as the candidates (they have different port numbers). Then I use the SIP plugin’s “update” command to send my new offer in the JSEP, to force an ICE restart. In the Janus log, I see (as expected) “ICE restart detected”. I can see the re-invite to the PBX, the auto-accept… everything looks fine. I get the Janus “accepted” event with the new answer SDP.
However, when I set the new answer SDP using “setRemoteDescription()”, the following happens:
Within 2 to 3 seconds, I see in my browser console that the ICE connection state goes to disconnected.
I still have audio from the SIP extension to the browser for another 10 seconds or so, and then it completely stops.
I cannot seem to find the problem. Why does my ICE state change to disconnected when I perform an ICE restart with Janus? The initial call with the initial SDP always works. Could it be the PBX? Or have I made a mistake in understanding the “update” command?
Thanks again for your time; I appreciate your help!
You cannot use ICE to transfer a call somewhere else. DTLS will fail, as the new endpoint will try to set up a new DTLS handshake while the old one will assume the previous one will still apply.
I no longer want to transfer a call somewhere else using ICE restart (you have made it clear that it isn’t a suitable method), but I am now focussing on why ICE restart itself does not seem to work.
In the example I described in my previous post, I restarted ICE from the same browser I generated the intial SDP from. This should work, right? Suppose I use a mobile app to make a call and I transition from Wi-Fi to 4G/5G/LTE, then we would need ICE restart to restart the ICE connection. That is exactly what I am trying to simulate in my simple browser setup.
From the logs and the admin-endpoint, I cannot explain why my audio breaks in both directions. I do not see any errors or warnings. One thing I noticed is that when I use pc.createOffer() with iceRestart set to true, I do not see an onselectedcandidatepairchange event happening, although I expect that to happen. Could that be an indicator that something is wrong?
I am sorry for my elaborate text, but I feel that providing context is necessary here.
I have checked the admin endpoint to extract the “local” and “remote” SDPs, both after establishing the call and after ICE restarting it from the browser. It seems that the ice-ufrag and the ice-pwd change, as expected. Janus also correctly detects an ICE restart when reading the logs.