At times, you may want to change the properties of a connection that has already been established. For example, you may want to "put a call on hold". In the context of SDP, "putting a call on hold" really means modifying the direction. However, one participant cannot unilaterally change the properties of the connection. They must send a new SDP offer to the remote participant, who must reply in turn with a new SDP answer. This process is known as SDP renegotiation.
Switching a Stream's Direction
The direction of a stream is what indicates whether it is one-way or two-way. There are four possible directions, which are provided by the
- SendReceive: This stream both sends and receives data.
- SendOnly: This stream only sends data.
- ReceiveOnly: This stream only receives data.
- Inactive: This stream does not send or receive any data.
In the scenario mentioned above, a normal call where both parties are talking would have audio and video streams that are
SendReceive. If one party wants to place the call on hold, the streams would be set to
Inactive. To change the direction of an active stream, you invoke the
ChangeDirection method of an
VideoStream instance. The following code shows how to change a two-way stream so that it is inactive.
Make sure that you only change the direction of audio and video streams. You cannot change the direction of a data stream. If you attempt to, then the IceLink SDK will raise an error and refuse to process the direction change.
Note that the initial configuration of the stream affects which directions that you can specify. For example, if you did not specify a
RemoteMedia instance when you initialized your streams, you can never change the direction to
SendReceive, because there is no remote media instance to receive from. Likewise, if you did not specify a
LocalCameraMedia instance, you can never change the direction to
SendReceive, because there is no local media instance to send with.
As mentioned in the introduction to this section, it is not enough to change the direction like this. You must also send a new offer to the remote party. The next section shows you how to accomplish this.
Performing Other Operations
Before you get into the details of actually performing the renegotiation, note that the only property that IceLink supports renegotiation for is for the direction of the streams. It may be possible to modify the SDP messages directly and perform a renegotiation, but this is not supported and will likely have unintended side effects.
Renegotiating With the WebSync Extension
If you are using the WebSync extension, there is an extension method that specifically handles this for you. To renegotiate the properties of a
Connection instance, invoke the
Renegotiate method of your
Client instance and pass in the connection object. You must specify the channel id for your session and you must do this after you make any changes to the properties of the connection.
The renegotiation is not instant, and returns a promise that resolves when the renegotiation is complete. You should always monitor this promise to ensure that the renegotiation was successful. If, for whatever reason, the new offer is not accepted by the remote party, then the connection will return to its previous state. The following examples show the use of the
If you make multiple renegotiation requests at the same time, they will be queued and processed in the order that they are received. This can cause unpredictable results if one or more of the requests are rejected by the remote party. For this reason, you should try to only perform one renegotiation at a time.
The above information covers what happens when a local party initiates a renegotiation, but it is equally possible that a remote party is the one who initiates. IceLink will automatically respond to the the renegotiation request, so there is no API call that you need to invoke. However, you may wish to be notified of this attempt, so that you can avoid sending a competing renegotiation offer. To do this, add an
OnSignallingChange event handler to your
Connection instance. This event is raised whenever the signalling state of a connection is changed. You can view the signalling state of a connection by accessing its
SignallingState property, of which there are four distinct values:
- New: no offer has been sent or received
- HasLocalOffer: a local offer has been sent but no remote answer has been received
- HasRemoteOffer: a remote offer has been received but no local answer has been sent
- Stable: the offer/answer exchange is complete
An example is shown below that demonstrates how to be notified when a new renegotiation request is received.
You can now successfully renegotiate the direction of the streams in a connection instance, which is useful for putting a session on hold and for other scenarios. If you need a refresher on how the WebSync extension works, return to the section on Connecting to the Signalling Server.