Esempio n. 1
0
        /// <summary>
        /// Start listening for associations.
        /// </summary>
        /// <returns>true on success, false on failure.</returns>
        public bool Start(IPAddress addr)
        {
            try
            {
                ListenAddress = addr;

                _assocParameters = new ServerAssociationParameters(AeTitle, new IPEndPoint(addr, ListenPort));

                // Load our presentation contexts from all the extensions
                CreatePresentationContexts();

                if (_assocParameters.GetPresentationContextIDs().Count == 0)
                {
                    Platform.Log(LogLevel.Fatal, "No configured presentation contexts for AE: {0}", AeTitle);
                    return(false);
                }

                return(DicomServer.StartListening(_assocParameters, StartAssociation));
            }
            catch (DicomException ex)
            {
                Platform.Log(LogLevel.Fatal, ex, "Unexpected exception when starting listener on port {0)", ListenPort);
                return(false);
            }
        }
Esempio n. 2
0
        public void OnReceiveRequestMessage(DicomServer server, ServerAssociationParameters association, byte presentationID, ClearCanvas.Dicom.DicomMessage message)
        {
            foreach (byte pcid in association.GetPresentationContextIDs())
            {
                DicomPresContext context = association.GetPresentationContext(pcid);
                if (context.Result == DicomPresContextResult.Accept)
                {
                    if (context.AbstractSyntax == SopClass.StudyRootQueryRetrieveInformationModelFind)
                    {
                        DicomMessage response = new DicomMessage();
                        response.DataSet[DicomTags.StudyInstanceUid].SetStringValue("1.2.3");
                        response.DataSet[DicomTags.PatientId].SetStringValue("1");
                        response.DataSet[DicomTags.PatientsName].SetStringValue("test");
                        response.DataSet[DicomTags.StudyId].SetStringValue("1");
                        response.DataSet[DicomTags.StudyDescription].SetStringValue("dummy");
                        server.SendCFindResponse(presentationID, message.MessageId, response, DicomStatuses.Pending);

                        DicomMessage finalResponse = new DicomMessage();
                        server.SendCFindResponse(presentationID, message.MessageId, finalResponse, DicomStatuses.Success);
                    }
                    else if (context.AbstractSyntax == SopClass.VerificationSopClass)
                    {
                        server.SendCEchoResponse(presentationID, message.MessageId, DicomStatuses.Success);
                    }
                }
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <remarks>
        /// The constructor creates a dictionary of each presentation context negotiated for the
        /// association, and the plugin that will handle it.  This is used later when incoming request
        /// messages are processed.
        /// </remarks>
        /// <param name="server">The server.</param>
        /// <param name="parameters">Association parameters for the negotiated association.</param>
        /// <param name="userParms">User parameters to be passed to the plugins called by the class.</param>
        /// <param name="verifier">Delegate to call to verify an association before its accepted.</param>
        /// <param name="complete">Delegate to call when the association is closed/complete.  Can be null.</param>
        public DicomScpHandler(DicomServer server, ServerAssociationParameters parameters, TContext userParms, DicomScp <TContext> .AssociationVerifyCallback verifier, DicomScp <TContext> .AssociationComplete complete)
        {
            _context  = userParms;
            _verifier = verifier;
            _complete = complete;

            var ep = new DicomScpExtensionPoint <TContext>();

            object[] scps = ep.CreateExtensions();

            // First set the user parms for each of the extensions before we do anything with them.
            foreach (object obj in scps)
            {
                var scp = obj as IDicomScp <TContext>;
                if (scp != null)
                {
                    scp.SetContext(_context);
                }
            }

            // Now, create a dictionary with the extension to be used for each presentation context.
            foreach (byte pcid in parameters.GetPresentationContextIDs())
            {
                if (parameters.GetPresentationContextResult(pcid) == DicomPresContextResult.Accept)
                {
                    SopClass       acceptedSop    = SopClass.GetSopClass(parameters.GetAbstractSyntax(pcid).UID);
                    TransferSyntax acceptedSyntax = parameters.GetAcceptedTransferSyntax(pcid);
                    foreach (object obj in scps)
                    {
                        var scp = obj as IDicomScp <TContext>;
                        if (scp == null)
                        {
                            continue;
                        }

                        IList <SupportedSop> sops = scp.GetSupportedSopClasses();
                        foreach (SupportedSop sop in sops)
                        {
                            if (sop.SopClass.Equals(acceptedSop))
                            {
                                if (sop.SyntaxList.Contains(acceptedSyntax))
                                {
                                    if (!_extensionList.ContainsKey(pcid))
                                    {
                                        _extensionList.Add(pcid, scp);
                                        break;
                                    }
                                    Platform.Log(LogLevel.Error, "SOP Class {0} supported by more than one extension", sop.SopClass.Name);
                                }
                            }
                        }
                    }
                }
            }

            _statsRecorder = new AssociationStatisticsRecorder(server);
        }
Esempio n. 4
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <remarks>
        /// The constructor creates a dictionary of each presentation context negotiated for the
        /// association, and the plugin that will handle it.  This is used later when incoming request
        /// messages are processed.
        /// </remarks>
        /// <param name="server">The server.</param>
        /// <param name="parameters">Association parameters for the negotiated association.</param>
        /// <param name="userParms">User parameters to be passed to the plugins called by the class.</param>
        /// <param name="verifier">Delegate to call to verify an association before its accepted.</param>
        /// <param name="complete">Delegate to call when the association is closed/complete.  Can be null.</param>
        public DicomScpHandler(DicomServer server, ServerAssociationParameters parameters, TContext userParms, DicomScp <TContext> .AssociationVerifyCallback verifier, DicomScp <TContext> .AssociationComplete complete)
        {
            _context  = userParms;
            _verifier = verifier;
            _complete = complete;

            List <IDicomScp <TContext> > scps =
                Platform.Instance.CompositionContainer.GetExportedValues <IDicomScp <TContext> >().Select(scp => scp).
                ToList();

            // First set the user parms for each of the extensions before we do anything with them.
            foreach (object obj in scps)
            {
                IDicomScp <TContext> scp = obj as IDicomScp <TContext>;
                scp.SetContext(_context);
            }

            // Now, create a dictionary with the extension to be used for each presentation context.
            foreach (byte pcid in parameters.GetPresentationContextIDs())
            {
                if (parameters.GetPresentationContextResult(pcid) == DicomPresContextResult.Accept)
                {
                    SopClass       acceptedSop    = SopClass.GetSopClass(parameters.GetAbstractSyntax(pcid).UID);
                    TransferSyntax acceptedSyntax = parameters.GetAcceptedTransferSyntax(pcid);
                    foreach (object obj in scps)
                    {
                        IDicomScp <TContext> scp = obj as IDicomScp <TContext>;

                        IList <SupportedSop> sops = scp.GetSupportedSopClasses();
                        foreach (SupportedSop sop in sops)
                        {
                            if (sop.SopClass.Equals(acceptedSop))
                            {
                                if (sop.SyntaxList.Contains(acceptedSyntax))
                                {
                                    if (!_extensionList.ContainsKey(pcid))
                                    {
                                        _extensionList.Add(pcid, scp);
                                        break;
                                    }
                                    else
                                    {
                                        LogAdapter.Logger.ErrorWithFormat("SOP Class {0} supported by more than one extension", sop.SopClass.Name);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Esempio n. 5
0
        void IDicomServerHandler.OnReceiveAssociateRequest(DicomServer server, ServerAssociationParameters association)
        {
            if (_verifier != null)
            {
                DicomRejectResult result;
                DicomRejectReason reason;
                bool verified = _verifier(_context, association, out result, out reason);
                if (verified == false)
                {
                    server.SendAssociateReject(result, DicomRejectSource.ServiceUser, reason);
                    LogAdapter.Logger.Info("Association rejected from {0} to {1}",
                                           association.CallingAE, association.CalledAE);
                    return;
                }
            }

            // Let the extensions have its say on whether a presentation context is really acceptable.
            //
            bool atLeastOneAccepted = false;

            foreach (byte pcid in association.GetPresentationContextIDs())
            {
                if (association.GetPresentationContextResult(pcid) == DicomPresContextResult.Accept)
                {
                    IDicomScp <TContext>   scp = _extensionList[pcid];
                    DicomPresContextResult res = scp.VerifyAssociation(association, pcid);
                    if (res != DicomPresContextResult.Accept)
                    {
                        association.GetPresentationContext(pcid).ClearTransfers();
                        association.SetPresentationContextResult(pcid, res);
                    }
                    else
                    {
                        atLeastOneAccepted = true;
                    }
                }
            }

            if (!atLeastOneAccepted)
            {
                LogAdapter.Logger.Info("None of the proposed presentation context is accepted. Rejecting association from {0} to {1}", association.CallingAE, association.CalledAE);
                server.SendAssociateReject(DicomRejectResult.Permanent, DicomRejectSource.ServiceUser, DicomRejectReason.NoReasonGiven);
                return;
            }

            server.SendAssociateAccept(association);

            // Optimization to speed query performance
            Task.Factory.StartNew(() => LogAdapter.Logger.Info("Received association:\r\n{0}", association.ToString()));
        }