Share via


Holding and Transferring Sessions

This content is no longer actively maintained. It is provided as is, for anyone who may still be using these technologies, with no warranties or claims of accuracy with regard to the most recent product version or service release.

When a session is under way, a Unified Communications Client API application can perform many functions traditionally available to PSTN telephones on a PBX. You must cast the active IUccAudioVideoSession to the IUccSessionCallControl interface to expose methods providing such PBX-like functionality as:

  • Transferring a media session to another remote endpoint. If the session is an audio session, the remote endpoint can be a PSTN telephone such as a cell phone or a PSTN phone controlled by a proxy endpoint on a remote workstation running a Unified Communications Client API client. Audio/video sessions can be transferred to remote endpoints that have audio/video media capabilities. If an audio/video session is transferred to an audio only endpoint, such as a cell phone or UC-enabled phone on a workstation without a webcam, only the audio channel is supported.
    For example, using your custom client, you can transfer a remote participant on a cell phone to another user on a cell phone or a computer running your custom client.
  • Alternating between two individual audio/video or audio only sessions. By making a single method call, you can alternate between an active session and a held session. The first of the two sessions is taken off hold while the second session is placed on hold.

Note

The application session and instant messaging session cannot be controlled like a telephone session. Hold, unhold, transfer, alternate, and reconnect are not available for the application or instant messaging session types.

It is a good idea to cache locally originated and received sessions in a type such as a dictionary using the remote endpoint Uri as a dictionary key. When this is done, accessing individual sessions by Uri to perform a call control operation is easier. For an example of this, see Answer an Incoming Phone Call.

Such functionalities are supported by the IUccSessionCallControl interface. The features of the IUccSessionCallControl interface apply to PSTN audio sessions and IP-based audio/video sessions. However, only BlindTransfer can be applied to transferring a PSTN audio session. Consultative transfer is only applicable to computer-to-computer or computer-to-PSTN-phone calls.

A Unified Communications Client API application can obtain the IUccSessionCallControl interface by calling QueryInterface on an IUccSession object. If the application is written in .NET language such as C#, the interface is obtained by a cast from the IUccSession object.

Controlling an audio/video session involves the following tasks:

  • Place a audio/video or audio session on hold. Placing a session on hold is a matter of muting the audio device that is carrying the audio media feed. This operation does not require the IUccSessionCallControl interface. An example of placing a session on hold can be found in the following code examples.
  • Take an audio/video or audio session off hold. This requires a single active session. If another session is active, that session must first be placed on hold. The programming pattern for removing a session from hold is the same as for holding a session except the audio device is un-muted.
  • Hold one session and take another off hold. This task requires two IUccSession objects. The IUccSession representing the call to be taken off hold is cast to the IUccSessionCallControl, while the call to be placed on hold is passed as an IUccSession argument to the Alternate method.
  • Blind transfer an audio/video or audio session. A blind transfer requires a single active session. A computer-to-computer session transfer requires the target endpoint Uri formatted as a SIP Uri. To transfer an audio session to a PSTN phone, supply the transfer target telephone number formatted as an Uri.
  • Consultative transfer a session. This transfer requires that the local user create a second audio or audio/video session representing a remote endpoint to be consulted. A call to the ConsultativeTransfer method essentially swaps the local endpoint initiating a transfer for the remote endpoint being transferred. The effect is that the local endpoint is disconnected from the session leaving the two remote endpoints connected to each other.

Blind Transfer

The audio/video session represented by the IUccSession object is cast to the IUccSessionCallControl interface to expose the BlindTransfer method. Call the BlindTransfer method on the session and pass the transfer target Uri in the first parameter.

When the remote endpoint accepts the session, the local application receives OnTerminate for the session transferred to a remote endpoint. A Unified Communications Client API client receiving a blind transfer must handle the OnIncomingTransfer event to accept the transfer. A PSTN phone represented by a proxy endpoint on a remote client must handle the OnIncomingSession raised by the proxy endpoint object to accept the call. If the remote endpoint is a PSTN phone such as a cell phone, the phone rings. Accepting a session on a phone such as a cell phone amounts to answering the call. To learn about receiving a blind transfer from a remote user, see Providing Session Call Control.

public long  BlindTransfer(
    IUccSession session,
    string bstrDestinationUri,
    long lOperationId
    )
{
    long hr = S_OK;

    try
    {
        IUccSessionCallControl SessionCC = session as IUccSessionCallControl;
        UccOperationContext oc = new UccOperationContext();
        oc.Initialize((int)lOperationId, null);

        SessionCC.BlindTransfer(bstrDestinationUri, oc);

    }
    catch (Exception ex)
    {
        hr = HandleException(ex);
    }

    return hr;
}

Consultative Transfer

Consultative transfer allows user A to transfer user B to user C after asking user C to accept the transferred session. The consultative transfer programming pattern requires two IUccSession objects. The first session object represents the connection created when user A calls user B. The second session object is created when user B calls user C to consult. The pattern can be outlined as follows:

  • User A creates session 1 to call user B. For information about originating an audio/video session, see Make an Outgoing Phone Call.
  • User B accepts a call session from user A. For information about accepting a call, see Handling Session Invitations.
  • User B begins a consultative call to user C by placing session 1 (user A) on hold.
  • User B creates session 2 to call user C. User C accepts the call and verbally agrees to the transfer.
  • User B executes ConsultativeTransfer on the session 1 object.
  • User C receives the OnIncomingTransfer event and accepts the transfer. To learn about receiving a consultative transfer from a remote user, see Providing Session Call Control.
  • When user C accepts the transferred call, user B is removed as a participant from session 2. Session 1 (user A calls user B) is terminated and user B receives the OnTerminate event for session 1.

The following programming pattern represents the call to ConsultativeTransfer. The example application uses a wrapper function that accepts the two session objects. The first argument to the wrapper function is the held session between user A and user B (xfercall). The second argument is the active session between user B and user C (xferTarget). For an example of originating a phone call, see Make an Outgoing Phone Call. For a code example that demonstrates the programming pattern that user C follows, see Providing Session Call Control.

public long  Wrap_ConsultativeTransfer(
    IUccSession xferCall,
    IUccSession xferTarget, 
    long lOperationId
    )
{
    long hr = S_OK;

    try
    {
        IUccSessionCallControl xferCC = xferCall as IUccSessionCallControl;
        if (xferCC != null)
        {
            UccOperationContext oc = new UccOperationContext();
            oc.Initialize((int)lOperationId, null);

            xferCC.ConsultativeTransfer(xferTarget, pOperationContext);
        }
        else
            hr = -1

    }
    catch (Exception ex)
    {
        hr = -1;
    }

    return hr;
}

Hold or Un-hold an Audio Session

An audio session is placed on hold or taken off hold by muting or un-muting the audio device configured on a local computer. The following example accepts a Boolean flag indicating the muting action to be taken on an audio media device on a local computer. The example iterates on the collection of media devices exposed by the media device manager and sets the IsMuted property.

/// <summary>
/// returns boolean flag indicating client has enabled video send device
/// <param name="pHold">Boolean hold action</param>
/// <param name="pMediaDeviceManager">IUccMediaDeviceManager device manager exposes local collection of media devices</param>
/// </summary>
/// <returns>Boolean returnValue True if on hold, false if off hold</returns>
public Boolean HoldMedia(Boolean pHold, IUccMediaDeviceManager pMediaDeviceManager)
{
    Boolean returnValue = false;
    IUccCollection deviceCollection = pMediaDeviceManager.GetDevices(
        UCC_MEDIA_TYPES.UCCMT_AUDIO,
        UCC_MEDIA_DIRECTIONS.UCCMD_SEND | UCC_MEDIA_DIRECTIONS.UCCMD_RECEIVE);
    if (deviceCollection.Count > 0)
    {
        foreach (IUccMediaDevice md in deviceCollection)
        {
            if (md.MediaType == UCC_MEDIA_TYPES.UCCMT_AUDIO)
            {
                IUccAudioMediaDevice amd = md as IUccAudioMediaDevice;
                if (pHold == true)
                {
                    amd.IsMuted = true;
                }
                else
                {
                    amd.IsMuted = false;
                }
                returnValue = amd.IsMuted;
            }
        }
    }
    return returnValue;
}

Place One Call on Hold and Take Another Call off Hold

The example application implements a wrapper function called wrapAlternate, which accepts the two session objects to be alternated. The first wrapper method argument represents the call that is to be taken off hold. The second argument is the currently active telephone call. To perform the action, the held telephone call session must be cast to the IUccSessionCallControl interface. This interface exposes the method that provides the hold swapping functionality. The Alternate method accepts the currently active telephone call session as an argument and places the call on hold.

public long  wrapAlternate(
    IUccSession pHeldSession,         //session to take off hold
    IUccSession pActiveSession,  //session to put on hold
    long lOperationId)
{
    long hr = S_OK;
    
    try
    {
        //cast held session to session call control iface
        IUccSessionCallControl SessionCC = pHeldSession as IUccSessionCallControl;
        UccOperationContext oc = new UccOperationContext();
        oc.Initialize((int)lOperationId, null);

        //un-hold pHeldSession. Hold pActiveSession
        SessionCC.Alternate(pActiveSession, oc);

    }
    catch (Exception ex)
    {
        hr = HandleException(ex);
    }

    return hr;
}

See Also

Concepts

Create and Enable a Proxy Endpoint
Handling Session Invitations
Providing Session Call Control
Answer an Incoming Phone Call
Make an Outgoing Phone Call