protected override void OnReceiveCMoveRequest(byte presentationID, ushort messageID, string destinationAE, DcmPriority priority, DcmDataset query) { Console.WriteLine(String.Format("{0} Receive C-Move from {1} (marked as anonymous:{2})", DateTime.Now, this.Associate.CallingAE, _flagAnonymousAccess)); Debug.WriteLine(query.Dump()); AEInfo recipientInfo = FindAE(destinationAE); if (recipientInfo == null) { SendCMoveResponse(presentationID, messageID, DcmStatus.QueryRetrieveMoveDestinationUnknown, 0, 0, 0, 0); Console.Write("Moving to:" + recipientInfo.Name + "> "); return; } Console.Write("Moving to:" + recipientInfo.Name + "> "); ushort imagesProcessed = 0; ushort errorCount = 0; ushort successCount = 0; try { using (var database = new MedicalISDataContext()) { var storeClient = new CStoreClient(); storeClient.CallingAE = "CURAPACS"; storeClient.CalledAE = destinationAE; storeClient.PreferredTransferSyntax = recipientInfo.TransferSyntax; storeClient.PreloadCount = 10; storeClient.LogID = "store"; if (Settings.Default.DebugMove) Dicom.Debug.InitializeConsoleDebugLogger(); if (_flagAnonymousAccess) storeClient.DisableFileStreaming = true; var files = GetFilePaths(database, query); if (Settings.Default.UseFixedFolder) { files = Directory.GetFiles(Settings.Default.FixedFolderPath); } long totalSize = 0; foreach (var f in files) { totalSize += new FileInfo(f).Length; storeClient.AddFile(f); } int totalImageCount = (ushort) files.Count(); Console.Write("#{0} files > ", totalImageCount); Stopwatch timer = Stopwatch.StartNew(); storeClient.OnCStoreRequestBegin = (c, i) => { if (_flagAnonymousAccess) { var dataset = i.Dataset; AnonymizeDatasetBasedOnStudyInfo(dataset); } }; storeClient.OnCStoreRequestComplete = (c, i) => { timer.Stop(); if (i.HasError) { Console.WriteLine("Error:{0}", i.Error); } else { // Console.WriteLine("Done"); } totalImageCount -= storeClient.PendingCount; }; storeClient.OnCStoreResponseReceived = (c, i) => { if (i.Status == DcmStatus.Success) { successCount++; Console.Write("."); } else { errorCount++; Console.Write("x"); } }; storeClient.OnCStoreRequestProgress = (c, i, p) => { //Console.WriteLine("{0}@{1}", p.BytesTransfered, c.Socket.LocalStats.ToString()); }; storeClient.OnCStoreRequestFailed = (c, i) => { Console.WriteLine(""); Console.WriteLine("Failed. " + i.Error.ToString()); }; storeClient.Connect(recipientInfo.Ip, recipientInfo.Port, DcmSocketType.TCP); if (storeClient.Wait()) { } timer.Stop(); double bytesPerSeconds = (double) totalSize/timer.Elapsed.TotalSeconds; double MiBPerSecond = bytesPerSeconds/(1024.0*1024.0); Console.WriteLine(""); Console.WriteLine("Done. {0} MiB/s (ImagesProcessed={1})", MiBPerSecond, imagesProcessed); SendCMoveResponse(presentationID, messageID, DcmStatus.Success, 0, imagesProcessed, 0, 0); storeClient.Close(); } } catch (Exception ex) { Console.WriteLine(""); Console.WriteLine("Failed. => " + ex.ToString()); SendCMoveResponse(presentationID, messageID, DcmStatus.ProcessingFailure, 0, imagesProcessed, 0, 0); } }
protected override void OnReceiveCFindRequest(byte presentationID, ushort messageID, DcmPriority priority, Dicom.Data.DcmDataset query) { TryInterpretStringsInDatasetUsingCorrectEncoding(query); Trace.WriteLine(String.Format("{0} Receive C-Find from {1} (marked as anonymous:{2})", DateTime.Now, this.Associate.CallingAE, _flagAnonymousAccess)); Trace.WriteLine(query.Dump()); using( var database = new MedicalISDataContext() ) { var queryLevel = query.GetString(DicomTags.QueryRetrieveLevel, null); if (queryLevel == "PATIENT") { IQueryable<Patient> patients = PatientQueries.GetMatchingPatients(database, query, _flagAnonymousAccess); patients = patients.Take(Settings.Default.MaxNumberOfStudiesReturned); foreach (var currentPatient in patients) { foreach (var currentStudy in currentPatient.Studies) { var p = currentPatient; var response = new DcmDataset { SpecificCharacterSetEncoding = query.SpecificCharacterSetEncoding }; // Map saved study tags to output response.AddElementWithValue(DicomTags.RetrieveAETitle, "CURAPACS"); response.AddElementWithValue(DicomTags.QueryRetrieveLevel, "PATIENT"); response.AddElementWithValue(DicomTags.PatientID, p.ExternalPatientID); response.AddElementWithValue(DicomTags.PatientsName, p.LastName + "^" + p.FirstName); response.AddElementWithValue(DicomTags.PatientsBirthDate, p.BirthDateTime.Value); response.AddElementWithValue(DicomTags.StudyInstanceUID, currentStudy.StudyInstanceUid); response.AddElementWithValue(DicomTags.AccessionNumber, currentStudy.AccessionNumber); response.AddElementWithValue(DicomTags.StudyDescription, currentStudy.Description); response.AddElementWithValue(DicomTags.ModalitiesInStudy, currentStudy.ModalityAggregation); if (currentStudy.PerformedDateTime.HasValue) { response.AddElementWithValue(DicomTags.StudyDate, currentStudy.PerformedDateTime.Value); response.AddElementWithValue(DicomTags.StudyTime, currentStudy.PerformedDateTime.Value); } response.AddElementWithValue(DicomTags.NumberOfStudyRelatedSeries, currentStudy.Series.Count); response.AddElementWithValue(DicomTags.NumberOfStudyRelatedInstances, (from s in currentStudy.Series select s.Images.Count).Sum()); if (_flagAnonymousAccess) AnonymizeDatasetBasedOnStudyInfo(response); SendCFindResponse(presentationID, messageID, response, DcmStatus.Pending); } } } else if (queryLevel == "STUDY") { IQueryable<Study> studies = StudyQueries.GetMatchingStudies(database, query, _flagAnonymousAccess); studies = studies.Take(Settings.Default.MaxNumberOfStudiesReturned); foreach (var currentStudy in studies) { var p = currentStudy.Patient; var response = new DcmDataset { SpecificCharacterSetEncoding = query.SpecificCharacterSetEncoding }; // Map saved study tags to output response.AddElementWithValue(DicomTags.RetrieveAETitle, "CURAPACS"); response.AddElementWithValue(DicomTags.QueryRetrieveLevel, "STUDY"); response.AddElementWithValue(DicomTags.PatientID, p.ExternalPatientID); response.AddElementWithValue(DicomTags.PatientsName, p.LastName + "^" + p.FirstName); response.AddElementWithValue(DicomTags.PatientsBirthDate, p.BirthDateTime.Value); response.AddElementWithValue(DicomTags.StudyInstanceUID, currentStudy.StudyInstanceUid); response.AddElementWithValue(DicomTags.AccessionNumber, currentStudy.AccessionNumber); response.AddElementWithValue(DicomTags.StudyDescription, currentStudy.Description); response.AddElementWithValue(DicomTags.ModalitiesInStudy, currentStudy.ModalityAggregation); if (currentStudy.PerformedDateTime.HasValue) { response.AddElementWithValue(DicomTags.StudyDate, currentStudy.PerformedDateTime.Value); response.AddElementWithValue(DicomTags.StudyTime, currentStudy.PerformedDateTime.Value); } response.AddElementWithValue(DicomTags.NumberOfStudyRelatedSeries, currentStudy.Series.Count); response.AddElementWithValue(DicomTags.NumberOfStudyRelatedInstances, (from s in currentStudy.Series select s.Images.Count).Sum()); if (! String.IsNullOrEmpty(query.GetString(DicomTags.PatientsSex, null))) { response.AddElementWithValue(DicomTags.PatientsSex, Settings.Default.AlwaysRespondWithGender); } if(_flagAnonymousAccess) AnonymizeDatasetBasedOnStudyInfo(response); Trace.WriteLine("response (STUDY): > "); Trace.WriteLine(response.Dump()); SendCFindResponse(presentationID, messageID, response, DcmStatus.Pending); } } else if (queryLevel == "SERIES") { IQueryable<Series> series = SeriesQueries.GetMatchingSeries(database, query); foreach (var currentSeries in series) { var response = new DcmDataset { SpecificCharacterSetEncoding = query.SpecificCharacterSetEncoding }; if (currentSeries.PerformedDateTime.HasValue) { response.AddElementWithValue(DicomTags.SeriesDate, currentSeries.PerformedDateTime.Value); response.AddElementWithValue(DicomTags.SeriesTime, currentSeries.PerformedDateTime.Value); } response.AddElementWithValue(DicomTags.QueryRetrieveLevel, "SERIES"); response.AddElementWithValue(DicomTags.StudyInstanceUID, currentSeries.StudyInstanceUid); response.AddElementWithValue(DicomTags.SeriesInstanceUID, currentSeries.SeriesInstanceUid); response.AddElementWithValue(DicomTags.SeriesNumber, currentSeries.SeriesNumber); response.AddElementWithValue(DicomTags.SeriesDescription, currentSeries.Description); response.AddElementWithValue(DicomTags.Modality, currentSeries.PerformedModalityType); response.AddElementWithValue(DicomTags.NumberOfSeriesRelatedInstances, currentSeries.Images.Count()); response.AddElementWithValue(DicomTags.ReferringPhysiciansName, ""); response.AddElementWithValue(DicomTags.StudyCommentsRETIRED, ""); SendCFindResponse(presentationID, messageID, response, DcmStatus.Pending); } } SendCFindResponse(presentationID, messageID, DcmStatus.Success); } }
public DcmClientBase() : base() { _maxPdu = 32768; _priority = DcmPriority.High; _closedOnError = false; _closedEvent = new ManualResetEvent(false); _error = "No error"; }
protected override void OnReceiveCStoreRequest(byte presentationID, ushort messageID, DicomUID affectedInstance, DcmPriority priority, string moveAE, ushort moveMessageID, DcmDataset dataset, string fileName) { DcmStatus status = DcmStatus.Success; if (OnCStoreRequest != null) { status = OnCStoreRequest(this, presentationID, messageID, affectedInstance, priority, moveAE, moveMessageID, dataset, fileName); } SendCStoreResponse(presentationID, messageID, affectedInstance, status); }
protected virtual void OnReceiveCMoveRequest(byte presentationID, ushort messageID, string destinationAE, DcmPriority priority, DcmDataset dataset) { SendAbort(DcmAbortSource.ServiceProvider, DcmAbortReason.NotSpecified); }
protected virtual void OnReceiveCStoreRequest(byte presentationID, ushort messageID, DicomUID affectedInstance, DcmPriority priority, string moveAE, ushort moveMessageID, DcmDataset dataset, string fileName) { SendAbort(DcmAbortSource.ServiceProvider, DcmAbortReason.NotSpecified); }
protected virtual void OnPreReceiveCStoreRequest(byte presentationID, ushort messageID, DicomUID affectedInstance, DcmPriority priority, string moveAE, ushort moveMessageID, out string fileName) { if (UseFileBuffer) { fileName = Path.GetTempFileName(); } else { fileName = null; } }
protected virtual void OnReceiveCEchoRequest(byte presentationID, ushort messageID, DcmPriority priority) { SendAbort(DcmAbortSource.ServiceProvider, DcmAbortReason.NotSpecified); }
protected override void OnReceiveCFindRequest(byte presentationID, ushort messageID, DcmPriority priority, DcmDataset dataset) { DcmStatus status = DcmStatus.QueryRetrieveUnableToProcess; DcmDataset resultDataset = null; if (OnCFindRequest != null) { status = OnCFindRequest(this, presentationID, messageID, priority, dataset); } SendCFindResponse(presentationID, messageID, resultDataset, status); }
private DcmCommand CreateRequest(ushort messageID, DcmCommandField commandField, DicomUID affectedClass, DcmPriority priority, bool hasDataset) { DcmCommand command = new DcmCommand(); command.AffectedSOPClassUID = affectedClass; command.CommandField = commandField; command.MessageID = messageID; command.Priority = priority; command.HasDataset = hasDataset; return command; }
protected override void OnReceiveCStoreRequest(byte presentationID, ushort messageID, DicomUID affectedInstance, DcmPriority priority, string moveAE, ushort moveMessageID, DcmDataset dataset, string fileName) { Trace.WriteLine(String.Format("{0} Receive C-Store from {1} ", DateTime.Now, this.Associate.CallingAE)); DcmStatus status = DcmStatus.Success; IsReceiveConnection = true; SendCStoreResponse(presentationID, messageID, affectedInstance, status); }
/// <summary> /// The C-STORE service is used by a DIMSE-service-user to store a composite /// SOP Instance on a peer DIMSE-service-user. It is a confirmed service. /// </summary> /// <param name="presentationID">The Presentation Context ID identifies the /// Presentation Context within the scope of a specific Association.</param> /// <param name="messageID">This parameter identifies the operation. It is used /// to distinguish this operation from other notifications or operations that /// the DIMSE-service-provider may have in progress. No two identical values /// for the Message ID (0000,0110) shall be used for outstanding operations or /// notifications.</param> /// <param name="affectedInstance">For the request/indication, this parameter /// specifies the SOP Instance to be stored. It may be included in the /// response/confirmation. If included in the response/confirmation, this /// parameter shall be equal to the value in the request/indication.</param> /// <param name="priority">This parameter specifies the priority of the /// C-STORE operation. It shall be one of LOW, MEDIUM, or HIGH.</param> /// <param name="datastream">The Data Set accompanying the C-STORE primitive /// contains the Attributes of the Composite SOP Instance to be stored.</param> protected void SendCStoreRequest(byte presentationID, ushort messageID, DicomUID affectedInstance, DcmPriority priority, Stream datastream) { SendCStoreRequest(presentationID, messageID, affectedInstance, priority, null, 0, datastream); }
protected override void OnReceiveCStoreRequest(byte presentationID, ushort messageID, DicomUID affectedInstance, DcmPriority priority, string moveAE, ushort moveMessageID, DcmDataset dataset, string fileName) { DcmStatus status = DcmStatus.Success; if (OnCStoreRequest != null) status = OnCStoreRequest(this, presentationID, messageID, affectedInstance, priority, moveAE, moveMessageID, dataset, fileName); SendCStoreResponse(presentationID, messageID, affectedInstance, status); }
protected override void OnReceiveCEchoRequest(byte presentationID, ushort messageID, DcmPriority priority) { SendCEchoResponse(presentationID, messageID, DcmStatus.Success); }
protected override void OnReceiveCEchoRequest(byte presentationID, ushort messageID, DcmPriority priority) { DcmStatus status = DcmStatus.Success; if (OnCEchoRequest != null) status = OnCEchoRequest(this, presentationID, messageID, priority); SendCEchoResponse(presentationID, messageID, status); }
protected override void OnReceiveCMoveRequest(byte presentationID, ushort messageID, string destinationAE, DcmPriority priority, DcmDataset dataset) { DcmStatus status = DcmStatus.QueryRetrieveUnableToProcess; ushort remain = 0; ushort complete = 0; ushort warning = 0; ushort failure = 0; if (OnCMoveRequest != null) { status = OnCMoveRequest(this, presentationID, messageID, destinationAE, priority, dataset, out remain, out complete, out warning, out failure); } SendCMoveResponse(presentationID, messageID, status, remain, complete, warning, failure); }
protected void SendCEchoRequest(byte presentationID, ushort messageID, DcmPriority priority) { DicomUID affectedClass = Associate.GetAbstractSyntax(presentationID); DcmCommand command = CreateRequest(messageID, DcmCommandField.CEchoRequest, affectedClass, priority, false); Log.Info("{0} -> C-Echo request [pc: {1}; id: {2}]", LogID, presentationID, messageID); SendDimse(presentationID, command, null); }
protected override void OnReceiveCEchoRequest(byte presentationID, ushort messageID, DcmPriority priority) { DcmStatus status = DcmStatus.Success; if (OnCEchoRequest != null) { status = OnCEchoRequest(this, presentationID, messageID, priority); } SendCEchoResponse(presentationID, messageID, status); }
protected void SendCMoveRequest(byte presentationID, ushort messageID, string destinationAE, DcmPriority priority, DcmDataset dataset) { String level = dataset.GetString(DicomTags.QueryRetrieveLevel, "UNKNOWN"); DicomUID affectedClass = Associate.GetAbstractSyntax(presentationID); DcmCommand command = CreateRequest(messageID, DcmCommandField.CMoveRequest, affectedClass, priority, true); command.MoveDestinationAE = destinationAE; Log.Info("{0} -> C-Move request [pc: {1}; id: {2}; lvl: {3}; dest: {4}]", LogID, presentationID, messageID, level, destinationAE); SendDimse(presentationID, command, dataset); }
/// <summary> /// The C-STORE service is used by a DIMSE-service-user to store a composite /// SOP Instance on a peer DIMSE-service-user. It is a confirmed service. /// </summary> /// <param name="presentationID">The Presentation Context ID identifies the /// Presentation Context within the scope of a specific Association.</param> /// <param name="messageID">This parameter identifies the operation. It is used /// to distinguish this operation from other notifications or operations that /// the DIMSE-service-provider may have in progress. No two identical values /// for the Message ID (0000,0110) shall be used for outstanding operations or /// notifications.</param> /// <param name="affectedInstance">For the request/indication, this parameter /// specifies the SOP Instance to be stored. It may be included in the /// response/confirmation. If included in the response/confirmation, this /// parameter shall be equal to the value in the request/indication.</param> /// <param name="priority">This parameter specifies the priority of the /// C-STORE operation. It shall be one of LOW, MEDIUM, or HIGH.</param> /// <param name="moveAE">This parameter specifies the DICOM AE Title of the /// DICOM AE which invoked the C-MOVE operation from which this C-STORE /// sub-operation is being performed.</param> /// <param name="moveMessageID">This parameter specifies the Message ID (0000,0110) /// of the C-MOVE request/indication primitive from which this C-STORE /// sub-operation is being performed.</param> /// <param name="datastream">The Data Set accompanying the C-STORE primitive /// contains the Attributes of the Composite SOP Instance to be stored.</param> protected void SendCStoreRequest(byte presentationID, ushort messageID, DicomUID affectedInstance, DcmPriority priority, string moveAE, ushort moveMessageID, Stream datastream) { DicomUID affectedClass = Associate.GetAbstractSyntax(presentationID); DcmCommand command = CreateRequest(messageID, DcmCommandField.CStoreRequest, affectedClass, priority, true); command.AffectedSOPInstanceUID = affectedInstance; if (moveAE != null && moveAE != String.Empty) { command.MoveOriginatorAE = moveAE; command.MoveOriginatorMessageID = moveMessageID; } Log.Info("{0} -> C-Store request [pc: {1}; id: {2}] (stream)\n\t=> {3}\n\t=> {4}", LogID, presentationID, messageID, affectedInstance, affectedClass); SendDimseStream(presentationID, command, datastream); }