예제 #1
0
        public void Level_GetterOnRequestCreatedFromCommand_Throws()
        {
            var request   = new DicomCMoveRequest(new DicomDataset());
            var exception = Record.Exception(() => request.Level);

            Assert.NotNull(exception);
        }
예제 #2
0
        public IEnumerable <DicomCMoveResponse> OnCMoveRequest(DicomCMoveRequest request)
        {
            List <DicomCMoveResponse> response = new List <DicomCMoveResponse>();
            List <Pathmodel>          pathList = qrm.CMove(request.Dataset, request.Level);
            DicomClient cstoreClient           = new DicomClient();

            try
            {
                foreach (Pathmodel p in pathList)
                {
                    DicomCStoreRequest cstorerq = new DicomCStoreRequest(p.Path);
                    cstorerq.OnResponseReceived = (rq, rs) =>
                    {
                        if (rs.Status == DicomStatus.Success)
                        {
                            DicomCMoveResponse rsp = new DicomCMoveResponse(request, DicomStatus.Pending);
                            SendResponse(rsp);
                        }
                    };
                    cstoreClient.AddRequest(cstorerq);
                    cstoreClient.Send("127.0.0.1", 2222, false, this.Association.CalledAE, request.DestinationAE);
                }
                return(response);
            }
            catch
            {
                DicomCMoveResponse rs = new DicomCMoveResponse(request, DicomStatus.StorageStorageOutOfResources);
                response.Add(rs);
                return(response);
            }
        }
예제 #3
0
        public static DicomCMoveRequest CreateCMoveByStudyUID(string destination, string studyUID)
        {
            var request = new DicomCMoveRequest(destination, studyUID);

            // no more dicomtags have to be set
            return(request);
        }
예제 #4
0
            public IEnumerable <DicomCMoveResponse> OnCMoveRequest(DicomCMoveRequest request)
            {
                yield return(new DicomCMoveResponse(request, DicomStatus.Pending));

                Thread.Sleep(3000);
                yield return(new DicomCMoveResponse(request, DicomStatus.Success));
            }
예제 #5
0
        public async Task SendingMoveRequestToServerThatSendsPendingResponsesTooSlowlyShouldTimeout()
        {
            var port = Ports.GetNext();

            using (CreateServer <SlowPendingResponsesDicomServer>(port))
            {
                var client = CreateClient(port);

                client.ServiceOptions.RequestTimeout = TimeSpan.FromSeconds(2);

                var request = new DicomCMoveRequest("another-AE", "study123");

                DicomRequest.OnTimeoutEventArgs onTimeoutEventArgs = null;
                request.OnTimeout += (sender, args) => onTimeoutEventArgs = args;
                RequestTimedOutEventArgs eventArgsFromDicomClientRequestTimedOut = null;
                client.RequestTimedOut += (sender, args) => eventArgsFromDicomClientRequestTimedOut = args;

                await client.AddRequestAsync(request).ConfigureAwait(false);

                var sendTask = client.SendAsync();
                var sendTimeoutCancellationTokenSource = new CancellationTokenSource();
                var sendTimeout = Task.Delay(TimeSpan.FromSeconds(10), sendTimeoutCancellationTokenSource.Token);

                var winner = await Task.WhenAny(sendTask, sendTimeout).ConfigureAwait(false);

                sendTimeoutCancellationTokenSource.Cancel();
                sendTimeoutCancellationTokenSource.Dispose();

                Assert.Equal(winner, sendTask);
                Assert.NotNull(onTimeoutEventArgs);
                Assert.NotNull(eventArgsFromDicomClientRequestTimedOut);
                Assert.Equal(request, eventArgsFromDicomClientRequestTimedOut.Request);
                Assert.Equal(client.ServiceOptions.RequestTimeout, eventArgsFromDicomClientRequestTimedOut.Timeout);
            }
        }
예제 #6
0
        public async Task <bool?> MoveImagesAsync(string serverIp, int serverPort, string serverAET, string localAET, string destAET, string studyInstanceUid, string seriesInstanceUid = null)
        {
            bool?success = null;

            DicomCMoveRequest request = string.IsNullOrEmpty(seriesInstanceUid) ?
                                        RequestFactory.CreateCMoveByStudyUID(destAET, studyInstanceUid) :
                                        RequestFactory.CreateCMoveBySeriesUID(destAET, studyInstanceUid, seriesInstanceUid);

            request.OnResponseReceived += (req, res) =>
            {
                if (res.Status.State == DicomState.Pending)
                {
                    logger.Info("Sending is in progress. please wait: " + res.Remaining.ToString());
                }
                else if (res.Status.State == DicomState.Success)
                {
                    logger.Info("Sending successfully finished.");
                    success = true;
                }
                else if (res.Status.State == DicomState.Failure)
                {
                    logger.Info("Error sending datasets: " + res.Status.Description);
                    success = false;
                }
                logger.Debug("C-MOVE response status. " + res.Status.Description);
            };

            DicomClient client = new DicomClient(serverIp, serverPort, false, localAET, serverAET);
            await client.AddRequestAsync(request);

            await client.SendAsync();

            return(success);
        }
예제 #7
0
        /// <summary>
        /// Asks the server indicated in <see cref="Configuration"/>
        /// to send the specified <see cref="Series"/>.
        /// Implements the DICOM C-MOVE Command at SERIES level.
        /// </summary>
        /// <param name="configuration">Server and Client configuration.</param>
        /// <param name="seriesResponse">Parameters specifying the query.</param>
        /// <returns>The path where the series has been saved.</returns>
        public static string CMOVESeries(Configuration configuration, Series seriesResponse)
        {
            // init move request
            var cmove = new DicomCMoveRequest(configuration.thisNodeAET, seriesResponse.getStudyInstanceUID(), seriesResponse.getSeriesInstanceUID());

            var client = new DicomClient();

            client.AddRequest(cmove);

            // prepare to receive data
            File.Delete("singleImage.txt");
            // write file path based on uids, current date, and path chosen by user
            string path = seriesResponse.getFullPath(configuration.fileDestination);

            Directory.CreateDirectory(path);
            using (var streamWriter = new StreamWriter("pathForDownload.txt", false))
            {
                streamWriter.WriteLine(path);
            }

            // send query
            if (Directory.GetFiles(path).Length == 0)
            {
                Debug.downloading(configuration);
                var _networkStream = new DesktopNetworkStream(configuration, true, true);
                client.Send(_networkStream, configuration.thisNodeAET, configuration.AET, 5000);
                Debug.done();
            }
            else
            {
                Console.WriteLine("File is already present in database.");
            }
            return(path);
        }
예제 #8
0
        public void AddSeveralUIDsToQuery()
        {
            var e = Record.Exception(() =>
            {
                var request = new DicomCMoveRequest("DestinationAE", "1.2.3.456");
                request.Dataset.Add(DicomTag.SeriesInstanceUID, "1.2.3\\3.4.5");
                Assert.Equal(2, request.Dataset.GetValueCount(DicomTag.SeriesInstanceUID));
            });

            Assert.Null(e);

            e = Record.Exception(() =>
            {
                var request = new DicomCMoveRequest("DestinationAE", "1.2.3.456");
                request.Dataset.Add(DicomTag.SeriesInstanceUID, "1.2.3", "2.3.4");
                Assert.Equal(2, request.Dataset.GetValueCount(DicomTag.SeriesInstanceUID));
            });
            Assert.Null(e);

            e = Record.Exception(() =>
            {
                var request = new DicomCMoveRequest("DestinationAE", "1.2.3.456");
                request.Dataset.Add(new DicomUniqueIdentifier(DicomTag.SeriesInstanceUID, "1.2.3", "3.4.5"));
                Assert.Equal(2, request.Dataset.GetValueCount(DicomTag.SeriesInstanceUID));
            });
            Assert.Null(e);
        }
예제 #9
0
        public static DicomCMoveRequest CreateCMoveBySeriesUID(string destAET, string studyInstanceUID, string seriesInstanceUID, DicomPriority priority = DicomPriority.Medium)
        {
            var request = new DicomCMoveRequest(destAET, studyInstanceUID, seriesInstanceUID, priority);

            // no more dicomtags have to be set
            return(request);
        }
예제 #10
0
        private DicomCMoveRequest CreateCMoveByStudyUid(string destination, string studyUid, DicomPriority priority = DicomPriority.Low)
        {
            var request = new DicomCMoveRequest(destination, studyUid, priority);

            Listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Information, "DicomRetriever.CreateCMoveByStudyUid created request for: " + studyUid));
            // no more dicomtags have to be set
            return(request);
        }
예제 #11
0
        private DicomCMoveRequest CreateCMoveBySopInstanceUid(string destination, string studyUid, string seriesUid, string sopInstanceUid)
        {
            var request = new DicomCMoveRequest(destination, studyUid, seriesUid, sopInstanceUid);

            Listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Information, "DicomRetriever.CreateCMoveBySopInstanceUid created request for: " + sopInstanceUid));
            // no more dicomtags have to be set
            return(request);
        }
예제 #12
0
        protected DicomCMoveRequest CreateCMoveByStudyUid(string destination, string studyUid, IDataLoadEventListener listener)
        {
            var request = new DicomCMoveRequest(destination, studyUid);

            listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Information, "DicomRetriever.CreateCMoveByStudyUid created request for: " + studyUid));
            // no more dicomtags have to be set
            return(request);
        }
예제 #13
0
        public DicomCMoveRequest CreateCMoveBySeriesUID(DicomDataset dSet)
        {
            dSet.AddOrUpdate(DicomTag.CommandField, (ushort)DicomCommandField.CMoveRequest);
            dSet.AddOrUpdate(DicomTag.AffectedSOPClassUID, DicomUID.StudyRootQueryRetrieveInformationModelMOVE);
            var request = new DicomCMoveRequest(dSet);

            return(request);
        }
예제 #14
0
        private void move_click(object sender, EventArgs e)
        {
            var cmove = new DicomCMoveRequest("DEST-AE", studyInstanceUid);

            var client = new DicomClient();

            client.AddRequest(cmove);
            client.Send("127.0.0.1", 11112, false, "SCU-AE", "SCP-AE");
        }
예제 #15
0
        public void CreateQueryWithInvalidUID()
        {
            var invalidStudyUID = "1.2.0004";
            var e = Record.Exception(() =>
            {
                var request = new DicomCMoveRequest("DestinationAE", invalidStudyUID);
                Assert.Equal(invalidStudyUID, request.Dataset.GetSingleValue <string>(DicomTag.StudyInstanceUID));
            });

            Assert.Null(e);
        }
예제 #16
0
        public void AddInvalidUIDToQuery()
        {
            var invalidStudyUID = "1.2.0004";
            var e = Record.Exception(() =>
            {
                var request = new DicomCMoveRequest("DestinationAE", invalidStudyUID);
                request.Dataset.AddOrUpdate(DicomTag.SeriesInstanceUID, invalidStudyUID);
                Assert.Equal(invalidStudyUID, request.Dataset.GetSingleValue <string>(DicomTag.SeriesInstanceUID));
            });

            Assert.Null(e);
        }
예제 #17
0
 public DicomCMoveRequest GetDicomCMoveRequest(string destination)
 {
     if (_items == null)
     {
         lock (_oItemsLock)
         {
             _items = _order.GetPickerList();
         }
     }
     if (_dicomCMoveRequest == null)
     {
         _dicomCMoveRequest = _order.GetDicomCMoveRequest(destination, _items.Values.FirstOrDefault());
     }
     return(_dicomCMoveRequest);
 }
예제 #18
0
        // download series----------------------------------------------
        void onSeriesClicked(int seriesNumber)
        {
            var seriesResponse = seriesResponses[seriesNumber];

            // download
            File.Delete("singleImage.txt");
            var cmove = new DicomCMoveRequest(configuration.thisNodeAET, seriesResponse.StudyInstanceUID, seriesResponse.SeriesInstanceUID);

            var client = new DicomClient();

            client.AddRequest(cmove);

            Console.WriteLine("Downloading series from server " + configuration.ip + ":" + configuration.port);
            client.Send(configuration.ip, configuration.port, false, configuration.thisNodeAET, configuration.AET);
            Console.WriteLine("Done.");
        }
예제 #19
0
        /// <summary>
        /// Asks the server indicated in <see cref="Configuration"/> to send the image specified
        /// in the <see cref="string"/>, representative of the <see cref="Series"/>.
        /// Implements DICOM C-MOVE Command at IMAGE level.
        /// </summary>
        /// <param name="configuration">Server and Client configuration.</param>
        /// <param name="seriesResponse">Parameters specifying the query.</param>
        /// <param name="SOPInstanceUID">SOPInstanceUID specifying the query.</param>
        /// <returns>The .dcm image representative of the series as a BitmapImage.</returns>
        static BitmapImage CMOVEImage(Configuration configuration, Series seriesResponse, string SOPInstanceUID)
        {
            // init move request
            var cmove = new DicomCMoveRequest(configuration.thisNodeAET, seriesResponse.getStudyInstanceUID(), seriesResponse.getSeriesInstanceUID(), SOPInstanceUID);

            var client = new DicomClient();

            client.AddRequest(cmove);

            // prepare to receive data
            File.Create("singleImage.txt").Close();
            DirectoryInfo di = new DirectoryInfo("./images/");

            di.Create();
            foreach (FileInfo file in di.GetFiles())
            {
                file.Delete();
            }

            // send query
            var _networkStream = new DesktopNetworkStream(configuration, true, true);

            client.Send(_networkStream, configuration.thisNodeAET, configuration.AET, 5000);


            // load the image downloaded from the listener
            var image = new BitmapImage();

            if (File.Exists("./images/file.jpg"))
            {
                var uriSource = new Uri(Path.GetFullPath("./images/file.jpg"));
                image.BeginInit();
                image.CacheOption   = BitmapCacheOption.OnLoad;
                image.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
                image.UriSource     = uriSource;
                image.EndInit();
            }
            else
            {
                Console.WriteLine("Listener didn't receive anything or didn't work");
            }

            File.Delete("singleImage.txt");
            return(image);
        }
예제 #20
0
            public async IAsyncEnumerable <DicomCMoveResponse> OnCMoveRequestAsync(DicomCMoveRequest request)
            {
                await Task.Delay(1000);

                yield return(new DicomCMoveResponse(request, DicomStatus.Pending));

                await Task.Delay(1000);

                yield return(new DicomCMoveResponse(request, DicomStatus.Pending));

                await Task.Delay(1000);

                yield return(new DicomCMoveResponse(request, DicomStatus.Pending));

                await Task.Delay(1000);

                yield return(new DicomCMoveResponse(request, DicomStatus.Success));
            }
예제 #21
0
        public async Task RetrieveAsync(DicomCMoveRequest request, Func <DicomDataset, Task <bool> > storeHandler, int destinationPort)
        {
            var server = (DicomStoreServer)DicomServer.Create <DicomStoreService, DicomStoreServer>(null, destinationPort);

            server.AeTitle              = request.DestinationAE;
            server.OnCStoreRequest      = cStoreRequest => storeHandler(cStoreRequest.Dataset).Result ? DicomStatus.Success : DicomStatus.QueryRetrieveUnableToPerformSuboperations;
            request.OnResponseReceived += (_, response) =>
            {
                if (response.Status == DicomStatus.Success)
                {
                    server.Dispose();
                }
            };

            var client = CreateClient();
            await client.AddRequestAsync(request);

            await client.SendAsync();
        }
예제 #22
0
        public async Task <List <DicomFile> > GetDicomFiles(string studyInstanceUID, string seriesInstanceUID)
        {
            ReceivedFiles.Clear();
            DicomCMoveRequest moveRequest = new DicomCMoveRequest(_preferences.AETitle, studyInstanceUID, seriesInstanceUID);

            moveRequest.OnResponseReceived += (DicomCMoveRequest requ, DicomCMoveResponse response) =>
            {
                if (response.Status.State == DicomState.Pending)
                {
                    //logger.Trace("PresentationContext: " + response.PresentationContext.AcceptedTransferSyntax.ToString());
                }
                else if (response.Status.State == DicomState.Success)
                {
                    logger.Trace("Sending successfully finished");
                }
                else if (response.Status.State == DicomState.Failure)
                {
                    logger.Error("Error sending datasets: " + response.Status.Description);
                }
            };
            logger.Debug("Move Request; AE Title: " + _preferences.AETitle + "; Level: " + moveRequest.Level + "; SOP Class UID: " + moveRequest.SOPClassUID);
            foreach (StoredDicomServer s in DicomServers)
            {
                logger.Trace("GetDicomFiles(" + studyInstanceUID + "," + seriesInstanceUID + ") on " + s.AETitle);


                var pcs = DicomPresentationContext.GetScpRolePresentationContextsFromStorageUids(
                    DicomStorageCategory.Image,
                    DicomTransferSyntax.ExplicitVRLittleEndian,
                    DicomTransferSyntax.ImplicitVRLittleEndian);
                DicomClient client = new DicomClient(s.IPAddress, s.Port, false, _preferences.AETitle, s.AETitle);
                client.AdditionalPresentationContexts.AddRange(pcs);
                client.AssociationRejected += Client_AssociationRejected;
                client.AssociationAccepted += Client_AssociationAccepted;
                client.NegotiateAsyncOps();
                await client.AddRequestAsync(moveRequest);

                await client.SendAsync();
            }

            return(ReceivedFiles);
        }
예제 #23
0
        //建立连接并Retrieve
        async public void DicomCRetrieveRequestFunct(ServerConfig OneServerConfig)
        {
            // 建立连接
            var client = new DicomClient(OneServerConfig.RemoteIp, OneServerConfig.RemotePort,
                                         false, OneServerConfig.LocalAeTitle, OneServerConfig.RemoteAeTitle);

            client.NegotiateAsyncOps();

            // 使用CMOVE抓取信息,发送到本机STORE服务
            // using ()
            {
                OneServerConfig.AddLogStr($"Run C-Store SCP server on port 104");
                foreach (var oneResult in Results)
                {
                    var  cMoveRequest     = new DicomCMoveRequest("SegAE", oneResult.StudyInstanceUid, oneResult.SeriesInstanceUid);
                    bool?moveSuccessfully = null;


                    cMoveRequest.OnResponseReceived += (DicomCMoveRequest requ, DicomCMoveResponse response) =>
                    {
                        if (response.Status.State == DicomState.Pending)
                        {
                            // Console.WriteLine("Sending is in progress. please wait: " + response.Remaining.ToString());
                        }
                        else if (response.Status.State == DicomState.Success)
                        {
                            OneServerConfig.AddLogStr($"{oneResult.PatientId} " +
                                                      $"{oneResult.SeriesInstanceUid}");
                            moveSuccessfully = true;
                        }
                        else if (response.Status.State == DicomState.Failure)
                        {
                            OneServerConfig.AddLogStr($"{response.Status.Description}");
                            moveSuccessfully = false;
                        }
                    };
                    await client.AddRequestAsync(cMoveRequest);

                    await client.SendAsync();
                }
            }
        }
예제 #24
0
        private string CMoveRequestToString(DicomCMoveRequest cMoveRequest)
        {
            var stub = "Retrieving " + cMoveRequest.Level.ToString() + " : ";

            switch (cMoveRequest.Level)
            {
            case DicomQueryRetrieveLevel.Patient:
                return(stub + cMoveRequest.Dataset.GetSingleValue <string>(DicomTag.PatientID));

            case DicomQueryRetrieveLevel.Study:
                return(stub + cMoveRequest.Dataset.GetSingleValue <string>(DicomTag.StudyInstanceUID));

            case DicomQueryRetrieveLevel.Series:
                return(stub + cMoveRequest.Dataset.GetSingleValue <string>(DicomTag.SeriesInstanceUID));

            case DicomQueryRetrieveLevel.Image:
                return(stub + cMoveRequest.Dataset.GetSingleValue <string>(DicomTag.SOPInstanceUID));

            default:
                return(stub + DicomQueryRetrieveLevel.NotApplicable.ToString());
            }
        }
예제 #25
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();
        }
예제 #26
0
        BitmapImage downloadSampleImage(SeriesQueryOut seriesResponse, string SOPInstanceUID)
        {
            var cmove = new DicomCMoveRequest(configuration.thisNodeAET, seriesResponse.StudyInstanceUID, seriesResponse.SeriesInstanceUID, SOPInstanceUID);

            var client = new DicomClient();

            client.AddRequest(cmove);

            File.Create("singleImage.txt").Close();

            DirectoryInfo di = new DirectoryInfo("./images/");

            foreach (FileInfo file in di.GetFiles())
            {
                file.Delete();
            }

            client.Send(configuration.ip, configuration.port, false, configuration.thisNodeAET, configuration.AET);

            var image = new BitmapImage();

            if (File.Exists("./images/file.jpg"))
            {
                var uriSource = new Uri(Path.GetFullPath("./images/file.jpg"));
                image.BeginInit();
                image.CacheOption   = BitmapCacheOption.OnLoad;
                image.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
                image.UriSource     = uriSource;
                image.EndInit();
            }
            else
            {
                MessageBox.Show("Listener didn't receive anything or didn't work");
            }

            File.Delete("singleImage.txt");
            return(image);
        }
예제 #27
0
        public async Task SendingMoveRequestToServerThatSendsPendingResponsesWithinTimeoutShouldNotTimeout()
        {
            var port = Ports.GetNext();

            using (CreateServer <FastPendingResponsesDicomServer>(port))
            {
                var client = CreateClient(port);

                client.ServiceOptions.RequestTimeout = TimeSpan.FromSeconds(2);

                DicomCMoveResponse lastResponse = null;
                var request = new DicomCMoveRequest("another-AE", "study123")
                {
                    OnResponseReceived = (req, res) => lastResponse = res
                };

                DicomRequest.OnTimeoutEventArgs onTimeoutEventArgs = null;
                request.OnTimeout += (sender, args) => onTimeoutEventArgs = args;

                await client.AddRequestAsync(request).ConfigureAwait(false);

                var sendTask = client.SendAsync();
                var sendTimeoutCancellationTokenSource = new CancellationTokenSource();
                var sendTimeout = Task.Delay(TimeSpan.FromSeconds(10), sendTimeoutCancellationTokenSource.Token);

                var winner = await Task.WhenAny(sendTask, sendTimeout).ConfigureAwait(false);

                sendTimeoutCancellationTokenSource.Cancel();
                sendTimeoutCancellationTokenSource.Dispose();

                Assert.Equal(winner, sendTask);
                Assert.NotNull(lastResponse);
                Assert.Equal(lastResponse.Status, DicomStatus.Success);
                Assert.Null(onTimeoutEventArgs);
            }
        }
예제 #28
0
        static void Main(string[] args)
        {
            //开启C-STORE SCP服务,用于接收C-MOVE SCP返回的图像
            CStoreSCP.OnCStoreRequestCallBack = (request) =>
            {
                var studyUid = request.Dataset.Get <string>(DicomTag.StudyInstanceUID);
                var instUid  = request.SOPInstanceUID.UID;

                var path = Path.GetFullPath(@"c:\cmove-scu");
                path = Path.Combine(path, studyUid);

                if (!Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                }

                path = Path.Combine(path, instUid) + ".dcm";

                request.File.Save(path);

                return(new DicomCStoreResponse(request, DicomStatus.Success));
            };

            var cstoreServer = new DicomServer <CStoreSCP>(22345);

            //发起C-MOVE-RQ操作,发送请求的StudyID是12
            DicomCMoveRequest req = new DicomCMoveRequest("DEST-AE", "12");
            var client            = new DicomClient();

            client.NegotiateAsyncOps();
            client.AddRequest(req);
            //这里的IP地址是C-MOVE SCP的地址,12345端口号是C-MOVE SCP提供C-MOVE服务的端口
            //在C-MOVE SCP端发出的C-STORE-RQ子操作请求的是C-MOVE SCU端我们实现的C-STORE SCP,C-STORE SCP绑定的端口是22345
            client.Send("127.0.0.1", 12345, false, "DEST-AE", "SCP-AE");
            Console.ReadLine();
        }
예제 #29
0
        public IEnumerable <DicomCMoveResponse> OnCMoveRequest(DicomCMoveRequest request)
        {
            // the c-move request contains the DestinationAE. the data of this AE should be configured somewhere.
            if (request.DestinationAE != "STORESCP")
            {
                yield return(new DicomCMoveResponse(request, DicomStatus.QueryRetrieveMoveDestinationUnknown));

                yield return(new DicomCMoveResponse(request, DicomStatus.ProcessingFailure));

                yield break;
            }

            // this data should come from some data storage!
            var destinationPort = 11112;
            var destinationIP   = "localhost";

            IDicomImageFinderService finderService = QRServer.CreateFinderService;
            List <string>            matchingFiles = null;

            switch (request.Level)
            {
            case DicomQueryRetrieveLevel.Patient:
                matchingFiles = finderService.FindFilesByUID(request.Dataset.Get <string>(DicomTag.PatientID), string.Empty, string.Empty);
                break;

            case DicomQueryRetrieveLevel.Study:
                matchingFiles = finderService.FindFilesByUID(string.Empty, request.Dataset.Get <string>(DicomTag.StudyInstanceUID), string.Empty);
                break;

            case DicomQueryRetrieveLevel.Series:
                matchingFiles = finderService.FindFilesByUID(string.Empty, string.Empty, request.Dataset.Get <string>(DicomTag.SeriesInstanceUID));
                break;

            case DicomQueryRetrieveLevel.Image:
                yield return(new DicomCMoveResponse(request, DicomStatus.QueryRetrieveUnableToPerformSuboperations));

                yield break;
            }

            DicomClient client = new DicomClient();

            client.NegotiateAsyncOps();
            int storeTotal   = matchingFiles.Count;
            int storeDone    = 0; // this variable stores the number of instances that have already been sent
            int storeFailure = 0; // this variable stores the number of faulues returned in a OnResponseReceived

            foreach (string file in matchingFiles)
            {
                var storeRequest = new DicomCStoreRequest(file);
                // !!! there is a Bug in fo-dicom 3.0.2 that the OnResponseReceived handlers are invoked not until the DicomClient has already
                //     sent all the instances. So the counters are not increased image by image sent but only once in a bulk after all storage
                //     has been finished. This bug will be fixed hopefully soon.
                storeRequest.OnResponseReceived += (req, resp) =>
                {
                    if (resp.Status == DicomStatus.Success)
                    {
                        Logger.Info("Storage of image successfull");
                        storeDone++;
                    }
                    else
                    {
                        Logger.Error("Storage of image failed");
                        storeFailure++;
                    }
                    // SendResponse(new DicomCMoveResponse(request, DicomStatus.Pending) { Remaining = storeTotal - storeDone - storeFailure, Completed = storeDone });
                };
                client.AddRequest(storeRequest);
            }

            // client.Send(destinationIP, destinationPort, false, QRServer.AETitle, request.DestinationAE);

            var sendTask = client.SendAsync(destinationIP, destinationPort, false, QRServer.AETitle, request.DestinationAE);

            while (!sendTask.IsCompleted)
            {
                // while the send-task is runnin we inform the QR SCU every 2 seconds about the status and how many instances are remaining to send.
                yield return(new DicomCMoveResponse(request, DicomStatus.Pending)
                {
                    Remaining = storeTotal - storeDone - storeFailure, Completed = storeDone
                });

                Thread.Sleep(TimeSpan.FromSeconds(2));
            }

            Logger.Info("..fertig");
            yield return(new DicomCMoveResponse(request, DicomStatus.Success));
        }
        public void CMove(RoutedItem routedItem, long taskID, DICOMConnection connection)
        {
            Connection = connection;

            var taskInfo = $"task: {taskID} connection: {Connection.name}";

            try
            {
                try
                {
                    // 2018-01-22 shb changed from dicomServerName to localAETitle
                    var cmove = new DicomCMoveRequest(Connection.localAETitle, routedItem.request);
                    _logger.Log(LogLevel.Information, $"{taskInfo} cMove id: {routedItem.id} MessageID: {cmove.MessageID} attempt: {routedItem.attempts}");

                    cmove.UserState           = routedItem;
                    routedItem.MessageId      = cmove.MessageID;
                    routedItem.fromConnection = Connection.name;
                    routedItem.toConnections.Clear();
                    routedItem.status = RoutedItem.Status.PENDING;

                    _routedItemManager.Init(routedItem);
                    //var riToCache = (RoutedItem)routedItem.Clone();
                    var riToCache = _routedItemManager.Clone();
                    _routedItemManager.Init(riToCache);
                    _routedItemManager.Enqueue(Connection, Connection.toRules, nameof(Connection.toRules));

                    // Returns the status of the request, actual transfer happens in DicomListener
                    cmove.OnResponseReceived = (DicomCMoveRequest request, DicomCMoveResponse response) =>
                    {
                        RoutedItem ri = (RoutedItem)request.UserState;

                        _logger.Log(LogLevel.Information, $"{taskInfo} cmove.OnResponseReceived id: {ri.id} MessageId: {request.MessageID} {response.Status.Description}");

                        Dictionary <string, Dictionary <string, string> > results = new Dictionary <string, Dictionary <string, string> >();

                        Dictionary <string, string> returnTagData = new Dictionary <string, string>
                        {
                            { "StatusCode", response.Status.Code.ToString() },
                            { "StatusDescription", response.Status.Description },
                            { "StatusErrorComment", response.Status.ErrorComment },
                            { "StatusState", response.Status.State.ToString() }
                        };

                        if (response.Completed != 0 || response.Remaining != 0)
                        {
                            returnTagData.Add("Completed", response.Completed.ToString());
                            returnTagData.Add("Remaining", response.Remaining.ToString());
                        }
                        returnTagData.Add("SOPClassUID", response.SOPClassUID.ToString());

                        if (response.Command != null)
                        {
                            foreach (var dicomItem in response.Command)
                            {
                                _logger.Log(LogLevel.Debug, $"{taskInfo} cMove Response {ri.id} MessageId {request.MessageID}, {dicomItem.Tag} {response.Command.GetValueOrDefault<string>(dicomItem.Tag, 0, "")}");
                                returnTagData.Add(dicomItem.Tag.ToString(), response.Command.GetValueOrDefault <string>(dicomItem.Tag, 0, ""));
                            }
                            results.Add("response", returnTagData);
                        }

                        string jsonResults = JsonSerializer.Serialize(results);

                        ri.response.Add(jsonResults);

                        switch (response.Status.ToString())
                        {
                        case "Success":
                            ri.status      = RoutedItem.Status.COMPLETED;
                            ri.resultsTime = DateTime.Now;
                            _routedItemManager.Init(ri);
                            _routedItemManager.Dequeue(Connection, Connection.toDicom, nameof(Connection.toDicom), error: false);

                            //var toCache = (RoutedItem)ri.Clone();
                            var toCache = _routedItemManager.Clone();
                            toCache.fromConnection = Connection.name;
                            ri.toConnections.Clear();

                            _routedItemManager.Init(toCache);
                            _routedItemManager.Enqueue(Connection, Connection.toRules, nameof(Connection.toRules));
                            break;

                        case "Pending":
                            break;

                        default:
                            _routedItemManager.Init(ri);
                            _routedItemManager.Dequeue(Connection, Connection.toDicom, nameof(Connection.toDicom), error: true);
                            break;
                        }
                    };

                    dicomClient.AddRequest(cmove);
                }
                catch (Exception e)   // Needed for transfer syntax exceptions
                {
                    _logger.LogFullException(e, $"{taskInfo} move:");
                }
            }
            catch (Exception e)
            {
                _logger.LogFullException(e, taskInfo);
            }
        }