LAUREL BRIDGE

LaurelBridge.DCF.Examples.VerificationSCP Namespace

DICOM Connectivity Framework V3.4
The VerificationSCP example demonstrates how to use DCF to implement a verification (DICOM echo) service class provider.
Classes

  ClassDescription
Public classProgram
Simple verification service class provider which should should be used with VerificationSCU.
Public classProgramCallbackVerificationServer
CallbackVerificationServer handles associations by creating a custom Verification SCP that extends VerificationSCP to handle the C-ECHO requests on the association.
Public classProgramExtendedVerificationServer
ExtendedVerificationServer handles associations by creating a custom Verification SCP that extends VerificationSCP to handle the C-ECHO requests on the association.
Examples

VerificationSCP Sample Code
public class Program
{
    /// <summary>
    /// Main entry point for VerificationSCP.
    /// </summary>
    [STAThread]
    public static void Main()
    {
        try
        {
            // Create a CallbackVerificationServer that listens for associations on port 104
            CallbackVerificationServer server104 = new CallbackVerificationServer(104);
            server104.BeginListening();
            Console.WriteLine("listening on {0}...", 104);

            // Create a CallbackVerificationServer that listens for associations on port 105.
            // only accept ELE or ILE for this server
            IList<AllowedPresentationContext> allowed = new List<AllowedPresentationContext>();
            allowed.Add(new AllowedPresentationContext(Uids.VerificationSOPClass,
                new[] { Uids.TransferSyntax.ExplicitVRLittleEndian, Uids.TransferSyntax.ImplicitVRLittleEndian }));
            CallbackVerificationServer server105 = new CallbackVerificationServer(105, allowed);
            server105.BeginListening();
            Console.WriteLine("listening on {0}...", 105);

            // Create an ExtendedVerificationServer that listens for associations on port 106
            ExtendedVerificationServer extendedVerificationServer = new ExtendedVerificationServer(106);
            extendedVerificationServer.BeginListening();
            Console.WriteLine("listening on {0}...", 106);
        }
        catch (Exception e)
        {
            Console.WriteLine("Exception caught during execution: {0}", e);
        }
    }

    /// <summary>
    /// CallbackVerificationServer handles associations by creating a custom Verification SCP that extends
    /// VerificationSCP to handle the C-ECHO requests on the association.
    /// </summary>
    public class CallbackVerificationServer : AssociationListenerAdapter, IAssociationConfigPolicyManager
    {
        readonly AssociationManager _manager;
        readonly IList<AllowedPresentationContext> _presentationContexts;

        /// <summary>
        /// Callback verification server constructor.
        /// </summary>
        /// <param name="port">server port</param>
        public CallbackVerificationServer(int port)
            : this(port, null)
        {
        }

        /// <summary>
        /// Callback verification server with allowed presentation contexts.
        /// </summary>
        /// <param name="port">server port</param>
        /// <param name="allowedPresentationContexts">allowed presentation context list</param>
        public CallbackVerificationServer(int port, IList<AllowedPresentationContext> allowedPresentationContexts)
        {
            _presentationContexts = allowedPresentationContexts;
            _manager = new AssociationManager();
            _manager.ServerTcpPort = port;
            _manager.AssociationConfigPolicyMgr = this;
            _manager.AddAssociationListener(this);
        }

        /// <summary>
        /// Return the session settings for the given association acceptor.
        /// </summary>
        /// <param name="assoc">The AssociationException</param>
        /// <returns>the session settings</returns>
        public DicomSessionSettings GetSessionSettings(AssociationAcceptor assoc)
        {
            return new DicomSessionSettings();
        }

        /// <summary>
        /// Start listening for associations via the AssociationManager.
        /// </summary>
        public void BeginListening()
        {
            Thread t = new Thread(_manager.Run);
            t.Start();
            if (!_manager.WaitForRunning(2000))
            {
                throw new TimeoutException("AssociationManager did not start in an acceptable amount of time");
            }
        }

        /// <summary>
        /// Stop the server.
        /// </summary>
        public void Stop()
        {
            _manager.Stop();
        }

        /// <summary>
        /// Call back for begin association.
        /// </summary>
        /// <param name="assoc">the AssociationAcceptor</param>
        public override void BeginAssociation(AssociationAcceptor assoc)
        {
            assoc.RegisterServiceClassProvider(new Dicom.Verification.VerificationSCP(assoc, _presentationContexts, CEcho));
        }

        /// <summary>
        /// Handler for CEcho.
        /// </summary>
        /// <param name="acceptor">The AssociationAcceptor</param>
        /// <param name="request">The C-Echo request message</param>
        /// <returns>The C-Echo response</returns>
        public CEchoResponse CEcho(AssociationAcceptor acceptor, CEchoRequest request)
        {
            CEchoResponse response = new CEchoResponse(request);
            Console.WriteLine("CallbackVerificationServer: cEcho request from {0} to port {1}",
                acceptor.AssociationInfo.CallingTitle, acceptor.AssociationInfo.CalledPresentationAddress);

            return response;
        }
    }

    /// <summary>
    /// ExtendedVerificationServer handles associations by creating a custom Verification SCP that extends VerificationSCP to handle the C-ECHO requests on the association.
    /// </summary>
    public class ExtendedVerificationServer : AssociationListenerAdapter, IAssociationConfigPolicyManager
    {
        private readonly AssociationManager _manager;
        private readonly IList<AllowedPresentationContext> _presentationContexts;

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="port">Server port</param>
        public ExtendedVerificationServer(int port)
            : this(port, null)
        {
        }

        /// <summary>
        /// Constructor with allowed presentation contexts.
        /// </summary>
        /// <param name="port">Server port</param>
        /// <param name="allowedPresentationContexts">list of allowed presentation contexts</param>
        public ExtendedVerificationServer(int port, IList<AllowedPresentationContext> allowedPresentationContexts)
        {
            _presentationContexts = allowedPresentationContexts;
            _manager = new AssociationManager();
            _manager.ServerTcpPort = port;
            _manager.AddAssociationListener(this);
        }

        /// <summary>
        /// Get the session settings for the AssociationAcceptor.
        /// </summary>
        /// <param name="assoc">the AssociationAcceptor</param>
        /// <returns>the session settings</returns>
        public DicomSessionSettings GetSessionSettings(AssociationAcceptor assoc)
        {
            return new DicomSessionSettings();
        }

        /// <summary>
        /// Start listening for associations via the AssociationManager.
        /// </summary>
        public void BeginListening()
        {
            Thread t = new Thread(_manager.Run);
            t.Start();
            if (!_manager.WaitForRunning(2000))
            {
                throw new TimeoutException("AssociationManager did not start in an acceptable amount of time");
            }
        }

        /// <summary>
        /// Stop receiving any new associations.
        /// </summary>
        public void Stop()
        {
            _manager.Stop();
        }

        /// <summary>
        /// Callback for beginning the association.
        /// </summary>
        /// <param name="assoc">the AssociationAcceptor</param>
        public override void BeginAssociation(AssociationAcceptor assoc)
        {
            assoc.RegisterServiceClassProvider(new MyVerificationScp(assoc, _presentationContexts));
        }
    }

    /// <summary>
    /// MyVerificationScp overrides the VerificationSCP's CEchoRq method, which is called anytime a C-ECHO request DIMSE message is received.
    /// </summary>
    class MyVerificationScp : Dicom.Verification.VerificationSCP
    {
        public MyVerificationScp(AssociationAcceptor acceptor, IList<AllowedPresentationContext> allowedPresentationContexts)
            : base(acceptor, allowedPresentationContexts, null)
        {
        }

        public override CEchoResponse CEchoRq(CEchoRequest request)
        {
            CEchoResponse response = new CEchoResponse(request);

            Console.WriteLine("MyVerificationScp: cEcho request from {0} to port {1}",
                Acceptor.AssociationInfo.CallingTitle, Acceptor.AssociationInfo.CalledPresentationAddress);

            return response;
        }
    }
}