Code Listing: Programming Endpoint Object in C#

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.

The following example is a class representing a server-based principal endpoint. There are four public methods, in addition to the class constructor:

  • Constructor. Create an IUccEndpoint instance and advise it of event handlers following _IUccEndpointEvents and _IUccServerSignalingSettingsEvents. The handlers are implemented as part of this C# class as well. For more information about event handling, see Code Listing: Handling Endpoint Events in C#.
  • SignIn. Configure the server signaling settings for a given user and start to log the user on to the server by enabling the underlying IUccEndpoint instance.
  • SignOut. Start to log off the user by disabling an enabled IUccEndpoint object.
  • AddProxyForRCC. Create and enable a proxy of the principal endpoint to control a phone device.
  • RemoveProxyForRCC. Remove the phone control by disabling the enabled proxy of the principal endpoint.
using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;
using Microsoft.Office.Interop.UccApi;

namespace UccApiComponents
{
    public partial class UccApiEndpoint : IDisposable, 
      _IUccEndpointEvents, 
      _IUccServerSignalingSettingsEvents  
    {
        IUccEndpoint _uccEndpointProxy = null;
        IUccEndpoint _uccEndpoint = null;
        IUccPlatform _uccPlatform = null;
        IUccServerSignalingSettings _uccSignalingSettings = null;
        bool _enabled = false;
        bool _disabled = false;
        bool _proxyEnabled = false;
        bool _proxyDisabled = false;

        string _userName, _password, _domain;
        UCC_TRANSPORT_MODE _transport;
        UCC_AUTHENTICATION_MODES _authModes;
        UccOperationContext _signInOpCtx;

        private void Dispose(Boolean disposing)
        {
            if (!this._disposed)
            {
                if (disposing)
                {
                    if (this._enabled)
                        SignOut(null);
                }
                this._disposed = true;
            }
        }


        public void Dispose()
        {
            this.Dispose(true);
            GC.SuppressFinalize(this);
        }

        #region Constructors

        // 3 overloads of UccApiEndpoint class constructor.
        // Each overload illustrates the ways an endpoint
        // can be initiated. Optional parameters include:
        //  endpointId: A string assigned by client to identify an endpoint
        //         ctx: A UCCP class encapsulating context pertaining
        //              to the enable operation.
        //
        public UccApiEndpoint(IUccPlatform uccPlatform, 
                              string sipUri, 
                              string endpointId, UccContext ctx)
        {
            Initialize(uccPlatform, sipUri, endpointId, ctx);
        }

        public UccApiEndpoint(IUccPlatform uccPlatform, string sipUri, string endpointId)
        {
            Initialize(uccPlatform, sipUri, endpointId, null);
        }

        public UccApiEndpoint(IUccPlatform uccPlatform, string sipUri)
        {
            Initialize(uccPlatform, sipUri, null, null);
        }
        #endregion Constructors


        void Initialize(IUccPlatform uccPlatform, string sipUri, string endpointId, UccContext ctx)
        {
            // Initialize class IUccPlatform. 
            this._uccPlatform = uccPlatform;

            // Create new instance of URI Manager class.
            UccUriManager uriMan = new UccUriManagerClass();

            // Convert passed SIP address string to Uri object.
            UccUri pUri = uriMan.ParseUri(sipUri);

            // Create server-based endpoint.
            // IMPORTANT: Endpoint exists but has not been registered with server.
            this._uccEndpoint = this._uccPlatform.CreateEndpoint(
                UCC_ENDPOINT_TYPE.UCCET_PRINCIPAL_SERVER_BASED,pUri, 
                endpointId, ctx);

            // Create COM connection point between event source and sink.
            this.AdviseForEvents<_IUccEndpointEvents>(
                this._uccEndpoint, this);

            // Get server signaling settings to set user credentials,
            //authentication modes, and Office Communications Server instance.
            this._uccSignalingSettings = this._uccEndpoint as IUccServerSignalingSettings;

        }


        #region Methods:


        // Two overloads of SignIn. First overload is used when calling
        // code does not have instance of IUccSignalingServer (Office Communications Server instance to 
        // sign in to). Second overload is used when IUccSignalingServer has
        // been obtained. 
        //
        public void SignIn(
                        string userName,
                        string password,
                        string domain,
                        string serverAddr,
                        UCC_TRANSPORT_MODE transport,
                        UCC_AUTHENTICATION_MODES authModes,
                        UccOperationContext opCtx)
        {
            if (serverAddr == null)
            {
                this._authModes = authModes;
                this._transport = transport;
                this._userName = userName;
                this._password = password;
                this._domain = domain;
                this._signInOpCtx = opCtx;

                string current_domain = null;

               // Create COM connection point between event source and sink.
               this.AdviseForEvents<_IUccServerSignalingSettingsEvents>(
                   this._uccSignalingSettings, this);

                this._uccSignalingSettings.FindServer(current_domain, opCtx);
                // SignIn(_userName, _password, _domain, pServer, _transport, _authModes, opCtx) 
                // will be called in OnFindServer event provided that valid pServer is returned.
            }
            else
            {
                IUccSignalingServer server = this._uccSignalingSettings.CreateSignalingServer(serverAddr, transport);
                SignIn(userName, password, domain, server, transport, authModes, opCtx);
            }
        }

        public void SignIn(
                        string userName,
                        string password,
                        string domain,
                        IUccSignalingServer signalingServer,
                        UCC_TRANSPORT_MODE transport,
                        UCC_AUTHENTICATION_MODES authModes,
                        UccOperationContext opCtx)
        {
            _enabled = false;
            _disabled = false;

            // Configure the server signaling settings before enabling the endpoint.
            this._uccSignalingSettings.AllowedAuthenticationModes = (int)authModes;

            UccCredential credential = null;
            if (userName == null || password == null || domain == null)
            {
                if (!this._uccSignalingSettings.CredentialCache.TryGetCredential("SIP Communications Service", out credential))
                        credential = this._uccSignalingSettings.CredentialCache.DefaultCredential; 
            }
            else
            {
                credential = this._uccSignalingSettings.CredentialCache.CreateCredential(userName, password, domain);
            }

            if (credential != null) 
                 this._uccSignalingSettings.CredentialCache.SetCredential("SIP Communications Service", credential);
            else 
                 throw new Exception("invalid credential");

            this._uccSignalingSettings.Server = signalingServer; 
            this._uccEndpoint.Enable(opCtx);
            // Must handle _IUccEndpointEvents.OnEnable events to determine if the call succeeds or not.
        }
        private void SignIn(IUccSignalingServer signalingServer)
        {
           this.SignIn( 
              this._userName, 
              this._password, 
              this._domain, 
              signalingServer,
              signalingServer.TransportMode,
              UCC_AUTHENTICATION_MODES.UCCAM_KERBEROS)
        }
        
        public void SignOut(UccOperationContext opContext)
        {
            if (_enabled)
            {
                _uccEndpoint.Disable(opContext);
                // Must handle _IUccEndpointEvents.OnDisable event 
                // to determine if the call succeeds or not.
            }
        }

        public void AddProxyForRCC(string proxySipUri, string proxyTelUri, UccContext ctx)
        {
            _proxyDisabled = false;
            _proxyEnabled = false;

            UccUriManager uriMan = new UccUriManager();
            UccUri pSipUri = uriMan.ParseUri(proxySipUri);
            this._uccEndpointProxy = this._uccPlatform.CreateProxyEndpoint(
                UCC_ENDPOINT_TYPE.UCCET_PROXY_TELEPHONY,
                this._uccEndpoint, 
                pSipUri, 
                proxyTelUri, 
                ctx);
            this.AdviseForEvents<_IUccEndpointEvents>(this._uccEndpointProxy, this);
            this._uccEndpointProxy.Enable(null);
        }

        public void RemoveProxyForRCC(UccOperationContext opCtx)
        {
            if (this._proxyEnabled)
            {
                this._uccEndpointProxy.Disable(opCtx);
            }
        }

        /// <summary>
        /// Creates connection point between event source and sink
        /// </summary>
        /// <typeparam name="T">Generic. dispinterface implemented by sink </typeparam>
        /// <param name="source">Object raising event</param>
        /// <param name="sink">Object handling event</param>
        public static void AdviseForEvents<T>(object source, T sink)
        {
            IConnectionPoint cp;
            try
            {
                IConnectionPointContainer container = (IConnectionPointContainer)source;
                Guid guid = typeof(T).GUID;
                container.FindConnectionPoint(ref guid, out cp);
                cp.Advise(sink, out cookie);

            }
            catch (Exception )
            {
            }

        }

        #endregion Methods

        #region properties

        public string Id { get { return _uccEndpoint.Id; } }
        public string SipUri { get { return this.Uri.Value; } }
        public UccUri Uri { get { return _uccEndpoint.Uri; } }
        public int MediaCapabilities { get { return _uccEndpoint.MediaCapabilities; } }
        public int SignalingCapabilities { get { return _uccEndpoint.SignalingCapabilities; } }

        public bool Enabled { get { return _enabled; } }
        public bool Disabled { get { return _disabled; } }

        public IUccPlatform UccPlatform { get { return _uccPlatform; } }
        public IUccEndpoint UccEndpoint { get { return _enabled ? _uccEndpoint : null; } }
        public IUccEndpoint UccEndpointProxy { get { return _enabled ? _uccEndpointProxy : null; } }

        #endregion properties.
        #region event handlers
       void _IUccEndpointEvents.OnDisable(
           IUccEndpoint pEventSource, 
           IUccOperationProgressEvent pEventData)
       {
       }
       void _IUccEndpointEvents.OnEnable(
           IUccEndpoint pEventSource, 
           IUccOperationProgressEvent pEventData)
       {
       } 
       void _IUccServerSignalingSettingsEvents.OnFindServer(
           IUccEndpoint pEventSource, 
           UccFindServerEvent pEventData)
       {
            IUccServerSignalingSettings serverSignalingSettings = pEventSource as IUccServerSignalingSettings;

            if (pEventData.IsComplete)
            {
                this.servers = pEventData.SignalingServers.GetEnumerator();

                // Initial Boolean flag for server found?
                bool nextAvailable = false;

                nextAvailable = this.servers.MoveNext();

                // If next server was found.
                if (nextAvailable)
                {
                   // Get first server in collection.
                   IUccSignalingServer ss = this.servers.Current as IUccSignalingServer;
                   this.SignIn(ss);
                }
            }
       }
        #endregion event handlers
    }


}

See Also

Concepts

Create a Principal Endpoint
Create and Enable a Proxy Endpoint
Code Listing: Handling Endpoint Events in C#