Пример #1
0
        public void AddFindRequest_NullDicomRequest_ThrowsException()
        {
            // Arrange
            var mockProvider = new MockProvider();
            var dicomClient = new DicomClient<TestInfo>(mockProvider.GetSettingsProviderFake(), mockProvider.GetRequestAdapterFake());

            // Act + Assert
            Assert.That(() => dicomClient.AddFindRequest(null), Throws.InstanceOf<ArgumentNullException>());
        }
Пример #2
0
        public void AddMoveRequest_RequestAdapterIsCalled()
        {
            // Arrange
            var mockProvider = new MockProvider();
            var requestAdapter = mockProvider.GetRequestAdapterFake();
            var dicomClient = new DicomClient<TestInfo>(mockProvider.GetSettingsProviderFake(), requestAdapter);
            var dicomMoveRequest = Substitute.For<IDicomMoveRequest>();

            // Act
            dicomClient.AddMoveRequest(dicomMoveRequest);

            // Assert
            Assert.That(() => requestAdapter.Received(1).CreateMoveDicomRequest(dicomMoveRequest), Throws.Nothing);
        }
Пример #3
0
        public void AddFindRequest_RequestAdapterIsCalled()
        {
            // Arrange
            var mockProvider = new MockProvider();
            var fellowOakMockProvider = new FellowOakMockProvider();
            var requestAdapter = mockProvider.GetRequestAdapterFake();
            var dicomClient = new DicomClient<TestInfo>(mockProvider.GetSettingsProviderFake(), requestAdapter);
            var dicomFindRequest = new FellowOakDicomFindRequest<TestInfo>(mockProvider.GetDicomMappingFake(),fellowOakMockProvider.GetDicomTagAdapterFake(), mockProvider.GetDicomInfoBuilderFake(), mockProvider.GetGeneralizedInfoProviderFake(), fellowOakMockProvider.GetDicomSopClassUidProviderFake(), c=> {},mockProvider.GetDicomWhereCollectionFake());

            // Act
            dicomClient.AddFindRequest(dicomFindRequest);

            // Assert
            Assert.That(() => requestAdapter.Received(1).CreateFindDicomRequest(dicomFindRequest), Throws.Nothing);
        }
        public DicomCommandStatusType OnNSet
        (
            DicomClient Client,
            byte presentationID,
            int messageID,
            string affectedClass,
            string instance,
            DicomDataSet Request,
            DicomDataSet Response
        )
        {
            ClientSession          clientSession;
            NSetClientSessionProxy sessionProxy;
            DicomCommand           mppsCommand;

            if (!AddInsSession.IsLicenseValid())
            {
                Logger.Global.SystemMessage(LogType.Information, "Worklist license not valid.  Worklist set cannot be performed", Client.AETitle);
                return(DicomCommandStatusType.ProcessingFailure);
            }

            clientSession = new ClientSession(Client);
            sessionProxy  = new NSetClientSessionProxy(clientSession, presentationID, messageID, affectedClass, instance);

            if (null == DicomCommandFactory.GetInitializationService(typeof(MppsNSetCommand)))
            {
                DicomCommandFactory.RegisterCommandInitializationService(typeof(MppsNSetCommand),
                                                                         new MppsSetCommandInitializationService( ));
            }

            mppsCommand = DicomCommandFactory.GetInstance( ).CreateNSetCommand(sessionProxy, Request);

            _clientSession = clientSession;
            _sessionProxy  = sessionProxy;

            clientSession.NSetResponse += new EventHandler <NSetResponseEventArgs>(clientSession_NSetResponse);

            clientSession.ProcessNSetRequest(presentationID, messageID, affectedClass, instance, mppsCommand).WaitOne( );

            Response = _response;

            return(_status);
        }
Пример #5
0
        public DicomCommandStatusType OnFind
        (
            DicomClient client,
            byte presentationId,
            int messageId,
            string affectedClass,
            DicomCommandPriorityType priority,
            DicomDataSet request
        )
        {
            try
            {
                CFindClientSessionProxy sessionProxy;
                DicomCommand            command;


                _messageId      = messageId;
                _presentationId = presentationId;
                _clientSession  = new ClientSession(client);

                if (null == DicomCommandFactory.GetInitializationService(typeof(QueryCFindCommand)))
                {
                    DicomCommandFactory.RegisterCommandInitializationService(typeof(QueryCFindCommand),
                                                                             new FindCommandInitializationService( ));
                }

                sessionProxy = new CFindClientSessionProxy(_clientSession, presentationId, messageId, affectedClass);
                command      = DicomCommandFactory.GetInstance( ).CreateCFindCommand(sessionProxy, request);

                _clientSession.CFindResponse += new EventHandler <CFindResponseEventArgs> (clientSession_CFindResponse);

                _clientSession.ProcessCFindRequest(presentationId, messageId, affectedClass, priority, command).WaitOne( );;

                return(_status);
            }
            finally
            {
                if (null != request)
                {
                    request.Dispose( );
                }
            }
        }
Пример #6
0
        /// <summary>
        /// 发送DCM文件夹
        /// </summary>
        /// <param name="dcmDir"></param>
        /// <param name="ip"></param>
        /// <param name="port"></param>
        /// <param name="callingAe"></param>
        /// <param name="calledAe"></param>
        public static void SendDcmDir(string dcmDir, string ip, int port, string callingAe = "ZYPACS", string calledAe = "ZYPACS")
        {
            if (Directory.Exists(dcmDir))
            {
                DirectoryInfo dir    = new DirectoryInfo(dcmDir);
                var           files  = dir.GetFileSystemInfos();
                var           client = new DicomClient();


                foreach (var file in files)
                {
                    if (file.Attributes != FileAttributes.Directory && file.Attributes != FileAttributes.Device)
                    {
                        client.AddRequest(new DicomCStoreRequest(file.FullName));
                    }
                }
                client.Send(ip, port, false, callingAe, calledAe);
            }
        }
        // Keep around of a bit until things shake out
        public async static void Test()
        {
            var client = new DicomClient();

            client.AddRequest(new DicomCStoreRequest(@"D:\\dvl\\lifeImage\\Images\\Generated\\Studies\\200mb\\SERIES_1\\INS_1"));
            client.AddRequest(new DicomCStoreRequest(@"D:\\dvl\\lifeImage\\Images\\Generated\\Studies\\200mb\\SERIES_1\\INS_2"));
            //            await client.SendAsync("127.0.0.1", 12345, false, "SCU", "ANY-SCP");

            await client.SendAsync("localhost", 11112, false, "LITEDCMRECV", "DCMRECV");

            client.Release();

            client = new DicomClient();
            client.AddRequest(new DicomCStoreRequest(@"D:\\dvl\\lifeImage\\Images\\Generated\\Studies\\200mb\\SERIES_1\\INS_3"));
            client.AddRequest(new DicomCStoreRequest(@"D:\\dvl\\lifeImage\\Images\\Generated\\Studies\\200mb\\SERIES_1\\INS_4"));
            //            await client.SendAsync("127.0.0.1", 12345, false, "SCU", "ANY-SCP");

            await client.SendAsync("localhost", 11112, false, "LITEDCMRECV", "DCMRECV");
        }
Пример #8
0
 /// <summary>
 /// Called when received response message.  Sets the <see cref="Result"/> property as appropriate.
 /// </summary>
 /// <param name="client">The client.</param>
 /// <param name="association">The association.</param>
 /// <param name="presentationID">The presentation ID.</param>
 /// <param name="message">The message.</param>
 public override void OnReceiveResponseMessage(DicomClient client, ClientAssociationParameters association, byte presentationID, DicomMessage message)
 {
     if (message.Status.Status != DicomState.Success)
     {
         LogAdapter.Logger.Error("Failure status received in sending verification: {0}", message.Status.Description);
         _verificationResult = VerificationResult.Failed;
     }
     else if (_verificationResult == VerificationResult.Canceled)
     {
         LogAdapter.Logger.Info("Verification was canceled");
     }
     else
     {
         LogAdapter.Logger.Info("Success status received in sending verification!");
         _verificationResult = VerificationResult.Success;
     }
     client.SendReleaseRequest();
     StopRunningOperation();
 }
Пример #9
0
        /// <summary>
        /// Called when [network error].
        /// </summary>
        /// <param name="client">The client.</param>
        /// <param name="association">The association.</param>
        /// <param name="e">The e.  Note, e can be null in some instances.</param>
        public void OnNetworkError(DicomClient client, ClientAssociationParameters association, Exception e)
        {
            //TODO: right now this method gets called in timeout and abort situations.  Should add
            // the appropriate methods to the IDicomClientHandler to address this.

            //We don't want to blow away other failure descriptions (e.g. the OnDimseTimeout one).
            if (Status == ScuOperationStatus.Running)
            {
                FailureDescription = String.Format("Unexpected network error: {0}", e == null ? "Unknown" : e.Message);
            }

            if (client.State == DicomAssociationState.Sta13_AwaitingTransportConnectionClose)
            {
                //When this state is set and an error occurs, an appropriate message has already been logged in the client.
            }
            else
            {
                Platform.Log(LogLevel.Warn, FailureDescription);
            }

            //We don't want to blow away the OnDimseTimeout 'TimeoutExpired' status.
            ScuOperationStatus stopStatus = Status;

            if (stopStatus == ScuOperationStatus.Running)
            {
                stopStatus = ScuOperationStatus.NetworkError;
            }

            ResultStatus = DicomState.Failure;

            try
            {
                StopRunningOperation(stopStatus);
            }
            finally
            {
                if (NetworkError != null)
                {
                    EventsHelper.Fire(NetworkError, this, association);
                }
            }
        }
Пример #10
0
        /// <summary>
        /// Sends verification request to specified Remote Dicom Host.
        /// </summary>
        /// <param name="clientAETitle"></param>
        /// <param name="remoteAE"></param>
        /// <param name="remoteHost"></param>
        /// <param name="remotePort"></param>
        /// <returns></returns>
        public VerificationResult Verify(string clientAETitle, string remoteAE, string remoteHost, int remotePort)
        {
            if (_dicomClient == null)
            {
                // TODO: Dispose...
                _dicomClient = null;
            }

            Logger.LogInfo("Preparing to connect to AE {0} on host {1} on port {2} for verification.", remoteAE, remoteHost, remotePort);
            try
            {
                IPAddress addr = null;
                foreach (IPAddress dnsAddr in Dns.GetHostAddresses(remoteHost))
                {
                    if (dnsAddr.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                    {
                        addr = dnsAddr;
                        break;
                    }
                }
                if (addr == null)
                {
                    Logger.LogError("No Valid IP addresses for host {0}", remoteHost);
                    _verificationResult = VerificationResult.Failed;
                }
                else
                {
                    _assocParams = new ClientAssociationParameters(clientAETitle, remoteAE, new IPEndPoint(addr, remotePort));

                    SetPresentationContexts();

                    _verificationResult = VerificationResult.Failed;
                    _dicomClient        = DicomClient.Connect(_assocParams, this);
                    ProgressEvent.WaitOne();
                }
            }
            catch (Exception e)
            {
                Logger.LogErrorException(e, "Unexpected exception trying to connect to Remote AE {0} on host {1} on port {2}", remoteAE, remoteHost, remotePort);
            }
            return(_verificationResult);
        }
Пример #11
0
        /// <summary>
        /// Queries the server indicated in <see cref="Configuration"/>
        /// with the query parameters indicated in <see cref="Study"/>.
        /// Implements the DICOM C-FIND command at STUDY Level.
        /// </summary>
        /// <param name="configuration">Server and client configuration.</param>
        /// <param name="studyQuery">Parameters specifying the query.</param>
        public static List <Study> CFINDStudies(Configuration configuration, Study studyQuery)
        {
            var studyResponses = new List <Study>();
            // init find request
            DicomCFindRequest cfind = new DicomCFindRequest(DicomQueryRetrieveLevel.Study);

            foreach (QueryParameter studyParameter in studyQuery)
            {
                cfind.Dataset.Add(studyParameter.getTag(), studyParameter.value);
            }

            cfind.OnResponseReceived = (request, response) =>
            {
                if (response.HasDataset)
                {
                    studyResponses.Add(new Study(response.Dataset, studyQuery));
                }
                if (!response.HasDataset)
                {
                    Debug.gotNumberOfResults(studyResponses.Count);
                }
            };

            var client = new DicomClient();

            client.AddRequest(cfind);

            // prepare to receive data
            studyResponses = new List <Study>();

            // send query
            Debug.studyQuery(configuration, studyQuery);
            try
            {
                var _networkStream = new DesktopNetworkStream(configuration, true, true);
                client.Send(_networkStream, configuration.thisNodeAET, configuration.AET, 5000);
            }
            catch (Exception) { Debug.cantReachServer(); }

            // arrange results in table
            return(studyResponses);
        }
Пример #12
0
        public void DicomClientSend_TooManyPresentationContexts_YieldsInformativeException()
        {
            var port = Ports.GetNext();

            using (DicomServer.Create <DicomCEchoProvider>(port))
            {
                var client = new DicomClient();

                // this just illustrates the issue of too many presentation contexts, not real world application.
                var pcs =
                    DicomPresentationContext.GetScpRolePresentationContextsFromStorageUids(
                        DicomStorageCategory.None,
                        DicomTransferSyntax.ImplicitVRLittleEndian);

                client.AdditionalPresentationContexts.AddRange(pcs);

                var exception = Record.Exception(() => client.Send("localhost", port, false, "SCU", "SCP"));
                Assert.IsType <DicomNetworkException>(exception);
            }
        }
Пример #13
0
        public DicomCommandStatusType OnNAction(DicomClient client, byte presentationId, int messageID, string affectedClass, string instance, int action, DicomDataSet requestDS, DicomDataSet responseDS)
        {
            StorageCommitArgs args = new StorageCommitArgs
            {
                Client         = client,
                PresentationId = presentationId,
                MessageId      = messageID,
                AffectedClass  = affectedClass,
                Instance       = instance,
                Action         = action
            };

            args.RequestDS = new DicomDataSet();
            args.RequestDS.Copy(requestDS, null, null);

            result = AsyncHelper.Execute <StorageCommitArgs>(new Action <StorageCommitArgs>(HandleNReport), args);
            // responseDS = null;

            return(DicomCommandStatusType.Success);
        }
Пример #14
0
        private void btnSendDCM_Click(object sender, EventArgs e)
        {
            try
            {
                var client = new DicomClient();
                client.NegotiateAsyncOps();
                //for (int i = 0; i < 10; i++)
                //{
                //    client.AddRequest(new DicomCEchoRequest());
                //}

                //client.AddRequest(new DicomCStoreRequest(@"test1.dcm"));
                client.AddRequest(new DicomCStoreRequest(@"test1.dcm"));
                client.Send("127.0.0.1", 11123, false, "SCUTEST", "JPACSStoreSCP");
            }
            catch (Exception exp)
            {
                MessageBox.Show(exp.Message);
            }
        }
Пример #15
0
        /// <summary>
        /// Возвращает всех пациентов из Dicom Worklist
        /// </summary>
        /// <returns></returns>
        public IEnumerable <Patient> GetAllPatients()
        {
            Patient     patient = new Patient();
            var         cfind   = DicomCFindRequest.CreateWorklistQuery();
            DicomClient client  = new DicomClient();

            cfind.OnResponseReceived = (DicomCFindRequest rq, DicomCFindResponse rp) =>
            {
                for (int i = 0; i < rp.Dataset.Count(); i++)
                {
                    patient = GetPatientInformation(rp);
                    _patients.Add(patient);
                }
            };

            client.AddRequest(cfind);
            client.Send(_host, _port, _useTls, _callingAe, _calledAe);

            return(_patients);
        }
Пример #16
0
        public void OnReceiveAssociateAccept(DicomClient client, ClientAssociationParameters association)
        {
            Logger.LogInfo("Association Accepted:\r\n{0}", association.ToString());

            _fileListIndex = 0;

            bool ok = SendCStore(client, association);

            while (ok == false)
            {
                _fileListIndex++;
                if (_fileListIndex >= _fileList.Count)
                {
                    Logger.LogInfo("Completed sending C-STORE-RQ messages, releasing association.");
                    client.SendReleaseRequest();
                    return;
                }
                ok = SendCStore(client, association);
            }
        }
Пример #17
0
        public void OnReceiveAssociateAccept(DicomClient client, ClientAssociationParameters association)
        {
            if (_type == TestTypes.AssociationReject)
            {
                Assert.Fail("Unexpected negotiated association on reject test.");
            }
            else if (_type == TestTypes.SendMR)
            {
                DicomMessage msg = new DicomMessage();

                _test.SetupMR(msg.DataSet);
                byte id = association.FindAbstractSyntaxWithTransferSyntax(msg.SopClass, TransferSyntax.ExplicitVrLittleEndian);

                client.SendCStoreRequest(id, client.NextMessageID(), DicomPriority.Medium, msg);
            }
            else
            {
                Assert.Fail("Unexpected test type");
            }
        }
Пример #18
0
        public void OldDicomClientSend_StorePart10File_ShouldSucceed()
        {
            var port = Ports.GetNext();

            using (var server = DicomServer.Create <CStoreScp>(port))
            {
                server.Logger = _logger.IncludePrefix("CStoreScp");

                var file = DicomFile.Open(@".\Test Data\CT-MONO2-16-ankle");

                var client = new DicomClient
                {
                    Logger = _logger.IncludePrefix("DicomClient")
                };
                client.AddRequest(new DicomCStoreRequest(file));

                var exception = Record.Exception(() => client.Send("127.0.0.1", port, false, "SCU", "SCP"));
                Assert.Null(exception);
            }
        }
Пример #19
0
        /// <summary>
        ///     Blocks until the request is received so calling code doesn't have to deal with asynchrony (see the EventWaitHandle in TrySend).
        ///     Only the timeout is applied no Throtelling, the client is unreleased on return
        /// </summary>
        /// <param name="dicomRequest"></param>
        /// <param name="client"></param>
        #region SendRequest
        public void SendRequest(DicomClient client)
        {
            _listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Information, "Sending request to " + _dicomConfiguration.RemoteAetTitle + " at " + _dicomConfiguration.RemoteAetUri.Host + ":" + _dicomConfiguration.RemoteAetUri.Port));
            var t = new Task(() =>
            {
                try
                {
                    client.Send(_dicomConfiguration.RemoteAetUri.Host, _dicomConfiguration.RemoteAetUri.Port, false, _dicomConfiguration.LocalAetTitle, _dicomConfiguration.RemoteAetTitle);
                }
                catch (Exception ex)
                {
                    if (OnRequestException != null)
                    {
                        OnRequestException(ex);
                    }
                    throw new Exception("Error when attempting to send DICOM request: " + ex.Message, ex);
                }
            }
                             );

            //var canceller = new CancellationTokenSource();
            t.Start();
            //allow some extra time.
            var canceller = new CancellationTokenSource();

            t.Wait(_dicomConfiguration.TransferTimeOutInMilliseconds + 1000, canceller.Token);

            if (!t.IsCompleted)
            {
                if (OnRequestTimeout != null)
                {
                    OnRequestTimeout();
                }
                canceller.Cancel(true);
            }
            else
            if (OnRequestSucess != null)
            {
                OnRequestSucess();
            }
        }
Пример #20
0
        /// <summary>
        /// Trigger the Actor Instances of the given Actor Type.
        /// </summary>
        /// <param name="actorType">Destination Actor Type.</param>
        /// <param name="trigger">Trigger message.</param>
        /// <param name="awaitCompletion">Boolean indicating whether this a synchronous call or not.</param>
        /// <returns>Boolean indicating success or failure.</returns>
        public bool TriggerActorInstances(ActorTypeEnum actorType, BaseTrigger trigger, bool awaitCompletion)
        {
            bool triggerResult = false;

            // can only trigger an actor that is started
            if (_actorState == ActorStateEnum.ActorStarted)
            {
                triggerResult = true;

                ActorNameCollection activeDestinationActors = ActorConnectionCollection.IsEnabled(actorType);
                foreach (ActorName activeActorName in activeDestinationActors)
                {
                    if (trigger is Hl7Trigger)
                    {
                        Hl7Client hl7Client = GetHl7Client(activeActorName);
                        if (hl7Client != null)
                        {
                            if (hl7Client.TriggerClient(activeActorName, trigger, awaitCompletion) == false)
                            {
                                // set returned result - but continue with other triggers
                                triggerResult = false;
                            }
                        }
                    }
                    else
                    {
                        DicomClient dicomClient = GetDicomClient(activeActorName);
                        if (dicomClient != null)
                        {
                            if (dicomClient.TriggerClient(activeActorName, trigger, awaitCompletion) == false)
                            {
                                // set returned result - but continue with other triggers
                                triggerResult = false;
                            }
                        }
                    }
                }
            }

            return(triggerResult);
        }
Пример #21
0
        /// <summary>
        /// Called when a timeout occurs waiting for the next message, as specified by <see cref="AssociationParameters.ReadTimeout"/>.
        /// </summary>
        /// <param name="client">The client.</param>
        /// <param name="association">The association.</param>
        public override void OnDimseTimeout(DicomClient client, ClientAssociationParameters association)
        {
            Status             = ScuOperationStatus.TimeoutExpired;
            FailureDescription =
                String.Format("Timeout Expired ({0} seconds) for remote AE {1} when processing C-MOVE-RQ, aborting connection", association.ReadTimeout / 1000,
                              RemoteAE);
            Platform.Log(LogLevel.Error, FailureDescription);

            try
            {
                client.SendAssociateAbort(DicomAbortSource.ServiceUser, DicomAbortReason.NotSpecified);
            }
            catch (Exception ex)
            {
                Platform.Log(LogLevel.Error, ex, "Error aborting association");
            }

            Platform.Log(LogLevel.Warn, "Completed aborting connection (after DIMSE timeout) from {0} to {1}",
                         association.CallingAE, association.CalledAE);
            ProgressEvent.Set();
        }
Пример #22
0
        public void Send(String localAE, String remoteAE, String host, int port)
        {
            if (_dicomClient == null)
            {
                if (_fileList.Count == 0)
                {
                    Logger.LogInfo("Not sending, no files to send.");
                    return;
                }

                Logger.LogInfo("Preparing to connect to AE {0} on host {1} on port {2} and sending {3} images.", remoteAE, host, port, _fileList.Count);

                try
                {
                    IPAddress addr = null;
                    foreach (IPAddress dnsAddr in Dns.GetHostAddresses(host))
                    {
                        if (dnsAddr.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                        {
                            addr = dnsAddr;
                            break;
                        }
                    }
                    if (addr == null)
                    {
                        Logger.LogError("No Valid IP addresses for host {0}", host);
                        return;
                    }
                    _assocParams = new ClientAssociationParameters(localAE, remoteAE, new IPEndPoint(addr, port));

                    SetPresentationContexts();

                    _dicomClient = DicomClient.Connect(_assocParams, this);
                }
                catch (Exception e)
                {
                    Logger.LogErrorException(e, "Unexpected exception trying to connect to Remote AE {0} on host {1} on port {2}", remoteAE, host, port);
                }
            }
        }
Пример #23
0
        public DicomCommandStatusType OnNCreate
        (
            DicomClient client,
            byte presentationID,
            int messageID,
            string affectedClass,
            string instance,
            DicomDataSet Request,
            DicomDataSet Response
        )
        {
            ClientSession             clientSession;
            NCreateClientSessionProxy sessionProxy;
            DicomCommand mediaCreateCommand;



            clientSession = new ClientSession(client);
            sessionProxy  = new NCreateClientSessionProxy(clientSession, presentationID, messageID, affectedClass, instance);

            mediaCreateCommand = DicomCommandFactory.GetInstance( ).CreateNCreateCommand(sessionProxy, Request);

            _clientSession = clientSession;
            _sessionProxy  = sessionProxy;

            clientSession.NCreateResponse += new EventHandler <NCreateResponseEventArgs>(clientSession_NCreateResponse);

            clientSession.ProcessNCreateRequest(presentationID, messageID, affectedClass, instance, mediaCreateCommand).WaitOne( );


            //TODO: use the new interface to update the instance parameter
            if (null != _status)
            {
                return(_status.Status);
            }
            else
            {
                return(DicomCommandStatusType.Failure);
            }
        }
Пример #24
0
        public DicomCommandStatusType OnFind
        (
            DicomClient Client,
            byte PresentationId,
            int MessageId,
            string AffectedClass,
            DicomCommandPriorityType Priority,
            DicomDataSet Request
        )
        {
            ClientSession           clientSession;
            CFindClientSessionProxy sessionProxy;
            DicomCommand            mwlCommand;

            if (!AddInsSession.IsLicenseValid())
            {
                Logger.Global.SystemMessage(LogType.Information, "Worklist license not valid.  Worklist search cannot be performed", Client.AETitle);
                return(DicomCommandStatusType.ProcessingFailure);
            }

            clientSession = new ClientSession(Client);
            sessionProxy  = new CFindClientSessionProxy(clientSession, PresentationId, MessageId, AffectedClass);

            if (null == DicomCommandFactory.GetInitializationService(typeof(MWLCFindCommand)))
            {
                DicomCommandFactory.RegisterCommandInitializationService(typeof(MWLCFindCommand),
                                                                         new MWLCommandInitializationService( ));
            }

            mwlCommand = DicomCommandFactory.GetInstance( ).CreateCFindCommand(sessionProxy, Request);

            _clientSession = clientSession;
            _sessionProxy  = sessionProxy;

            clientSession.CFindResponse += new EventHandler <Leadtools.Dicom.Scp.CFindResponseEventArgs> (clientSession_CFindResponse);

            clientSession.ProcessCFindRequest(PresentationId, MessageId, AffectedClass, Priority, mwlCommand).WaitOne( );

            return(_status);
        }
Пример #25
0
        public void OnReceiveResponseMessage(DicomClient client, ClientAssociationParameters association, byte presentationID, DicomMessage message)
        {
            if (message.Status.Status != DicomState.Success)
            {
                Logger.LogError("Failure status received in sending C-STORE: {0}", message.Status.Description);
            }

            bool ok = false;

            while (ok == false)
            {
                _fileListIndex++;
                if (_fileListIndex >= _fileList.Count)
                {
                    Logger.LogInfo("Completed sending C-STORE-RQ messages, releasing association.");
                    client.SendReleaseRequest();
                    return;
                }

                ok = SendCStore(client, association);
            }
        }
Пример #26
0
        public async Task SearchStudyAsync()
        {
            var client = new DicomClient();

            client.NegotiateAsyncOps();

            // Find a list of Studies.
            var request = CreateStudyRequest(new QueryConditionModel());

            var studies = new List <DicomDataset>();

            request.OnResponseReceived += (req, response) =>
            {
                DebugStudyResponse(response);
                if (response.Status == DicomStatus.Pending)
                {
                    _studies.OnNext(StudyViewHelper.CreateFrom(response.Dataset));
                }
            };
            client.AddRequest(request);
            await client.SendAsync(_pacsNode.Host, _pacsNode.Port, false, LocalAET, _pacsNode.AET);
        }
Пример #27
0
        public IEnumerable <string> SearchSeriesOfStudy(string studyUID)
        {
            var client = new DicomClient();

            client.NegotiateAsyncOps();

            List <string> result  = new List <string>();
            var           request = CreateSeriesRequestByStudyUID(studyUID);

            request.OnResponseReceived += (req, response) =>
            {
                if (response.Status == DicomStatus.Pending)
                {
                    result.Add(response.Dataset.GetString(DicomTag.SeriesInstanceUID));
                }
            };
            client.AddRequest(request);

            client.Send(_pacsNode.Host, _pacsNode.Port, false, LocalAET, _pacsNode.AET);

            return(result);
        }
Пример #28
0
        public DicomCommandStatusType OnNAction
        (
            DicomClient client,
            byte presentationId,
            int messageID,
            string affectedClass,
            string instance,
            int action,
            DicomDataSet request,
            DicomDataSet response
        )
        {
            ClientSession clientSession;
            INActionClientSessionProxy sessionProxy;
            DicomCommand mediaActionCommand;


            clientSession = new ClientSession(client);
            sessionProxy  = new NActionClientSessionProxy(clientSession, presentationId, messageID, affectedClass, instance, action, response);

            //by default this will return a strategy which switch between the actual Action command based on the Action Type
            mediaActionCommand = DicomCommandFactory.GetInstance( ).CreateNActionCommand(sessionProxy, request);

#if DEBUG
            if (mediaActionCommand is MediaCreationNActionCommandStrategy)
            {
                System.Diagnostics.Trace.WriteLine((( MediaCreationNActionCommandStrategy )mediaActionCommand).StrategyCommand.ToString( ));
            }
#endif

            _clientSession = clientSession;
            _sessionProxy  = sessionProxy;

            clientSession.NActionResponse += new EventHandler <NActionResponseEventArgs> (clientSession_NActionResponse);

            clientSession.ProcessNActionRequest(presentationId, messageID, affectedClass, instance, action, mediaActionCommand).WaitOne( );

            return(_status);
        }
Пример #29
0
        /// <summary>
        /// Send CGet to Get Target Frame
        /// </summary>
        /// <param name="SOPInstanceUID">the SOPInstanceUID Where Frame in</param>
        /// <param name="FrameIndex"> the FrameIndex Where Frame in</param>
        /// <returns></returns>
        internal async Task SaveTargetFramesAsyn(String SOPInstanceUID, int FrameIndex)
        {
            client = new DicomClient();
            var cGetRequest = CreateCGetRquest_FramesByList(SOPInstanceUID, FrameIndex);

            cGetRequest.Dataset.AddOrUpdate(new DicomTag(0x8, 0x5), "ISO_IR 100");
            cGetRequest.Dataset.AddOrUpdate(new DicomSequence(DicomTag.PerFrameFunctionalGroupsSequence));
            var FrameExtractionSequence = new DicomSequence(DicomTag.FrameExtractionSequence);

            cGetRequest.Dataset.AddOrUpdate(DicomTag.SOPInstanceUID, SOPInstanceUID);

            cGetRequest.Dataset.AddOrUpdate(DicomTag.QueryRetrieveLevel, DicomQueryRetrieveLevel.NotApplicable);

            var pcs = DicomPresentationContext.GetScpRolePresentationContextsFromStorageUids(
                DicomStorageCategory.Image,
                DicomTransferSyntax.ExplicitVRLittleEndian,
                DicomTransferSyntax.ImplicitVRLittleEndian,
                DicomTransferSyntax.ImplicitVRBigEndian,
                DicomTransferSyntax.JPEGLSLossless,
                DicomTransferSyntax.JPEG2000Lossless,
                DicomTransferSyntax.JPEGProcess14SV1,
                DicomTransferSyntax.JPEGProcess14,
                DicomTransferSyntax.RLELossless,
                DicomTransferSyntax.JPEGLSNearLossless,
                DicomTransferSyntax.JPEG2000Lossy,
                DicomTransferSyntax.JPEGProcess1,
                DicomTransferSyntax.JPEGProcess2_4
                );

            client.AdditionalPresentationContexts.AddRange(pcs);
            client.OnCStoreRequest += (DicomCStoreRequest req) =>
            {
                SaveImage(req.Dataset);

                return(new DicomCStoreResponse(req, DicomStatus.Success));
            };
            client.AddRequest(cGetRequest);
            client.Send(QRServerHost, QRServerPort, false, AET, QRServerAET);
        }
Пример #30
0
        /// <summary>
        /// Called when [dimse timeout].
        /// </summary>
        /// <param name="client">The client.</param>
        /// <param name="association">The association.</param>
        public virtual void OnDimseTimeout(DicomClient client, ClientAssociationParameters association)
        {
            Status             = ScuOperationStatus.TimeoutExpired;
            ResultStatus       = DicomState.Failure;
            FailureDescription = String.Format("Timeout Expired for remote host {0}, aborting connection", RemoteAE);
            if (LogInformation)
            {
                LogAdapter.Logger.Info(FailureDescription);
            }

            try
            {
                client.SendAssociateAbort(DicomAbortSource.ServiceUser, DicomAbortReason.NotSpecified);
            }
            catch (Exception ex)
            {
                LogAdapter.Logger.TraceException(ex);
            }

            LogAdapter.Logger.WarnWithFormat("Completed aborting connection (after DIMSE timeout) from {0} to {1}", association.CallingAE, association.CalledAE);
            ProgressEvent.Set();
        }
Пример #31
0
        /// <summary>
        /// Add the given DicomClient using the Destination Actor Configuration.
        /// </summary>
        /// <param name="dicomClientType">Dicom Client Type.</param>
        /// <param name="toActorType">To Actor Type.</param>
        /// <param name="commonConfig">Common Configuration.</param>
        /// <param name="peerToPeerConfigCollection">Peer to Peer Configuration collection.</param>
        protected void AddDicomClient(DicomClientTypeEnum dicomClientType, ActorTypeEnum toActorType, CommonConfig commonConfig, BasePeerToPeerConfigCollection peerToPeerConfigCollection)
        {
            foreach (BasePeerToPeerConfig basePeerToPeerConfig in peerToPeerConfigCollection)
            {
                if ((basePeerToPeerConfig is DicomPeerToPeerConfig) &&
                    (basePeerToPeerConfig.FromActorName.TypeId == _actorName.TypeId) &&
                    (basePeerToPeerConfig.ToActorName.Type == toActorType))
                {
                    DicomClient dicomClient = ClientServerFactory.CreateDicomClient(dicomClientType, this, basePeerToPeerConfig.ToActorName);
                    if (dicomClient != null)
                    {
                        dicomClient.ApplyConfig(commonConfig, (DicomPeerToPeerConfig)basePeerToPeerConfig);
                        SubscribeEvent(dicomClient);
                        _dicomClients.Add(dicomClient.ActorName.TypeId, dicomClient);

                        // Initialize the connection with the to actor as being active.
                        // - this can always be overruled by the application later.
                        SetActorDefaultConnectionActive(basePeerToPeerConfig.ToActorName);
                    }
                }
            }
        }
Пример #32
0
        private void MoveStudies(RetriveEntity RetriveFrom, DicomCMoveRequest cmoveRequest)
        {
            //Try to open Local SCP for CStore Support for comming files
            if (_scuStore == null)
            {
                _scuStore = new DicomServer <CStoreSCU>(_MoverSettings.LocalPort);
            }
            DicomClient clt = new DicomClient();

            cmoveRequest.OnResponseReceived = (request, response) =>
            {
            };
            // Add request to Dicom Client Object.
            clt.AddRequest(cmoveRequest);

            string Host, CalledAE;
            int    Port;

            GetEntityInfo(RetriveFrom, out Host, out Port, out CalledAE);
            clt.Send(Host, Port, false, _MoverSettings.Store_AE_Name, CalledAE);
            autoEvent.WaitOne();
        }
Пример #33
0
        private static DicomClient CreateDicomStoreClient(string fileToTransmit)
        {
            var client = new DicomClient();

            //request for DICOM store operation
            var dicomCStoreRequest = new DicomCStoreRequest(fileToTransmit);

            //attach an event handler when remote peer responds to store request
            dicomCStoreRequest.OnResponseReceived += OnStoreResponseReceivedFromRemoteHost;
            client.AddRequest(dicomCStoreRequest);

            //Add a handler to be notified of any association rejections
            client.AssociationRejected += OnAssociationRejected;

            //Add a handler to be notified of any association information on successful connections
            client.AssociationAccepted += OnAssociationAccepted;

            //Add a handler to be notified when association is successfully released - this can be triggered by the remote peer as well
            client.AssociationReleased += OnAssociationReleased;

            return(client);
        }
Пример #34
0
		/// <summary>
		/// Called when received associate accept.  For StorageScu, we then attempt to send the first file.
		/// </summary>
		/// <param name="client">The client.</param>
		/// <param name="association">The association.</param>
		public override void OnReceiveAssociateAccept(DicomClient client, ClientAssociationParameters association)
		{
			base.OnReceiveAssociateAccept(client, association);

			Platform.Log(LogLevel.Info, "Association Accepted:\r\n{0}", association.ToString());

			byte pcid = association.FindAbstractSyntaxWithTransferSyntax(SopClass.StorageCommitmentPushModelSopClass,
			                                                             TransferSyntax.ExplicitVrLittleEndian);
			if (pcid == 0)
				pcid = association.FindAbstractSyntaxWithTransferSyntax(SopClass.StorageCommitmentPushModelSopClass,
				                                                        TransferSyntax.ImplicitVrLittleEndian);
			if (pcid == 0)
			{
				client.SendAssociateAbort(DicomAbortSource.ServiceUser, DicomAbortReason.NotSpecified);
				return;
			}

			DicomMessage msg = new DicomMessage();

			msg.RequestedSopInstanceUid = "1.2.840.10008.1.20.1.1";
			msg.ActionTypeId = 1;
			msg.DataSet[DicomTags.TransactionUid].SetStringValue(DicomUid.GenerateUid().UID);

			foreach (StorageInstance instance in StorageInstanceList)
			{
				DicomSequenceItem item = new DicomSequenceItem();

				msg.DataSet[DicomTags.ReferencedSopSequence].AddSequenceItem(item);

				item[DicomTags.ReferencedSopClassUid].SetStringValue(instance.SopClass.Uid);
				item[DicomTags.ReferencedSopInstanceUid].SetStringValue(instance.SopInstanceUid);
			}


		}
Пример #35
0
        private void SendCreateFilmBoxRequest(DicomClient client, ClientAssociationParameters association, DicomMessage responseMessage)
        {

            ReferencedInstanceSequenceIod referencedFilmSessionSequence = new ReferencedInstanceSequenceIod();
            referencedFilmSessionSequence.ReferencedSopClassUid = SopClass.BasicFilmSessionSopClassUid;
            referencedFilmSessionSequence.ReferencedSopInstanceUid = responseMessage.AffectedSopInstanceUid;
            _basicFilmBoxModuleIod.ReferencedFilmSessionSequenceList.Add(referencedFilmSessionSequence);

            DicomMessage newRequestMessage = new DicomMessage(null, (DicomAttributeCollection)_basicFilmBoxModuleIod.DicomAttributeProvider);

            byte pcid = association.FindAbstractSyntaxOrThrowException(SopClass.BasicGrayscalePrintManagementMetaSopClass);

            _nextRequestType = RequestType.ImageBox;
            client.SendNCreateRequest(DicomUid.GenerateUid(), pcid, client.NextMessageID(), newRequestMessage, DicomUids.BasicFilmBoxSOP);
        }
Пример #36
0
        private void SendSetImageBoxRequest(DicomClient client, ClientAssociationParameters association)
        {
            if (_currentImageBoxIndex >= _imageBoxPixelModuleIods.Count)
            {
                // done sending images box - send print request
                _nextRequestType = RequestType.PrintAction;
                SendActionPrintRequest(client, association);
            }
            else
            {
                // want to get first film box response - although not sure if CC is using .net 3.5.. prolly not so do it old way
                IEnumerator<DicomAttributeCollection> filmBoxResponseEnumerator = _filmBoxResponseMessages.Values.GetEnumerator();
                filmBoxResponseEnumerator.Reset();
                filmBoxResponseEnumerator.MoveNext();

                BasicFilmBoxModuleIod basicFilmBoxModuleIod = new BasicFilmBoxModuleIod(filmBoxResponseEnumerator.Current);

                if (_currentImageBoxIndex > basicFilmBoxModuleIod.ReferencedImageBoxSequenceList.Count)
                {
                    throw new DicomException("Current Image Box Index is greater than number of Referenced ImageBox Sequences - set image box data");
                }

                ImageBoxPixelModuleIod imageBoxPixelModuleIod = _imageBoxPixelModuleIods[_currentImageBoxIndex];

                DicomMessage newRequestMessage = new DicomMessage(null, (DicomAttributeCollection)imageBoxPixelModuleIod.DicomAttributeProvider);
                newRequestMessage.RequestedSopClassUid = SopClass.BasicGrayscaleImageBoxSopClassUid;
                newRequestMessage.RequestedSopInstanceUid = basicFilmBoxModuleIod.ReferencedImageBoxSequenceList[_currentImageBoxIndex].ReferencedSopInstanceUid;

                byte pcid = association.FindAbstractSyntax(SopClass.BasicGrayscalePrintManagementMetaSopClass);

                _currentImageBoxIndex++;
                client.SendNSetRequest(pcid, client.NextMessageID(), newRequestMessage);
            }

        }
Пример #37
0
		/// <summary>
		/// Called when received response message.  Sets the <see cref="Result"/> property as appropriate.
		/// </summary>
		/// <param name="client">The client.</param>
		/// <param name="association">The association.</param>
		/// <param name="presentationID">The presentation ID.</param>
		/// <param name="message">The message.</param>
		public override void OnReceiveResponseMessage(DicomClient client, ClientAssociationParameters association, byte presentationID, DicomMessage message)
		{
			if (message.Status.Status != DicomState.Success)
			{
				Platform.Log(LogLevel.Error, "Failure status received in sending verification: {0}", message.Status.Description);
				_verificationResult = VerificationResult.Failed;
			}
			else if (_verificationResult == VerificationResult.Canceled)
			{
				Platform.Log(LogLevel.Info, "Verification was canceled");
			}
			else
			{
				Platform.Log(LogLevel.Info, "Success status received in sending verification!");
				_verificationResult = VerificationResult.Success;
			}
			client.SendReleaseRequest();
			StopRunningOperation();
		}
Пример #38
0
		/// <summary>
		/// Called when a timeout occurs waiting for the next message, as specified by <see cref="AssociationParameters.ReadTimeout"/>.
		/// </summary>
		/// <param name="client">The client.</param>
		/// <param name="association">The association.</param>
		public override void OnDimseTimeout(DicomClient client, ClientAssociationParameters association)
		{
			Status = ScuOperationStatus.TimeoutExpired;
			FailureDescription =
				String.Format("Timeout Expired ({0} seconds) for remote host {1} when processing C-MOVE-RQ, aborting connection", association.ReadTimeout/1000,
				              RemoteAE);
			Platform.Log(LogLevel.Error, FailureDescription);

			try
			{
				client.SendAssociateAbort(DicomAbortSource.ServiceUser, DicomAbortReason.NotSpecified);
			}
			catch (Exception ex)
			{
				Platform.Log(LogLevel.Error, ex, "Error aborting association");
			}

			Platform.Log(LogLevel.Warn, "Completed aborting connection (after DIMSE timeout) from {0} to {1}",
			             association.CallingAE, association.CalledAE);
			ProgressEvent.Set();
		}
Пример #39
0
        private void SendCreateFilmSessionRequest(DicomClient client, ClientAssociationParameters association)
        {
            DicomMessage newRequestMessage = new DicomMessage(null, (DicomAttributeCollection)_basicFilmSessionModuleIod.DicomAttributeProvider);

            byte pcid = association.FindAbstractSyntaxOrThrowException(SopClass.BasicGrayscalePrintManagementMetaSopClass);
            _nextRequestType = RequestType.FilmBox;
            client.SendNCreateRequest(DicomUid.GenerateUid(), pcid, client.NextMessageID(), newRequestMessage, DicomUids.BasicFilmSession);
        }
Пример #40
0
        /// <summary>
        /// Called when received associate accept.  
        /// </summary>
        /// <param name="client">The client.</param>
        /// <param name="association">The association.</param>
        public override void OnReceiveAssociateAccept(DicomClient client, ClientAssociationParameters association)
        {
            base.OnReceiveAssociateAccept(client, association);

            SendMoveRequest(client, association);
        }
Пример #41
0
        /// <summary>
        /// Called when received response message. 
        /// </summary>
        /// <param name="client">The client.</param>
        /// <param name="association">The association.</param>
        /// <param name="presentationID">The presentation ID.</param>
        /// <param name="message">The message.</param>
		public override void OnReceiveResponseMessage(DicomClient client, ClientAssociationParameters association, byte presentationID, DicomMessage message)
        {
			// Discovered issue with an SCP that was not setting these values on the final Success return, so blocking an update of the values if all of them are 0.
			if (message.NumberOfFailedSubOperations != 0 
				|| message.NumberOfCompletedSubOperations != 0
				|| message.NumberOfRemainingSubOperations != 0
				|| message.NumberOfWarningSubOperations != 0)
        	{
        		_failureSubOperations = message.NumberOfFailedSubOperations;
        		_successSubOperations = message.NumberOfCompletedSubOperations;
        		_remainingSubOperations = message.NumberOfRemainingSubOperations;
        		_warningSubOperations = message.NumberOfWarningSubOperations;
        		_totalSubOperations = _failureSubOperations + _successSubOperations + _remainingSubOperations +
        		                      _warningSubOperations;
        	}

        	if (message.Status.Status == DicomState.Pending)
        	{
        		OnImageMoveCompleted();
        	}
        	else
        	{
				DicomState status = message.Status.Status;
				if (message.Status.Status != DicomState.Success)
				{
					if (status == DicomState.Cancel)
					{
						if (LogInformation) Platform.Log(LogLevel.Info, "Cancel status received in Move Scu: {0}", message.Status);
						Status = ScuOperationStatus.Canceled;
					}
					else if (status == DicomState.Failure)
					{
						string msg = String.Format("Failure status received in Move Scu: {0}", message.Status);
						Platform.Log(LogLevel.Error, msg);
						Status = ScuOperationStatus.Failed;
						FailureDescription = msg;
					}
					else if (status == DicomState.Warning)
					{
						Platform.Log(LogLevel.Warn, "Warning status received in Move Scu: {0}", message.Status);
					}
					else if (Status == ScuOperationStatus.Canceled)
					{
						if (LogInformation) Platform.Log(LogLevel.Info, "Client cancelled Move Scu operation.");
					}
				}
				else
				{
					if (LogInformation) Platform.Log(LogLevel.Info, "Success status received in Move Scu!");
				}

				client.SendReleaseRequest();
				StopRunningOperation();
			}
        }
Пример #42
0
        /// <summary>
        /// Sends the move request (called after the association is accepted).
        /// </summary>
        /// <param name="client">The client.</param>
        /// <param name="association">The association.</param>
        private void SendMoveRequest(DicomClient client, ClientAssociationParameters association)
        {
            byte pcid = association.FindAbstractSyntaxOrThrowException(MoveSopClass);

            DicomMessage dicomMessage = new DicomMessage();
            foreach (DicomAttribute dicomAttribute in _dicomAttributeCollection)
            {
                // Need to do it this way in case the attribute is blank
                DicomAttribute dicomAttribute2 = dicomMessage.DataSet[dicomAttribute.Tag];
                if (dicomAttribute.Values != null)
                    dicomAttribute2.Values = dicomAttribute.Values;
            }

            client.SendCMoveRequest(pcid, client.NextMessageID(), _destinationAe, dicomMessage);
        }
Пример #43
0
		/// <summary>
		/// Called when received response message.  If there are more files to send, will send them here.
		/// </summary>
		/// <param name="client">The client.</param>
		/// <param name="association">The association.</param>
		/// <param name="presentationID">The presentation ID.</param>
		/// <param name="message">The message.</param>
		public override void OnReceiveResponseMessage(DicomClient client, ClientAssociationParameters association, byte presentationID, DicomMessage message)
		{
            if (_storageInstanceList.Count > 0)
            {
                _storageInstanceList[_fileListIndex].SendStatus = message.Status;
                _storageInstanceList[_fileListIndex].ExtendedFailureDescription = message.ErrorComment;
            }

		    if (message.Status.Status != DicomState.Success)
			{
				if (message.Status.Status == DicomState.Warning)
				{
					_warningSubOperations++;
					Platform.Log(LogLevel.Warn, "Warning status received in sending C-STORE to {0}: {1}",
								 association.CalledAE, message.Status.Description);
				}
				else if (message.Status.Status == DicomState.Failure)
				{
					_failureSubOperations++;
					Platform.Log(LogLevel.Error, "Failure status received in sending C-STORE to {0}: {1}",
						association.CalledAE, message.Status.Description);
				}
			}
			else
				_successSubOperations++;

			_remainingSubOperations--;

			OnImageStoreCompleted(_storageInstanceList[_fileListIndex]);

			if (Status == ScuOperationStatus.Canceled || message.Status.Status == DicomState.Cancel)
			{
				FailRemaining(DicomStatuses.Cancel);
				Platform.Log(LogLevel.Info, "Cancel requested by {0}, releasing association from {1} to {2}",
					(message.Status.Status == DicomState.Cancel) ? "remote host" : "client", 
					association.CallingAE, association.CalledAE);

				Status = ScuOperationStatus.Canceled;
				client.SendReleaseRequest();
				StopRunningOperation();
				return;
			}

			_fileListIndex++;
			if (_fileListIndex >= _storageInstanceList.Count)
			{
				Platform.Log(LogLevel.Info, "Completed sending {0} C-STORE-RQ messages, releasing association.", _storageInstanceList.Count);
				client.SendReleaseRequest();
				StopRunningOperation();
				return;
			}
		    SendCStoreUntilSuccess(client, association);
		}
Пример #44
0
		/// <summary>
		/// Called when received associate accept.  For StorageScu, we then attempt to send the first file.
		/// </summary>
		/// <param name="client">The client.</param>
		/// <param name="association">The association.</param>
		public override void OnReceiveAssociateAccept(DicomClient client, ClientAssociationParameters association)
		{
			base.OnReceiveAssociateAccept(client, association);

			Platform.Log(LogLevel.Info, "Association Accepted:\r\n{0}", association.ToString());

			_fileListIndex = 0;

			SendCStoreUntilSuccess(client,association);
		}
Пример #45
0
		/// <summary>
		/// Called when received response message.  If there are more files to send, will send them here.
		/// </summary>
		/// <param name="client">The client.</param>
		/// <param name="association">The association.</param>
		/// <param name="presentationID">The presentation ID.</param>
		/// <param name="message">The message.</param>
		public override void OnReceiveResponseMessage(DicomClient client, ClientAssociationParameters association, byte presentationID, DicomMessage message)
		{
			if (Status == ScuOperationStatus.Canceled)
			{
				Platform.Log(LogLevel.Info, "Cancel request received, releasing association from {0} to {1}", association.CallingAE, association.CalledAE);
				client.SendReleaseRequest();
				StopRunningOperation();
				return;
			}
		}
Пример #46
0
		/// <summary>
		/// Generic routine to send the next C-ECHO-RQ message.
		/// </summary>
		/// <param name="client">DICOM Client class</param>
		/// <param name="association">Association Parameters</param>
		private void SendVerificationRequest(DicomClient client, ClientAssociationParameters association)
		{
			byte pcid = association.FindAbstractSyntax(SopClass.VerificationSopClass);

			client.SendCEchoRequest(pcid, client.NextMessageID());
		}
Пример #47
0
		/// <summary>
		/// Called when [receive request message].
		/// </summary>
		/// <param name="client">The client.</param>
		/// <param name="association">The association.</param>
		/// <param name="presentationID">The presentation ID.</param>
		/// <param name="message">The message.</param>
		public override void OnReceiveRequestMessage(DicomClient client, ClientAssociationParameters association, byte presentationID, DicomMessage message)
		{
			if (message.CommandField == DicomCommandField.NEventReportRequest)
			{
				Platform.Log(LogLevel.Info, "N-EVENT-REPORT-RQ messages currently not supported by StorageCommitScu.  Aborting connection.");
				client.SendAssociateAbort(DicomAbortSource.ServiceUser, DicomAbortReason.NotSpecified);
				StopRunningOperation(ScuOperationStatus.UnexpectedMessage);
				throw new Exception("The method or operation is not implemented.");
			}
			else
			{
				Platform.Log(LogLevel.Info, "Unexpected OnReceiveRequestMessage callback on client.");
				try
				{
					client.SendAssociateAbort(DicomAbortSource.ServiceUser, DicomAbortReason.NotSpecified);
				}
				catch (Exception ex)
				{
					Platform.Log(LogLevel.Error, ex, "Error aborting association");
				}
				StopRunningOperation(ScuOperationStatus.UnexpectedMessage);
				throw new Exception("The method or operation is not implemented.");
			}
		}
Пример #48
0
 /// <summary>
 /// Sends the find request.
 /// </summary>
 /// <param name="client">The client.</param>
 /// <param name="association">The association.</param>
 private static void SendRequest(DicomClient client, ClientAssociationParameters association)
 {
     DicomMessage newRequestMessage = new DicomMessage();
     PrinterModuleIod.SetCommonTags(newRequestMessage.DataSet);
     byte pcid = association.FindAbstractSyntax(SopClass.PrinterSopClass);
     if (pcid > 0)
     {
         client.SendNGetRequest(DicomUids.PrinterSOPInstance, pcid, client.NextMessageID(), newRequestMessage);
     }
 }
Пример #49
0
		/// <summary>
		/// Generic routine to send the next C-STORE-RQ message in the <see cref="StorageInstanceList"/>.
		/// </summary>
		/// <param name="client">DICOM Client class</param>
		/// <param name="association">Association Parameters</param>
		private bool SendCStore(DicomClient client, ClientAssociationParameters association)
		{
			StorageInstance fileToSend = _storageInstanceList[_fileListIndex];

			OnImageStoreStarted(fileToSend);

			DicomFile dicomFile;

			try
			{
				// Check to see if image does not exist or is corrupted
				if (fileToSend.SendStatus == DicomStatuses.ProcessingFailure)
				{
					_failureSubOperations++;
					_remainingSubOperations--;
					OnImageStoreCompleted(fileToSend);
					return false;
				}

				dicomFile = fileToSend.LoadFile();
			}
			catch (DicomException e)
			{
				Platform.Log(LogLevel.Error, e, "Unexpected exception when loading DICOM file {0}", fileToSend.Filename);

				fileToSend.ExtendedFailureDescription = e.GetType().Name + " " + e.Message;
				_failureSubOperations++;
				_remainingSubOperations--;
				OnImageStoreCompleted(fileToSend);
				return false;
			}

			DicomMessage msg = new DicomMessage(dicomFile);

			byte pcid = 0;

			if (fileToSend.TransferSyntax.Encapsulated)
			{
				pcid = association.FindAbstractSyntaxWithTransferSyntax(fileToSend.SopClass, fileToSend.TransferSyntax);

				if (DicomCodecRegistry.GetCodec(fileToSend.TransferSyntax) != null)
				{
					if (pcid == 0)
						pcid = association.FindAbstractSyntaxWithTransferSyntax(fileToSend.SopClass,
						                                                        TransferSyntax.ExplicitVrLittleEndian);
					if (pcid == 0)
						pcid = association.FindAbstractSyntaxWithTransferSyntax(fileToSend.SopClass,
						                                                        TransferSyntax.ImplicitVrLittleEndian);
				}
			}
			else
			{
				if (pcid == 0)
					pcid = association.FindAbstractSyntaxWithTransferSyntax(fileToSend.SopClass,
					                                                        TransferSyntax.ExplicitVrLittleEndian);
				if (pcid == 0)
					pcid = association.FindAbstractSyntaxWithTransferSyntax(fileToSend.SopClass,
					                                                        TransferSyntax.ImplicitVrLittleEndian);
			}

			if (pcid == 0)
			{
				fileToSend.SendStatus = DicomStatuses.SOPClassNotSupported;
				fileToSend.ExtendedFailureDescription = "No valid presentation contexts for file.";
				OnImageStoreCompleted(fileToSend);
				_failureSubOperations++;
				_remainingSubOperations--;
				return false;
			}

			try
			{
				if (_moveOriginatorAe == null)
					client.SendCStoreRequest(pcid, client.NextMessageID(), DicomPriority.Medium, msg);
				else
					client.SendCStoreRequest(pcid, client.NextMessageID(), DicomPriority.Medium, _moveOriginatorAe,
					                         _moveOriginatorMessageId, msg);
			}
			catch(DicomNetworkException)
			{
				throw; //This is a DicomException-derived class that we want to throw.
			}
			catch(DicomCodecException e)
			{
				Platform.Log(LogLevel.Error, e, "Unexpected exception when compressing or decompressing file before send {0}", fileToSend.Filename);

				fileToSend.SendStatus = DicomStatuses.ProcessingFailure;
				fileToSend.ExtendedFailureDescription = "Error decompressing or compressing file before send.";
				OnImageStoreCompleted(fileToSend);
				_failureSubOperations++;
				_remainingSubOperations--;
				return false;

			}
			catch(DicomException e)
			{
				Platform.Log(LogLevel.Error, e, "Unexpected exception while sending file {0}", fileToSend.Filename);

				fileToSend.SendStatus = DicomStatuses.ProcessingFailure;
				fileToSend.ExtendedFailureDescription = "Unexpected exception while sending file.";
				OnImageStoreCompleted(fileToSend);
				_failureSubOperations++;
				_remainingSubOperations--;
				return false;
			}

			return true;
		}
Пример #50
0
 /// <summary>
 /// Called when received response message.
 /// </summary>
 /// <param name="client">The client.</param>
 /// <param name="association">The association.</param>
 /// <param name="presentationID">The presentation ID.</param>
 /// <param name="message">The message.</param>
 public override void OnReceiveResponseMessage(DicomClient client, ClientAssociationParameters association, byte presentationID, DicomMessage message)
 {
     base.ResultStatus = message.Status.Status;
     if (message.Status.Status == DicomState.Success)
     {
         this._results = message.DataSet;
     }
     base.ReleaseConnection(client);
 }
Пример #51
0
		/// <summary>
		/// Generic routine to send the next C-STORE-RQ message in the <see cref="StorageInstanceList"/>.
		/// </summary>
		/// <param name="client">DICOM Client class</param>
		/// <param name="association">Association Parameters</param>
		private bool SendCStore(DicomClient client, ClientAssociationParameters association)
		{
			StorageInstance fileToSend = _storageInstanceList[_fileListIndex];

			OnImageStoreStarted(fileToSend);

			DicomFile dicomFile;

			try
			{
				// Check to see if image does not exist or is corrupted
				if (fileToSend.SendStatus == DicomStatuses.ProcessingFailure)
				{
					_failureSubOperations++;
					_remainingSubOperations--;
					OnImageStoreCompleted(fileToSend);
					return false;
				}

				dicomFile = fileToSend.LoadFile();
			}
			catch (DicomException e)
			{
				Platform.Log(LogLevel.Error, e, "Unexpected exception when loading DICOM file {0}", fileToSend.Filename);

				fileToSend.ExtendedFailureDescription = e.GetType().Name + " " + e.Message;
				_failureSubOperations++;
				_remainingSubOperations--;
				OnImageStoreCompleted(fileToSend);
				return false;
			}

		    try
            {
                DicomMessage msg;

                byte pcid = SelectPresentationContext(association, fileToSend, dicomFile, out msg);

                if (pcid == 0)
                {
                    fileToSend.SendStatus = DicomStatuses.SOPClassNotSupported;
                    fileToSend.ExtendedFailureDescription = string.Format(SR.ErrorSendSopClassNotSupported, msg.SopClass);

                    LogError(fileToSend, msg, DicomStatuses.SOPClassNotSupported);

                    _failureSubOperations++;
                    _remainingSubOperations--;
                    OnImageStoreCompleted(fileToSend);
                    return false;
                }

                try
                {
                    SendOnPresentationContext(client, association, pcid, fileToSend, msg);
                }
                catch (DicomCodecUnsupportedSopException e)
                {
                    if (!msg.TransferSyntax.Encapsulated)
                    {
                        pcid = SelectUncompressedPresentationContext(association, msg);
                        if (pcid != 0)
                        {
                            SendOnPresentationContext(client, association, pcid, fileToSend, msg);
                            Platform.Log(LogLevel.Warn, "Could not send SOP as compressed, sent as uncompressed: {0}, file: {1}", e.Message, fileToSend.SopInstanceUid);
                            return true;
                        }
                    }

                    throw;
                }
            }
            catch (DicomNetworkException)
            {
                throw; //This is a DicomException-derived class that we want to throw.
            } 
            catch (DicomCodecException e)
            {
                Platform.Log(LogLevel.Error, e, "Unexpected exception when compressing or decompressing file before send {0}", fileToSend.Filename);

                fileToSend.SendStatus = DicomStatuses.ProcessingFailure;
                fileToSend.ExtendedFailureDescription = string.Format("Error decompressing or compressing file before send: {0}", e.Message);
                _failureSubOperations++;
                _remainingSubOperations--;
                OnImageStoreCompleted(fileToSend);
                return false;

            }
            catch (DicomException e)
            {
                Platform.Log(LogLevel.Error, e, "Unexpected exception while sending file {0}", fileToSend.Filename);

                fileToSend.SendStatus = DicomStatuses.ProcessingFailure;
                fileToSend.ExtendedFailureDescription = string.Format("Unexpected exception while sending file: {0}", e.Message);
                _failureSubOperations++;
                _remainingSubOperations--;
                OnImageStoreCompleted(fileToSend);
                return false;
            }

			return true;
		}
Пример #52
0
		public override void OnReceiveRequestMessage(DicomClient client, ClientAssociationParameters association, byte presentationID, DicomMessage message)
		{
			try
			{
				// We only handle NEventReport request messages
				if (message.CommandField != DicomCommandField.NEventReportRequest ||
					message.AffectedSopClassUid != SopClass.PrinterSopClassUid)
				{
					base.OnReceiveRequestMessage(client, association, presentationID, message);
					return;
				}
				
				var printerStatus = IodBase.ParseEnum(message.EventTypeId.ToString(), PrinterStatus.None);
				var printerModule = new PrinterModuleIod(message.DataSet);
				var logMessage = string.Format("Received NEventReportRequest, Printer Status: {0}, Status Info = {1}", printerStatus,
											   printerModule.PrinterStatusInfo);

				//Always respond.
				Client.SendNEventReportResponse(GetPresentationContextId(this.AssociationParameters),
												 message, new DicomMessage(), DicomStatuses.Success);

				switch (printerStatus)
				{
					case PrinterStatus.Failure:
						Platform.Log(LogLevel.Error, logMessage);
						this.FailureDescription = SR.MessagePrinterError;
						this.ReleaseConnection(client);
						return;
					case PrinterStatus.Warning:
						Platform.Log(LogLevel.Warn, logMessage);
						break;
					case PrinterStatus.None:
					case PrinterStatus.Normal:
					default:
						Platform.Log(LogLevel.Debug, logMessage);
						break;
				}

			}
			catch (Exception ex)
			{
				this.FailureDescription = ex.Message;
				Platform.Log(LogLevel.Error, ex.ToString());
				ReleaseConnection(client);
				throw;
			}
		}
Пример #53
0
        private void SendDeleteFilmBoxRequest(DicomClient client, ClientAssociationParameters association, DicomMessage responseMessage)
        {
            if (_filmBoxUids.Count == 0)
            {
                // no more film boxes left to delete - so send delete film session
                SendDeleteFilmSessionRequest(client, association);
            }
            else
            {
                string currentFilmBoxUid = _filmBoxUids[0];
                _filmBoxUids.Remove(currentFilmBoxUid);

                DicomMessage newRequestMessage = new DicomMessage(null, null);
                newRequestMessage.RequestedSopInstanceUid = currentFilmBoxUid;
                newRequestMessage.RequestedSopClassUid = SopClass.BasicFilmBoxSopClassUid;
                newRequestMessage.Priority = DicomPriority.Medium;

                _nextRequestType = RequestType.DeleteFilmBox;

                byte pcid = association.FindAbstractSyntaxOrThrowException(SopClass.BasicGrayscalePrintManagementMetaSopClass);
                client.SendNDeleteRequest(pcid, client.NextMessageID(), newRequestMessage);
            }
        }
Пример #54
0
        private void SendOnPresentationContext(DicomClient client, ClientAssociationParameters association, byte pcid, StorageInstance fileToSend, DicomMessage msg)
        {
            var presContext = association.GetPresentationContext(pcid);
            if (msg.TransferSyntax.Encapsulated
                && presContext.AcceptedTransferSyntax.Encapsulated
                && !msg.TransferSyntax.Equals(presContext.AcceptedTransferSyntax))
            {
                // Compressed in different syntaxes, decompress here first, ChangeTransferSyntax does not convert syntaxes properly in this case.
                msg.ChangeTransferSyntax(TransferSyntax.ExplicitVrLittleEndian);
            }

            fileToSend.SentMessageId = client.NextMessageID();

            if (_moveOriginatorAe == null)
                client.SendCStoreRequest(pcid, fileToSend.SentMessageId, DicomPriority.Medium, msg);
            else
                client.SendCStoreRequest(pcid, fileToSend.SentMessageId, DicomPriority.Medium, _moveOriginatorAe,
                                         _moveOriginatorMessageId, msg);
        }
Пример #55
0
		/// <summary>
		/// Called when received associate accept.  We send the verificationrequest.
		/// </summary>
		/// <param name="client">The client.</param>
		/// <param name="association">The association.</param>
		public override void OnReceiveAssociateAccept(DicomClient client, ClientAssociationParameters association)
		{
			base.OnReceiveAssociateAccept(client, association);
			if (Canceled)
				client.SendAssociateAbort(DicomAbortSource.ServiceUser,DicomAbortReason.NotSpecified);
			else
				SendVerificationRequest(client, association);
		}
Пример #56
0
        private void SendDeleteFilmSessionRequest(DicomClient client, ClientAssociationParameters association)
        {
            DicomMessage newRequestMessage = new DicomMessage(null, null);
            newRequestMessage.RequestedSopInstanceUid = _filmSessionUid;
            newRequestMessage.RequestedSopClassUid = SopClass.BasicFilmSessionSopClassUid;

            _nextRequestType = RequestType.Close;
            byte pcid = association.FindAbstractSyntaxOrThrowException(SopClass.BasicGrayscalePrintManagementMetaSopClass);
            client.SendNDeleteRequest(pcid, client.NextMessageID(), newRequestMessage);
        }
Пример #57
0
		/// <summary>
		/// Called when received associate accept.
		/// </summary>
		/// <param name="client">The client.</param>
		/// <param name="association">The association.</param>
		public override void OnReceiveAssociateAccept(DicomClient client, ClientAssociationParameters association)
		{
			base.OnReceiveAssociateAccept(client, association);
			if (Canceled)
			{
				client.SendAssociateAbort(DicomAbortSource.ServiceUser, DicomAbortReason.NotSpecified);
			}
			else
			{
				CreateFilmSession(_filmSession);
			}
		}
Пример #58
0
        /// <summary>
        /// Called when received response message.
        /// </summary>
        /// <param name="client">The client.</param>
        /// <param name="association">The association.</param>
        /// <param name="presentationID">The presentation ID.</param>
        /// <param name="message">The message.</param>
        public override void OnReceiveResponseMessage(DicomClient client, ClientAssociationParameters association, byte presentationID, DicomMessage message)
        {
            try
            {
                base.ResultStatus = message.Status.Status;
                if (message.Status.Status == DicomState.Success)
                {
                    if (message.CommandField == DicomCommandField.NCreateResponse && message.AffectedSopClassUid == SopClass.BasicFilmSessionSopClassUid)
                    {
                        _filmSessionUid = message.AffectedSopInstanceUid;
                    }

                    else if (message.CommandField == DicomCommandField.NCreateResponse && message.AffectedSopClassUid == SopClass.BasicFilmBoxSopClassUid)
                    {
                        _filmBoxUids.Add(message.AffectedSopInstanceUid);
                        _filmBoxResponseMessages.Add(message.AffectedSopInstanceUid, message.DataSet);
                    }

                    Platform.Log(LogLevel.Info, "Success status received in Printer Status Scu!");
                    _results = message.DataSet;
                    switch (_nextRequestType)
                    {
                        case RequestType.FilmBox:
                            SendCreateFilmBoxRequest(client, association, message);
                            break;

                        case RequestType.ImageBox:
                            SendSetImageBoxRequest(client, association);
                            break;

                        case RequestType.PrintAction:
                            SendActionPrintRequest(client, association);
                            break;

                        case RequestType.DeleteFilmBox:
                            SendDeleteFilmBoxRequest(client, association, message);
                            break;

                        case RequestType.DeleteFilmSession:
                            SendDeleteFilmSessionRequest(client, association);
                            break;

                        case RequestType.Close:
                            base.ReleaseConnection(client);
                            break;

                        case RequestType.None:
                        default:
                            // TODO: throw error....
                            break;
                    }
                }
                else
                {
                    // TODO: Handle this... check for warnings - they are OK?  throw exception on errors... ?
                }

            }
            catch (Exception ex)
            {
                Platform.Log(LogLevel.Error, ex.ToString());
                base.ReleaseConnection(client);
                throw;
            }
        }
Пример #59
0
		/// <summary>
		/// Called when received response message.
		/// </summary>
		/// <param name="client">The client.</param>
		/// <param name="association">The association.</param>
		/// <param name="presentationID">The presentation ID.</param>
		/// <param name="message">The message.</param>
		public override void OnReceiveResponseMessage(DicomClient client, ClientAssociationParameters association, byte presentationID, DicomMessage message)
		{
			try
			{
				this.ResultStatus = message.Status.Status;
				switch (this.ResultStatus)
				{
					case DicomState.Cancel:
					case DicomState.Pending:
					case DicomState.Failure:
						Platform.Log(LogLevel.Error, string.Format("{0} status received in Print Scu response message", message.Status.Status));

						this.FailureDescription = SR.MessagePrinterError;
						this.ReleaseConnection(client);
						return;

					case DicomState.Warning:
						Platform.Log(LogLevel.Warn, string.Format("{0} status received in Print Scu response message", message.Status.Status));
						break;

					case DicomState.Success:
						break;
				}

				EventsHelper.Fire(this.ProgressUpdated, this, new ProgressUpdateEventArgs(_numberOfImageBoxesSent));

				if (Canceled)
				{
					Platform.Log(LogLevel.Info, "Cancel requested by user.  Closing association.");
					client.SendAssociateAbort(DicomAbortSource.ServiceUser, DicomAbortReason.NotSpecified);
					return;
				}

				Platform.Log(LogLevel.Info, "Success status received in Print Scu");

				var affectedUid = new DicomUid(message.AffectedSopInstanceUid, "Instance UID", UidType.SOPInstance);

				switch (message.CommandField)
				{
					case DicomCommandField.NCreateResponse:
						switch (_eventObject)
						{
							case EventObject.FilmSession:
								_filmSession.OnCreated(affectedUid);
								break;
							case EventObject.FilmBox:
								{
									var responseFilmBoxModule = new BasicFilmBoxModuleIod(message.DataSet);
									_filmSession.OnFilmBoxCreated(affectedUid,
										CollectionUtils.Map<ReferencedInstanceSequenceIod, DicomUid>(
											responseFilmBoxModule.ReferencedImageBoxSequenceList,
											imageBoxModule => new DicomUid(imageBoxModule.ReferencedSopInstanceUid, "Instance UID", UidType.SOPInstance)
										));
								}
								break;
						}

						break;

					case DicomCommandField.NDeleteResponse:
						switch (_eventObject)
						{
							case EventObject.FilmSession:
								_filmSession.OnDeleted();
								this.ReleaseConnection(client);
								break;
							case EventObject.FilmBox:
								_filmSession.OnFilmBoxDeleted();
								break;
						}

						break;

					case DicomCommandField.NSetResponse:
						_numberOfImageBoxesSent++;
						_filmSession.OnImageBoxSet(affectedUid);
						break;

					case DicomCommandField.NActionResponse:
						_filmSession.OnFilmBoxPrinted(affectedUid);

						break;
					default:
						break;
				}
			}
			catch (Exception ex)
			{
				this.FailureDescription = ex.Message;
				Platform.Log(LogLevel.Error, ex.ToString());
				ReleaseConnection(client);
				throw;
			}
		}
Пример #60
0
		/// <summary>
		/// Generic routine to continue attempting to send C-STORE-RQ messages in the <see cref="StorageInstanceList"/> until one is successful.
		/// </summary>
		/// <remarks>
		/// <para>
		/// This routine will continue attempting to send a C-STORE until one has successfully been sent or all
		/// SOP instances in the <see cref="StorageInstanceList"/> have been sent.  Possible failures are that 
		/// a SOP Class was not negotiated, or a failure happened reading the SOP Instance from disk.
		/// </para>
		/// </remarks>
		/// <param name="client">DICOM Client class</param>
		/// <param name="association">Association Parameters</param>
		private void SendCStoreUntilSuccess(DicomClient client, ClientAssociationParameters association)
		{
		    /// TODO (CR Jun 2012): Probably shouldn't use thread pool threads for potentially long-running operations.
		    /// Although unlikely, this could exhaust the .NET thread pool.
		    
            // Added the background thread as part of ticket #9568.  Note that we probably should have some threading 
            // built into NetworkBase as opposed to here.
		    ThreadPool.QueueUserWorkItem(delegate
		                                     {
                                                 try
                                                 {
                                                     bool ok = SendCStore(client, association);
                                                     while (ok == false)
                                                     {
                                                         Platform.Log(LogLevel.Info, "Attempted to send {0} of {1} instances to {2}.", _fileListIndex + 1, _storageInstanceList.Count, client.AssociationParams.CalledAE);
                                                         _fileListIndex++;
                                                         if (_fileListIndex >= _storageInstanceList.Count)
                                                         {
                                                             Platform.Log(LogLevel.Info,
                                                                          "Completed sending C-STORE-RQ messages, releasing association.");
                                                             client.SendReleaseRequest();
                                                             StopRunningOperation();
                                                             return;
                                                         }

                                                         /// TODO (CR Jun 2012): Do we need to check for a stop signal?
                                                         // TODO (Marmot): Check stop?
                                                         // TODO (CR Jun 2012): Stop is checked for in OnReceiveResponseMessage after each c-store-rsp received.
                                                         // There's a small chance that every image we're attempting to send wasn't negotiated over the association and it
                                                         // takes awhile to go through the list, but the chances of that are small, plus it should be quick.
                                                         ok = SendCStore(client, association);                                                             
                                                     }                                                     
                                                 }
                                                 catch
                                                 {
                                                     Platform.Log(LogLevel.Error, "Error when sending C-STORE-RQ messages, aborted on-going send operations");
                                                     try
                                                     {
                                                         client.SendAssociateAbort(DicomAbortSource.ServiceProvider, DicomAbortReason.NotSpecified);
                                                         StopRunningOperation();    
                                                     }
                                                     catch
                                                     {
                                                         Platform.Log(LogLevel.Error, "Error attempting to abort association");
                                                     }                                                     
                                                 }
		                                     }, null);
		}