Enable an Endpoint

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.

To sign a local user in to Microsoft Office Communications Server, the client enables the endpoint that was previously created and configured. An enabled endpoint has established a security association with Office Communications Server and can begin to accept provisioning data and carry out collaboration with remote users. In addition to calling into the Enable method on the endpoint, the client must handle the events raised by the principal endpoint asynchronously after Enable is called.

The endpoint must be enabled before it is ready for use. Before enabling the endpoint, the client application must properly configure the server signaling settings to specify the underlying server, transport, authentication methods, and any required user credentials.

Enable an Endpoint

To discover available servers and sign in

  1. Using the IUccServerSignalingSettings instance obtained from the principal endpoint, call into the FindServer method. The FindServer method operates asynchronously. A collection of signaling server instances is returned in the OnFindServer event.

  2. Handle the OnFindServer event. You can get an instance of IEnumerator from the SignalingServers collection returned in the event data object. Using the IUccServerSignalingSettings interface obtained from the event source object, set the Server property to the first server in the returned server collection.

  3. Start the endpoint registration with the server by calling the Enable method on the IUccEndpoint instance.

    Tip

    You can use the event source object of the OnFindServer callback method.

  4. The endpoint remains unregistered until the client receives the notification of an OnEnable event with a succeeded status (StatusCode=0 and IsComplete=true).

    If the StatusCode is less than 0, the first server in the SignalingServers collection did not accept the registration request. Set a new value in the Server property of the IUccServerSignalingSettings instance obtained from the event source parameter of the OnEnable callback. The new value should be obtained from the next server in the SignalingServers collection returned in the OnFindServer callback. The server signaling settings object is now pointed to the next server in the pool of enterprise Office Communications Server instances. Call Enable on the endpoint and repeat step 4 until StatusCode is greater than or equal to zero. If the client has attempted to register with every server in the SignalingServers collection and all attempts result in a StatusCode less than zero, there are no available servers and sign in has failed.

For an example showing the registration of an endpoint with a server in Unified Communications Client API, see Create and Enable a Principal Endpoint Object.

OnEnable Event

The OnEnable event is raised by a principal endpoint asynchronously, after Enable is called. The event data parameter exposes properties used by a client to determine the success or failure of the sign-in process. A client’s OnEnable callback method should be designed to recover from a sign-in failure as well as continue provisioning the client in the event of sign-in success.

When Sign-In Succeeds

A StatusCode value greater than or equal to zero indicates sign-in success. At this point, the client and Office Communication Server have exchanged credentials and the client is authenticated. The enabled endpoint can now carry out the functional roles assigned to it. For information about endpoint roles, see Endpoint Object.

To access the functionality of the endpoint, a client obtains specific interfaces from the principal endpoint and advises for events raised by the interfaces. Using the endpoint derived interface IUccSubscriptionManager, a client should subscribe to the local user’s contact list and server configuration. In addition, a client should use the publication manager role of the endpoint to create a publication containing a local user’s status so that remote users can detect the presence of the local user. OnEnable is ideal for calling client application logic that initiates subscription and publication. For more information, see Publishing and Subscribing.

The following class fields are declared in the application class that handles the _IUccEndpointEvents dispinterface.

  internal IUccSubscriptionManager mySubscriptionMgr;
  internal IUccPublicationManager myPubManager;
  internal IUccSessionManager mySessionManager;
  internal IUccConferenceManager myConferenceMgr;
  internal IUccSessionManager mySessionManager;
  internal UccPlatform _platform;
  internal IUccEndpoint _endpoint;
  internal IUccEndpoint _telEndpoint;

The following example handles the OnEnable event and obtains the role-specific interfaces implemented by the principal endpoint.

void _IUccEndpointEvents.OnEnable(
    IUccEndpoint pEventSource,
    IUccOperationProgressEvent pEventData)
{
    try
    {
        if (pEventData.IsComplete )
        {
            if (pEventData.StatusCode >= 0)
            {
                // Sign in succeeded. Proceed with subscription and publication.

                // Get subscription manager role from endpoint.
                this.mySubscriptionMgr = pEventSource as IUccSubscriptionManager;

                // Get publication manager role from endpoint.
                this.myPubManager = pEventSource as IUccPublicationManager;

                // Advise publication manager instance of this class as endpoint sink.
                UCC_Advise<_IUccPublicationManagerEvents>(this.myPubManager, this);

                // Get Media Endpoint Settings object from active endpoint.
                IUccMediaEndpointSettings _mediaEndpointSettings = pEventSource as IUccMediaEndpointSettings;

                // Create a session manager object to handle session related functionality and events.
                this.mySessionManager = pEventSource as IUccSessionManager;

                // Advise session manager instance of this class as endpoint sink.
                UCC_Advise<_IUccSessionManagerEvents>(this.mySessionManager, this);

                // Get conference manager role from endpont.
                this._confManager = _endpoint as IUccConferenceManager;


                UCC_Advise<_IUccConferenceManagerSessionEvents>(
                    _confManagerSession,
                    this);

                //
                // The OnEnable callback is the best place to trigger application logic that creates self-subscriptions
                // for the local user's contact list and server configuration. The client should publish the user's presence
                // status at this time too.
                // 
                // Self-subscription requires many steps and is best handled by a helper method called from OnEnable.
                // Publication should be handled by a separate helper function called from OnEnable.
                // Both of these helper methods use the role specific interfaces obtained in OnEnable.
                 //


            }
            else
            {
               // Recover from failure to sign in.
            }

        }
        else
        {
            // Sign in failed. Make the endpoint null.
            pEventSource = null;
        }
    }
    catch (COMException ex)
    {
        throw ex;
    }
}

When Sign-In Fails

A client should attempt to recover from a sign-in failure by attempting to sign in to another Office Communications Server instance that is returned within the server collection in the OnFindServer event. If all servers are tried and the endpoint is not signed in, the local user should be given a chance to supply sign-in credentials again. With the new sign-in values, a client can renew the credential cache of the endpoint and attempt to sign in to the servers again. In the event the original credentials supplied were wrong and the local user has corrected the error, the second round of sign-in attempts succeeds. For information about finding servers in an enterprise server pool and working with the credential cache, see Configure Server Signaling Settings.

void _IUccEndpointEvents.OnEnable(
    IUccEndpoint pEventSource,
    IUccOperationProgressEvent pEventData)
{
    try
    {
        if (pEventData.IsComplete )
        {
            if (pEventData.StatusCode >= 0)
            {
                // Sign in succeeded. Proceed with publication and subscription.
            }
            else
            {

                //
                // Sign in failed.
                // The current server in the server collection returned with OnFindServers 
                // did not accept the endpoint registration (Enable). The next server in the collection
                // is tried.
                //

                // Initial Boolean flag for server found?
                bool nextAvailable = false;
                // Declare new instance of server signaling settings interface.
                IUccServerSignalingSettings serverSignalingSettings = null;

                // If OnFindServer returned collection of servers and IEnumerator for collection
                // is not null.
                if (this.servers != null)
                {
                    // Initialize server signaling settings by casting from endpoint instance.
                    serverSignalingSettings = this._endpoint as IUccServerSignalingSettings;

                    // Get the next server in the servers IEnumerator instance.
                    nextAvailable = this.servers.MoveNext();
                   
                }

                // If next server was found.
                if (nextAvailable)
                {
                    // Set found server as property value of server signaling settings and enable.
                    serverSignalingSettings.Server = this.servers.Current as IUccSignalingServer;
                    pEventSource.Enable(null);
                }
                else if (this.servers != null)
                {
                    // Last server in collection was attempted and failed.
                    if (MessageBox.Show("Sign in again? ", "Invalid Credentials", MessageBoxButtons.RetryCancel) == DialogResult.Retry)
                    {
                        // Ask user for credentials again.

                       //
                       // getCredentials is an application modal dialog that presents a user with three text boxes. The
                       // user is challenged for user name, password, and domain. The values entered are available as public
                       // string properties (UserName, Password, Domain). If the user enters all three values and closes the dialog using
                       // the OK button, the DialogResult returned is DialogResult.OK. Otherwise, the user has not chosen to 
                       // attempt to sign in again.
                       // 
                       // A custom client application can implement this functionality any way but with the single restriction that
                       // the method chosen must return the three string values.
                       //

                        getCredentials askForCreds = new getCredentials(); 
                        askForCreds.ShowDialog();

                       if (askForCreds.DialogResult == DialogResult.OK)
                       {
                                    

                            // Reset enumerator to top of collection.
                            this.servers.Reset();

                            // Get first server.
                            nextAvailable = this.servers.MoveNext();

                            // If a server was found.
                            if (nextAvailable)
                            {
                                // Set found server as property value of server signaling settings and enable.
                                serverSignalingSettings.Server = this.servers.Current as IUccSignalingServer;

                                        
                                //
                                // Update credential cache with new credentials. This involves:
                                //   Getting the existing credential for the realm.
                                //   Removing the credential.
                                //   Creating a new credential based on the new sign-in values supplied by the local user.
                                //   Setting the new credential as the active credential for the next Enable().
                                //

                                // Declare new credential to receive user name and password.
                                UccCredential thisCredential = null;

                                // Get existing credential based on realm.
                                if (serverSignalingSettings.CredentialCache.TryGetCredential("*", out thisCredential))
                                {

                                    // Remove the existing credential.
                                    serverSignalingSettings.CredentialCache.RemoveCredential("*");

                                    // Create a new credential with new user name and password.
                                    UccCredential newCredential = null;
                                    newCredential = serverSignalingSettings.CredentialCache.CreateCredential(
                                            askForCreds.UserName,
                                            askForCreds.Password,
                                            askForCreds.Domain);
                                                

                                    // Set the new credential into credential cache.
                                    serverSignalingSettings.CredentialCache.SetCredential("*", newCredential);

                                    // Enable the endpoint.
                                    pEventSource.Enable(null);
                                            
                                }

                            }
                        }
                        else
                        {
                            MessageBox.Show("Sign-in Failed");
                        }

                    }
                    else
                    {
                        MessageBox.Show("Sign-in Failed");
                    }
                }

            }

        }
        else
        {
            // Sign in failed. Make the endpoint null.
            pEventSource = null;
        }
    }
    catch (COMException ex)
    {
        throw ex;
    }
}

OnDisable Event

A local client signs out of Office Communications Server by calling the Disable method on the principal endpoint. To unadvise for endpoint and platform events, use the OnDisable event.

/// <summary>
/// Endpoint disable event handler unadvises for endpoint advisement,
/// de-references IUccEndpoint instance, shuts down platform
/// </summary>
/// <param name="pEventSource">disabled endpoint instance</param>
/// <param name="pEventData">operation progress event</param>
void _IUccEndpointEvents.OnDisable(
    IUccEndpoint pEventSource,
    IUccOperationProgressEvent pEventData
    )
{
    try
    {
       string eURI = pEventSource.Uri.Value;

       if (pEventData.IsComplete && pEventData.StatusCode >=0)
       {

            UCC_Unadvise<_IUccEndpointEvents>(pEventSource, this);

            if (this._telEndpoint != null)
            {
                UCC_Unadvise<_IUccEndpointEvents>(this._telEndpoint, this);
            }

            // Sign out completed.
            pEventSource = null;

            // Shut down the platform.
            if (this._platform != null)
            {
                this._platform.Shutdown(null);
                this._platformInitialized = false;
            }
        }
    }
    catch (COMException e)
    {
        MessageBox.Show(
           "On Endpoint Disable: COM Exception. " + 
            e.Message);
    }
}