public override bool OnReceiveRequest(DicomServer server,
                                              ServerAssociationParameters association,
                                              byte presentationID, DicomMessage message)
        {
            try
            {
                var import = new SopInstanceImporter(new SopInstanceImporterContext(
                                                         "", association.CallingAE, Partition));
                import.Import(message);

                server.SendCStoreResponse(presentationID, message.MessageId,
                    message.AffectedSopInstanceUid, DicomStatuses.Success);
            }
            catch (DicomDataException ex)
            {
                Platform.Log(LogLevel.Error, ex);
                return false; // caller will abort the association
            }
            catch (Exception ex)
            {
                Platform.Log(LogLevel.Error, ex);
                return false; // caller will abort the association
            }

            return true;
        }
Beispiel #2
0
        public override bool OnReceiveRequest(DicomServer server, ServerAssociationParameters association,
                                              byte presentationID, DicomMessage message)
        {
            server.SendCEchoResponse(presentationID, message.MessageId, DicomStatuses.Success);

            return true;
        }
Beispiel #3
0
        public override bool OnReceiveRequest(DicomServer server, ServerAssociationParameters association,
            byte presentationId, DicomMessage message)
        {
            string level = message.DataSet[DicomTags.QueryRetrieveLevel].GetString(0, string.Empty);

            if (message.CommandField == DicomCommandField.CCancelRequest)
            {
                Platform.Log(LogLevel.Info, "Received C-FIND-CANCEL-RQ message.");
                _cancelReceived = true;
                return true;
            }

            if (message.AffectedSopClassUid.Equals(SopClass.StudyRootQueryRetrieveInformationModelFindUid))
            {
                switch (level)
                {
                    case "STUDY":
                        // We use the ThreadPool to process the thread requests. This is so that we return back
                        // to the main message loop, and continue to look for cancel request messages coming
                        // in.  There's a small chance this may cause delays in responding to query requests if
                        // the .NET Thread pool fills up.
                        ThreadPool.QueueUserWorkItem(delegate
                        {
                            try
                            {
                                OnReceiveStudyLevelQuery(server, presentationId, message);
                            }
                            catch (Exception x)
                            {
                                Platform.Log(LogLevel.Error, x, "Unexpected exception in OnReceiveStudyLevelQuery.");
                            }
                        });
                        return true;

                    case "SERIES":
                        ThreadPool.QueueUserWorkItem(delegate
                        {
                            try
                            {
                                OnReceiveSeriesLevelQuery(server, presentationId, message);
                            }
                            catch (Exception x)
                            {
                                Platform.Log(LogLevel.Error, x,
                                             "Unexpected exception in OnReceiveSeriesLevelQuery.");
                            }
                        });
                        return true;

                    case "IMAGE":
                        ThreadPool.QueueUserWorkItem(delegate
                        {
                            try
                            {
                                OnReceiveImageLevelQuery(server, presentationId, message);
                            }
                            catch (Exception x)
                            {
                                Platform.Log(LogLevel.Error, x,
                                             "Unexpected exception in OnReceiveImageLevelQuery.");
                            }
                        });
                        return true;

                    default:
                        {
                            Platform.Log(LogLevel.Error, "Unexpected Study Root Query/Retrieve level: {0}", level);

                            server.SendCFindResponse(presentationId, message.MessageId, new DicomMessage(),
                                                     DicomStatuses.QueryRetrieveIdentifierDoesNotMatchSOPClass);
                            return true;
                        }
                }
            }

            if (message.AffectedSopClassUid.Equals(SopClass.PatientRootQueryRetrieveInformationModelFindUid))
            {
                switch (level)
                {
                    case "PATIENT":
                        ThreadPool.QueueUserWorkItem(delegate
                        {
                            try
                            {
                                OnReceivePatientQuery(server, presentationId, message);
                            }
                            catch (Exception x)
                            {
                                Platform.Log(LogLevel.Error, x,
                                             "Unexpected exception in OnReceivePatientQuery.");
                            }
                        });

                        return true;
                    case "STUDY":
                        ThreadPool.QueueUserWorkItem(delegate
                                                    {
                                                        try
                                                        {
                                                            OnReceiveStudyLevelQuery(server, presentationId, message);
                                                        }
                                                        catch (Exception x)
                                                        {
                                                            Platform.Log(LogLevel.Error, x,
                                                                         "Unexpected exception in OnReceiveStudyLevelQuery.");
                                                        }
                                                    });
                        return true;
                    case "SERIES":
                        ThreadPool.QueueUserWorkItem(delegate
                                                    {
                                                        try
                                                        {
                                                            OnReceiveSeriesLevelQuery(server, presentationId, message);
                                                        }
                                                        catch (Exception x)
                                                        {
                                                            Platform.Log(LogLevel.Error, x,
                                                                         "Unexpected exception in OnReceiveSeriesLevelQuery.");
                                                        }
                                                    });
                        return true;
                    case "IMAGE":
                        ThreadPool.QueueUserWorkItem(delegate
                                                     {
                                                         try
                                                         {
                                                             OnReceiveImageLevelQuery(server, presentationId, message);
                                                         }
                                                         catch (Exception x)
                                                         {
                                                             Platform.Log(LogLevel.Error, x,
                                                                          "Unexpected exception in OnReceiveImageLevelQuery.");
                                                         }
                                                     });
                        return true;

                    default:
                        {
                            Platform.Log(LogLevel.Error, "Unexpected Patient Root Query/Retrieve level: {0}", level);

                            server.SendCFindResponse(presentationId, message.MessageId, new DicomMessage(),
                                                     DicomStatuses.QueryRetrieveIdentifierDoesNotMatchSOPClass);
                            return true;
                        }
                }
            }

            // no supported message type, send a failure status 
            server.SendCFindResponse(presentationId, message.MessageId, new DicomMessage(),
                DicomStatuses.QueryRetrieveIdentifierDoesNotMatchSOPClass);

            return true;

        }
Beispiel #4
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 (!string.IsNullOrEmpty(message.ErrorComment))
                FailureDescription = message.ErrorComment;

        	if (message.Status.Status == DicomState.Pending)
        	{
        		OnImageMoveCompleted();
        	}
        	else
        	{
				DicomStatus status = DicomStatuses.LookupQueryRetrieve(message.Status.Code);
				if (message.Status.Status != DicomState.Success)
				{
					if (status.Status == DicomState.Cancel)
					{
                        if (LogInformation) Platform.Log(LogLevel.Info, "Cancel status received in Move Scu: {0}", status);
						Status = ScuOperationStatus.Canceled;
					}
                    else if (status.Status == DicomState.Failure)
					{
                        Platform.Log(LogLevel.Error, "Failure status received in Move Scu: {0}", status);
						Status = ScuOperationStatus.Failed;
						FailureDescription = status.ToString();
					}
                    else if (status.Status == DicomState.Warning)
					{
                        Platform.Log(LogLevel.Warn, "Warning status received in Move Scu: {0}", 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();
			}
        }
        public bool Import(DicomMessage dicomMessage)
        {
            if (dicomMessage.DataSet == null)
            {
                throw new ArgumentException();
            }

            var patient = new Patient
            {
                PatientId = dicomMessage.DataSet[DicomTags.PatientId].GetString(0, string.Empty),
                PatientName = dicomMessage.DataSet[DicomTags.PatientsName].GetString(0, string.Empty),
                PatientBirthDate = dicomMessage.DataSet[DicomTags.PatientsBirthDate].GetString(0, string.Empty),
                Issuer = dicomMessage.DataSet[DicomTags.IssuerOfPatientId].GetString(0, string.Empty),
            };

            var study = new Study()
            {
                StudyId = dicomMessage.DataSet[DicomTags.StudyId].GetString(0, string.Empty),
                StudyUid = dicomMessage.DataSet[DicomTags.StudyInstanceUid].GetString(0, string.Empty),
                AccessionNumber = dicomMessage.DataSet[DicomTags.AccessionNumber].GetString(0, string.Empty),
                StudyDate = dicomMessage.DataSet[DicomTags.StudyDate].GetString(0, string.Empty),
                StudyTime = dicomMessage.DataSet[DicomTags.StudyTime].GetString(0, string.Empty),
                RefPhysician = dicomMessage.DataSet[DicomTags.ReferringPhysiciansName].GetString(0, string.Empty),
                StudyDescription = dicomMessage.DataSet[DicomTags.StudyDescription].GetString(0, string.Empty),

                PatientId = patient.PatientId,
                PatientName = patient.PatientName,
                PatientBirthday = patient.PatientBirthDate,
                PatientAge = dicomMessage.DataSet[DicomTags.PatientsAge].GetString(0, string.Empty),
                PatientSize = dicomMessage.DataSet[DicomTags.PatientsSize].GetString(0, string.Empty),
                PatientWeight = dicomMessage.DataSet[DicomTags.PatientsWeight].GetString(0, string.Empty),
                PatientSex = dicomMessage.DataSet[DicomTags.PatientsSex].GetString(0, string.Empty)
            };

            var series = new Series()
            {
                SeriesUid = dicomMessage.DataSet[DicomTags.SeriesInstanceUid].GetString(0, string.Empty),
                SeriesNumber = dicomMessage.DataSet[DicomTags.SeriesNumber].GetString(0, string.Empty),
                Modality = dicomMessage.DataSet[DicomTags.Modality].GetString(0, string.Empty),
                BodyPart = dicomMessage.DataSet[DicomTags.BodyPartExamined].GetString(0, string.Empty),
                Institution = dicomMessage.DataSet[DicomTags.InstitutionName].GetString(0, string.Empty),
                StationName = dicomMessage.DataSet[DicomTags.StationName].GetString(0, string.Empty),
                Department = dicomMessage.DataSet[DicomTags.InstitutionalDepartmentName].GetString(0, string.Empty),
                PerfPhysician = dicomMessage.DataSet[DicomTags.PerformingPhysiciansName].GetString(0, string.Empty),
                SeriesDate = dicomMessage.DataSet[DicomTags.SeriesDate].GetString(0, string.Empty),
                SeriesTime = dicomMessage.DataSet[DicomTags.SeriesTime].GetString(0, string.Empty),
                SeriesDescription = dicomMessage.DataSet[DicomTags.SeriesDescription].GetString(0, string.Empty),
                PerformedProcedureStepStartDate = dicomMessage.DataSet[DicomTags.PerformedProcedureStepStartDate].GetString(0, string.Empty),
                PerformedProcedureStepStartTime = dicomMessage.DataSet[DicomTags.PerformedProcedureStepStartTime].GetString(0, string.Empty),
            };

            var instance = new Instance()
            {
                SopInstanceUid = dicomMessage.DataSet[DicomTags.SopInstanceUid].GetString(0, string.Empty),
                SopClassUid = dicomMessage.DataSet[DicomTags.SopClassUid].GetString(0, string.Empty),
                InstanceNumber = dicomMessage.DataSet[DicomTags.InstanceNumber].GetString(0, string.Empty),
                ContentDate = dicomMessage.DataSet[DicomTags.ContentDate].GetString(0, string.Empty),
                ContentTime = dicomMessage.DataSet[DicomTags.ContentTime].GetString(0, string.Empty)
            };

            if (string.IsNullOrEmpty(study.StudyUid)
                || string.IsNullOrEmpty(series.SeriesUid)
                || string.IsNullOrEmpty(instance.SopInstanceUid))
            {
                throw new ArgumentException();
            }

            // Get Patient Db Object 
            using (var context = new PacsContext())
            {
                Patient dbPatient = null;

                var dbStudy = InsertStudy(context, study, patient, out dbPatient);

                // Patient and study is exist in db now
                var dbSeries = InsertSeries(context, series, dbStudy, dbPatient);

                // insert instance 
                var dbInstance = InsertImage(context, instance, dbSeries, dbStudy, dbPatient);

                var dbFile = InsertFile(context, dbInstance, dbSeries, dbStudy, dbPatient);

                var dicomFile = new DicomFile(dicomMessage, dbFile.FilePath);
                
                if (!Directory.Exists(Path.GetDirectoryName(dbFile.FilePath)))
                {
                    Directory.CreateDirectory(Path.GetDirectoryName(dbFile.FilePath));
                }

                dicomFile.Save();

                context.SaveChanges();
            }

            return true;
        }
Beispiel #6
0
        private void OnReceiveMWLQuery(DicomServer server, byte presentationId, DicomMessage message)
        {
            var tagList = new List<DicomTag>();

            string specificCharacterSet = string.Empty;

            foreach (var attrib in message.DataSet)
            {
                tagList.Add(attrib.Tag);

                if (!attrib.IsNull)
                {
                    switch (attrib.Tag.TagValue)
                    {
                        case DicomTags.SpecificCharacterSet:
                            specificCharacterSet = message.DataSet[DicomTags.SpecificCharacterSet];
                            break;

                        #region Case Scheduled Procedure Step Seq

                        case DicomTags.ScheduledProcedureStepSequence:
                            DicomAttributeSQ sequence = attrib as DicomAttributeSQ;
                            DicomSequenceItem sqSubItems = sequence[0];

                            foreach (var sqSubItem in sqSubItems)
                            {
                                if(sqSubItem.IsNull)
                                    continue;

                                tagList.Add(sqSubItem.Tag);

                                switch (sqSubItem.Tag.TagValue)
                                {
                                    case DicomTags.ScheduledStationName:
                                        break;
                                    case DicomTags.Modality:
                                        break;
                                    case DicomTags.ScheduledPerformingPhysiciansName:
                                        break;
                                    case DicomTags.ScheduledProcedureStepStartDate:
                                        break;
                                    case DicomTags.ScheduledProcedureStepStartTime:
                                        break;

                                    // Optional Matching keys
                                    case DicomTags.ScheduledProcedureStepLocation:
                                        break;
                                    case DicomTags.ScheduledProcedureStepDescription:
                                        break;
                                    case DicomTags.RequestedProcedureId:
                                        break;
                                    case DicomTags.ScheduledProcedureStepId:
                                        break;
                                    default:
                                        break;
                                }
                            }
                            break;

                        #endregion

                        case DicomTags.PatientId:
                            break;
                        case DicomTags.PatientsName:
                            break;

                        //Optional Matching Keys
                        case DicomTags.AccessionNumber:
                            break;

                        case DicomTags.ReferringPhysiciansName:
                            break;
                        default:
                            break;
                    }
                }
            }

            // Populate result Information from Db
            List<DicomMessage> results = new List<DicomMessage>();

            var msg = new DicomMessage();
            msg.DataSet.SpecificCharacterSet = specificCharacterSet;
            ModalityWorklistIod iod = new ModalityWorklistIod(msg.DataSet);
            iod.SetCommonTags();

            iod.PatientIdentificationModule.PatientId = "1402001111";
            iod.PatientIdentificationModule.PatientsName = new PersonName("测试");
            iod.PatientIdentificationModule.PatientsSex = PatientsSex.M;
            iod.PatientIdentificationModule.PatientsBirthDate = new DateTime(2011, 11, 19);

            var spssIod = new ScheduledProcedureStepSequenceIod();
            spssIod.SetCommonTags();
            spssIod.DicomAttributeProvider[DicomTags.ScheduledProcedureStepStartDate].SetString(0, "20141119");
            spssIod.DicomAttributeProvider[DicomTags.ScheduledProcedureStepStartTime].SetString(0, "143806");

            iod.ScheduledProcedureStepModule.ScheduledProcedureStepSequenceList.Clear();
            iod.ScheduledProcedureStepModule.ScheduledProcedureStepSequenceList.Add(spssIod);

          results.Add(msg);
            try
            {
                foreach (var dicomMessage in results)
                {
                    if (_cancelReceived)
                    {
                        throw new DicomException("DICOM C-Cancel Received");
                    }
                    
                    server.SendCFindResponse(presentationId, message.MessageId, dicomMessage,
                                                         DicomStatuses.Pending);
                }
                
            }
            catch (Exception)
            {
                if (_cancelReceived)
                {
                    var errorResponse = new DicomMessage();
                    server.SendCFindResponse(presentationId, message.MessageId, errorResponse,
                                                DicomStatuses.Cancel);
                }

                return;
            }

            var finalResponse = new DicomMessage();
            server.SendCFindResponse(presentationId, message.MessageId, finalResponse, DicomStatuses.Success);
        }
Beispiel #7
0
        private bool GetSopListForInstance(PacsContext ctx, DicomMessage message, out string errorComment)
        {
            errorComment = string.Empty;

            string studyInstanceUid = message.DataSet[DicomTags.StudyInstanceUid].GetString(0, "");
            string seriesInstanceUid = message.DataSet[DicomTags.SeriesInstanceUid].GetString(0, "");
            var sopInstanceUidArray = (string[])message.DataSet[DicomTags.SopInstanceUid].Values;

            var sopPkArray =
                (from s in ctx.Instances where sopInstanceUidArray.Contains(s.SopInstanceUid) select s.Id).ToList();

            var fileList =
                (from f in ctx.Files where sopPkArray.Contains(f.InstanceFk) select f).ToList();

            foreach (var file in fileList)
            {
                _theScu.AddStorageInstance(new StorageInstance(file.FilePath));
            }

            return true;
        }
Beispiel #8
0
        private bool GetSopListForStudy(PacsContext ctx, DicomMessage message, out string errorComment)
        {
            errorComment = string.Empty;

            var studyUidList = (string[])message.DataSet[DicomTags.StudyInstanceUid].Values;

            var studyList = (from s in ctx.Studies where studyUidList.Contains(s.StudyUid) select s).ToList();

            foreach (var study in studyList)
            {
                var seriesPkList = (from s in ctx.Series where study.Id == s.StudyForeignKey select s.Id).ToList();

                var sopList = (from s in ctx.Instances where seriesPkList.Contains(s.SeriesForeignKey) select s.Id).ToList();

                var fileList = (from f in ctx.Files where sopList.Contains(f.InstanceFk) select f).ToList();

                foreach (var file in fileList)
                {
                    _theScu.AddStorageInstance(new StorageInstance(file.FilePath));
                }
            }

            return true;
        }
Beispiel #9
0
        private void PopuldateInstance(DicomMessageBase request, DicomMessage response, IEnumerable<DicomTag> tagList,
            Instance row)
        {
            DicomAttributeCollection dataSet = response.DataSet;

            dataSet[DicomTags.RetrieveAeTitle].SetStringValue(base.Partition.AeTitle);
            dataSet[DicomTags.InstanceAvailability].SetStringValue("ONLINE");

            // character set
            var characterSet = GetPreferredCharacterSet();
            if (!string.IsNullOrEmpty(characterSet))
            {
                dataSet[DicomTags.SpecificCharacterSet].SetStringValue(characterSet);
                dataSet.SpecificCharacterSet = characterSet;
            }

            foreach (DicomTag tag in tagList)
            {
                try
                {
                    switch (tag.TagValue)
                    {
                        case DicomTags.PatientId:
                            dataSet[DicomTags.PatientId].SetStringValue(request.DataSet[DicomTags.PatientId].ToString());
                            break;
                        case DicomTags.StudyInstanceUid:
                            dataSet[DicomTags.StudyInstanceUid].SetStringValue(
                                request.DataSet[DicomTags.StudyInstanceUid].ToString());
                            break;
                        case DicomTags.SeriesInstanceUid:
                            dataSet[DicomTags.SeriesInstanceUid].SetStringValue(
                                request.DataSet[DicomTags.SeriesInstanceUid].ToString());
                            break;
                        case DicomTags.QueryRetrieveLevel:
                            dataSet[DicomTags.QueryRetrieveLevel].SetStringValue("IMAGE");
                            break;
                        case DicomTags.SopInstanceUid:
                            dataSet[DicomTags.SopInstanceUid].SetStringValue(row.SopInstanceUid);
                            break;
                        case DicomTags.SopClassUid:
                            dataSet[DicomTags.SopClassUid].SetStringValue(row.SopClassUid);
                            break;
                        case DicomTags.InstanceNumber:
                            dataSet[DicomTags.InstanceNumber].SetStringValue(row.InstanceNumber);
                            break;
                        // Meta tags that should have not been in the RQ, but we've already set
                        case DicomTags.RetrieveAeTitle:
                        case DicomTags.InstanceAvailability:
                        case DicomTags.SpecificCharacterSet:
                            break;
                        default:
                            //if (sourceDataSet.Contains(tag))
                            //    dataSet[tag] = sourceDataSet[tag].Copy();
                            //else if (!tag.IsPrivate)
                            //    dataSet[tag].SetNullValue();
                            break;
                    }
                }
                catch (Exception e)
                {
                    Platform.Log(LogLevel.Warn, e, "Unexpected error setting tag {0} in C-FIND-RSP",
                                 dataSet[tag].Tag.ToString());
                    if (!tag.IsPrivate)
                        dataSet[tag].SetNullValue();
                }
            }
        }
Beispiel #10
0
        private void PopulateSeries(DicomMessageBase request, DicomMessage response,
            IEnumerable<DicomTag> tagList, Series row)
        {
            DicomAttributeCollection dataSet = response.DataSet;

            dataSet[DicomTags.RetrieveAeTitle].SetStringValue(base.Partition.AeTitle);
            dataSet[DicomTags.InstanceAvailability].SetStringValue("ONLINE");

            // character set
            var characterSet = GetPreferredCharacterSet();
            if (!string.IsNullOrEmpty(characterSet))
            {
                dataSet[DicomTags.SpecificCharacterSet].SetStringValue(characterSet);
                dataSet.SpecificCharacterSet = characterSet;
            }

            foreach (DicomTag tag in tagList)
            {
                try
                {
                    switch (tag.TagValue)
                    {
                        case DicomTags.PatientId:
                            dataSet[DicomTags.PatientId].SetStringValue(request.DataSet[DicomTags.PatientId].ToString());
                            break;
                        case DicomTags.StudyInstanceUid:
                            dataSet[DicomTags.StudyInstanceUid].SetStringValue(
                                request.DataSet[DicomTags.StudyInstanceUid].ToString());
                            break;
                        case DicomTags.SeriesInstanceUid:
                            dataSet[DicomTags.SeriesInstanceUid].SetStringValue(row.SeriesUid);
                            break;
                        case DicomTags.Modality:
                            dataSet[DicomTags.Modality].SetStringValue(row.Modality);
                            break;
                        case DicomTags.SeriesNumber:
                            dataSet[DicomTags.SeriesNumber].SetStringValue(row.SeriesNumber);
                            break;
                        case DicomTags.SeriesDescription:
                            dataSet[DicomTags.SeriesDescription].SetStringValue(row.SeriesDescription);
                            break;
                        case DicomTags.PerformedProcedureStepStartDate:
                            dataSet[DicomTags.PerformedProcedureStepStartDate].SetStringValue(
                                row.PerformedProcedureStepStartDate);
                            break;
                        case DicomTags.PerformedProcedureStepStartTime:
                            dataSet[DicomTags.PerformedProcedureStepStartTime].SetStringValue(
                                row.PerformedProcedureStepStartTime);
                            break;
                        case DicomTags.NumberOfSeriesRelatedInstances:
                            dataSet[DicomTags.NumberOfSeriesRelatedInstances].AppendInt32(row.NumberOfRelatedImage);
                            break;
                        case DicomTags.RequestAttributesSequence:
                            //LoadRequestAttributes(read, response, row);
                            break;
                        case DicomTags.QueryRetrieveLevel:
                            dataSet[DicomTags.QueryRetrieveLevel].SetStringValue("SERIES");
                            break;
                        // Meta tags that should have not been in the RQ, but we've already set
                        case DicomTags.RetrieveAeTitle:
                        case DicomTags.InstanceAvailability:
                        case DicomTags.SpecificCharacterSet:
                            break;
                        default:
                            if (!tag.IsPrivate)
                                dataSet[tag].SetNullValue();

                            break;
                    }
                }
                catch (Exception e)
                {
                    Platform.Log(LogLevel.Warn, e, "Unexpected error setting tag {0} in C-FIND-RSP",
                                 dataSet[tag].Tag.ToString());
                    if (!tag.IsPrivate)
                        dataSet[tag].SetNullValue();
                }
            }
        }
Beispiel #11
0
        private void PopulateStudy(DicomMessage response, IEnumerable<DicomTag> tagList, Study row)
        {
            DicomAttributeCollection dataSet = response.DataSet;

            dataSet[DicomTags.RetrieveAeTitle].SetStringValue(base.Partition.AeTitle);
            dataSet[DicomTags.InstanceAvailability].SetStringValue("ONLINE");

            // character set
            var characterSet = GetPreferredCharacterSet();
            if (!string.IsNullOrEmpty(characterSet))
            {
                dataSet[DicomTags.SpecificCharacterSet].SetStringValue(characterSet);
                dataSet.SpecificCharacterSet = characterSet;
            }

            foreach (DicomTag tag in tagList)
            {
                try
                {
                    switch (tag.TagValue)
                    {
                        case DicomTags.StudyInstanceUid:
                            dataSet[DicomTags.StudyInstanceUid].SetStringValue(row.StudyUid);
                            break;
                        case DicomTags.PatientsName:
                            dataSet[DicomTags.PatientsName].SetStringValue(row.Patient.PatientName);
                            break;
                        case DicomTags.PatientId:
                            dataSet[DicomTags.PatientId].SetStringValue(row.Patient.PatientId);
                            break;
                        case DicomTags.PatientsSex:
                            dataSet[DicomTags.PatientsSex].SetStringValue(row.PatientSex);
                            break;
                        case DicomTags.PatientsAge:
                            dataSet[DicomTags.PatientsAge].SetStringValue(row.PatientAge);
                            break;
                        case DicomTags.PatientsBirthDate:
                            dataSet[DicomTags.PatientsBirthDate].SetStringValue(row.Patient.PatientBirthDate);
                            break;
                        case DicomTags.StudyDate:
                            dataSet[DicomTags.StudyDate].SetStringValue(row.StudyDate);
                            break;
                        case DicomTags.StudyTime:
                            dataSet[DicomTags.StudyTime].SetStringValue(row.StudyTime);
                            break;
                        case DicomTags.AccessionNumber:
                            dataSet[DicomTags.AccessionNumber].SetStringValue(row.AccessionNumber);
                            break;
                        case DicomTags.StudyId:
                            dataSet[DicomTags.StudyId].SetStringValue(row.StudyId);
                            break;
                        case DicomTags.StudyDescription:
                            dataSet[DicomTags.StudyDescription].SetStringValue(row.StudyDescription);
                            break;
                        case DicomTags.ReferringPhysiciansName:
                            dataSet[DicomTags.ReferringPhysiciansName].SetStringValue(row.RefPhysician);
                            break;
                        case DicomTags.NumberOfStudyRelatedSeries:
                            dataSet[DicomTags.NumberOfStudyRelatedSeries].AppendInt32(row.NumberOfRelatedSeries);
                            break;
                        case DicomTags.NumberOfStudyRelatedInstances:
                            dataSet[DicomTags.NumberOfStudyRelatedInstances].AppendInt32(row.NumberOfRelatedImage);
                            break;
                        case DicomTags.ModalitiesInStudy:
                            break;

                        case DicomTags.QueryRetrieveLevel:
                            dataSet[DicomTags.QueryRetrieveLevel].SetStringValue("STUDY");
                            break;

                        // Meta tags that should have not been in the RQ, but we've already set
                        case DicomTags.RetrieveAeTitle:
                        case DicomTags.InstanceAvailability:
                        case DicomTags.SpecificCharacterSet:
                            break;

                        default:
                            if (!tag.IsPrivate)
                                dataSet[tag].SetNullValue();
                            break;
                    }
                }
                catch (Exception e)
                {
                    Platform.Log(LogLevel.Warn, e, "Unexpected error setting tag {0} in C-FIND-RSP",
                                 dataSet[tag].Tag.ToString());
                    if (!tag.IsPrivate)
                        dataSet[tag].SetNullValue();
                }
            }
        }
Beispiel #12
0
        public override bool OnReceiveRequest(DicomServer server, ServerAssociationParameters association,
                                             byte presentationID, DicomMessage message)
        {
            #region MPPS NCreate Request

            if (message.CommandField == DicomCommandField.NCreateRequest)
            {
                ModalityPerformedProcedureStepIod mppsIod = new ModalityPerformedProcedureStepIod(message.DataSet);
                bool conform = CheckNCreateDataSetConformance(server, association, presentationID, mppsIod, true);

                if (!conform)
                {
                    server.SendNCreateResponse(presentationID, message.MessageId, new DicomMessage(), DicomStatuses.InvalidAttributeValue);
                    Platform.Log(LogLevel.Error, "Sending Invalid Attributes Response.");
                    return true;
                }

                // wrong status
                if (mppsIod.PerformedProcedureStepInformation.PerformedProcedureStepStatus != PerformedProcedureStepStatus.InProgress)
                {
                    server.SendNCreateResponse(presentationID, message.MessageId, new DicomMessage(), DicomStatuses.InvalidAttributeValue);
                    Platform.Log(LogLevel.Error, "Received N-Create Request with bad status.");
                    return true;
                }

                if (!ProcessNCreateRequest(server, presentationID, message))
                {
                    server.SendNCreateResponse(presentationID, message.MessageId, new DicomMessage(), DicomStatuses.ProcessingFailure);
                    return true;
                }

                server.SendNCreateResponse(presentationID, message.MessageId, new DicomMessage(), DicomStatuses.Success);

            }

            #endregion

            #region MPPS NSet Request

            if (message.CommandField == DicomCommandField.NSetRequest)
            {
                ModalityPerformedProcedureStepIod mppsIod = new ModalityPerformedProcedureStepIod(message.DataSet);

                string studyInstanceUID = mppsIod.
                                          PerformedProcedureStepRelationship.
                                          DicomAttributeProvider[DicomTags.StudyInstanceUid].
                                          GetString(0, "");

                // Get Cached 
                ModalityPerformedProcedureStepIod cachedMppsIod = new ModalityPerformedProcedureStepIod();
                bool conform = CheckNSetDataSetConformance(server, association, presentationID, cachedMppsIod, mppsIod, true);

                if (!conform)
                {
                    server.SendNCreateResponse(presentationID, message.MessageId, new DicomMessage(), DicomStatuses.InvalidAttributeValue);
                    Platform.Log(LogLevel.Error, "Sending Failure Response.");
                    return true;
                }

                bool success = true;
                if (mppsIod.PerformedProcedureStepInformation.PerformedProcedureStepStatus
                            == PerformedProcedureStepStatus.Completed)
                {
                    success = ProcessNSetRequestForCompleted(server, presentationID, message);
                }

                if (mppsIod.PerformedProcedureStepInformation.PerformedProcedureStepStatus
                            == PerformedProcedureStepStatus.Discontinued)
                {
                    success = ProcessNSetRequestForDiscontinued(server, presentationID, message);
                }
                
                server.SendNSetResponse(presentationID, message.MessageId, new DicomMessage(),
                                    success ? DicomStatuses.Success : DicomStatuses.ProcessingFailure);
            }

            #endregion

            // no supported message type, send a failure status 
            server.SendCFindResponse(presentationID, message.MessageId, new DicomMessage(),
                DicomStatuses.QueryRetrieveIdentifierDoesNotMatchSOPClass);

            return true;
        }
Beispiel #13
0
 private bool ProcessNSetRequestForDiscontinued(DicomServer server, byte presentationId, DicomMessage message)
 {
     throw new NotImplementedException();
 }
Beispiel #14
0
 private bool ProcessNCreateRequest(DicomServer server, byte presentationId, DicomMessage message)
 {
     throw new NotImplementedException();
 }
Beispiel #15
0
        private void OnReceivePatientQuery(DicomServer server, byte presentationId, DicomMessage message)
        {
            var tagList = new List<DicomTag>();

            using (var pacsContext = new PacsContext())
            {
                var adapter = (IObjectContextAdapter)pacsContext;
                var query = new ObjectQuery<Patient>("Patients", adapter.ObjectContext);

                DicomAttributeCollection data = message.DataSet;

                foreach (DicomAttribute attribute in data)
                {
                    tagList.Add(attribute.Tag);
                    if (!attribute.IsNull)
                    {
                        switch (attribute.Tag.TagValue)
                        {
                            case DicomTags.PatientsName:
                                {
                                    var cond = QueryHelper.SetStringCondition("PatientName",
                                                                   data[DicomTags.PatientsName].GetString(0, string.Empty));
                                    query = query.Where(cond);
                                    break;
                                }

                            case DicomTags.PatientId:
                                {
                                    var cond = QueryHelper.SetStringCondition("PatientId",
                                                               data[DicomTags.PatientId].GetString(0, string.Empty));
                                    query = query.Where(cond);
                                    break;
                                }

                            case DicomTags.IssuerOfPatientId:
                                {
                                    var cond = QueryHelper.SetStringCondition("Issuer",
                                                                              data[DicomTags.IssuerOfPatientId]
                                                                                  .GetString(0, string.Empty));
                                }
                                break;
                            case DicomTags.PatientsSex:
                                break;
                            case DicomTags.PatientsBirthDate:
                                {
                                    var cond = QueryHelper.SetStringArrayCondition("PatientBirthDate",
                                                                                   (string[])
                                                                                   data[DicomTags.PatientsBirthDate]
                                                                                       .Values);
                                    query = query.Where(cond);
                                }
                                break;
                            default:
                                break;
                        }
                    }
                }

                int resultCount = 0;
                try
                {
                    foreach (Patient patient in query)
                    {
                        if (_cancelReceived)
                        {
                            throw new DicomException("DICOM C-Cancel Received");
                        }

                        resultCount++;
                        if (DicomSetting.Default.MaxQueryResponses != -1 &&
                            DicomSetting.Default.MaxQueryResponses < resultCount)
                        {
                            SendBufferedResponses(server, presentationId, message);
                            throw new DicomException("Maximum Configured Query Responses Exceeded: " + resultCount);
                        }

                        var response = new DicomMessage();
                        PopulatePatient(response, tagList, patient);
                        _responseQueue.Enqueue(response);

                        if (_responseQueue.Count >= DicomSetting.Default.BufferedQueryResponses)
                        {
                            SendBufferedResponses(server, presentationId, message);
                        }
                    }

                    SendBufferedResponses(server, presentationId, message);
                }
                catch (Exception e)
                {
                    if (_cancelReceived)
                    {
                        var errorResponse = new DicomMessage();
                        server.SendCFindResponse(presentationId, message.MessageId, errorResponse,
                                                 DicomStatuses.Cancel);
                    }
                }
            }

            var finalResponse = new DicomMessage();
            server.SendCFindResponse(presentationId, message.MessageId, finalResponse, DicomStatuses.Success);
        }
Beispiel #16
0
        private bool GetSopListForPatient(PacsContext ctx, DicomMessage message, out string errorComment)
        {
            errorComment = string.Empty;

            var patientId = message.DataSet[DicomTags.PatientId].GetString(0, string.Empty);
            int patientPK = ctx.Patients.Where(p => p.PatientId == patientId).Select(p => p.Id).FirstOrDefault();

            var studyList = (ctx.Studies.Where(s => s.PatientForeignKey == patientPK)).ToList();

            foreach (var study in studyList)
            {
                var seriesPkList = (from s in ctx.Series where study.Id == s.StudyForeignKey select s.Id).ToList();

                var sopList = (from s in ctx.Instances where seriesPkList.Contains(s.SeriesForeignKey) select s.Id).ToList();

                var fileList = (from f in ctx.Files where sopList.Contains(f.InstanceFk) select f).ToList();

                foreach (var file in fileList)
                {
                    _theScu.AddStorageInstance(new StorageInstance(file.FilePath));
                }
            }

            return true;
        }
Beispiel #17
0
        private void OnReceiveStudyLevelQuery(DicomServer server, byte presentationId, DicomMessage message)
        {
            var tagList = new List<DicomTag>();

            using (var pacsContext = new PacsContext())
            {
                var adapter = (IObjectContextAdapter)pacsContext;
                var query = new ObjectQuery<Study>("Studies", adapter.ObjectContext);

                DicomAttributeCollection data = message.DataSet;
                foreach (DicomAttribute attrib in message.DataSet)
                {
                    tagList.Add(attrib.Tag);

                    if (!attrib.IsNull)
                    {
                        switch (attrib.Tag.TagValue)
                        {
                            case DicomTags.StudyInstanceUid:
                                {
                                    var cond = QueryHelper.SetStringArrayCondition("StudyInstanceUid",
                                                                                   (string[])data[DicomTags.StudyInstanceUid].Values);
                                    if (!string.IsNullOrEmpty(cond))
                                    {
                                        query = query.Where(cond);
                                    }    
                                }
                                
                                break;
                            case DicomTags.PatientsName:
                                {
                                    var cond = QueryHelper.SetStringCondition("PatientName",
                                                                              data[DicomTags.PatientsName].GetString(0,
                                                                                                                     string
                                                                                                                         .Empty));
                                    if (!string.IsNullOrEmpty(cond))
                                    {
                                        query = query.Where(cond);
                                    }
                                    
                                    break;
                                }
                            case DicomTags.PatientId:
                                {
                                    var cond = QueryHelper.SetStringCondition("PatientId",
                                                                              data[DicomTags.PatientId].GetString(0,
                                                                                                                  string
                                                                                                                      .Empty));
                                    break;
                                }
                            case DicomTags.PatientsBirthDate:
                                {
                                    var cond = QueryHelper.SetRangeCondition("PatientBirthDate",
                                                                             data[DicomTags.PatientsBirthDate].GetString
                                                                                 (0, string.Empty));
                                    query = query.Where(cond);
                                    break;
                                }

                            case DicomTags.PatientsSex:
                                {
                                    var cond = QueryHelper.SetStringCondition("PatientSex",
                                                                              data[DicomTags.PatientsSex].GetString(0,
                                                                                                                    string
                                                                                                                        .Empty));
                                    query = query.Where(cond);
                                }
                                break;
                            case DicomTags.StudyDate:
                                {
                                    var cond = QueryHelper.SetRangeCondition("StudyDate",
                                                                              data[DicomTags.StudyDate].GetString(0,
                                                                                                                  string
                                                                                                                      .Empty));
                                    query = query.Where(cond);
                                }
                                break;
                            case DicomTags.StudyTime:
                                {
                                    var cond = QueryHelper.SetRangeCondition("StudyTime",
                                                                              data[DicomTags.StudyTime].GetString(0,
                                                                                                                  string
                                                                                                                      .Empty));
                                    query = query.Where(cond);
                                }
                                break;
                            case DicomTags.AccessionNumber:
                                {
                                    var cond = QueryHelper.SetStringCondition("AccessionNumber",
                                                                              data[DicomTags.AccessionNumber].GetString(
                                                                                  0, string.Empty));
                                    query = query.Where(cond);
                                }
                                break;
                            case DicomTags.StudyId:
                                {
                                    var cond = QueryHelper.SetStringCondition("StudyId",
                                        data[DicomTags.StudyId].GetString(0, string.Empty));

                                    query = query.Where(cond);
                                }
                                break;
                            case DicomTags.StudyDescription:
                                {
                                    var cond = QueryHelper.SetStringCondition("StudyDescription",
                                        data[DicomTags.StudyDescription].GetString(0, string.Empty));
                                    query = query.Where(cond);
                                }
                                break;
                            case DicomTags.ReferringPhysiciansName:
                                {
                                    var cond = QueryHelper.SetStringCondition("RefPhysician",
                                                                              data[DicomTags.ReferringPhysiciansName]
                                                                                  .GetString(0, string.Empty));
                                    query = query.Where(cond);
                                }
                                break;
                            case DicomTags.ModalitiesInStudy:
                                break;
                            default:
                                break;
                        }
                    }
                }
                int resultCount = 0;
                try
                {
                    foreach (Study study in query)
                    {
                        if (_cancelReceived)
                        {
                            throw new DicomException("DICOM C-Cancel Received");
                        }

                        resultCount++;
                        if (DicomSetting.Default.MaxQueryResponses != -1 &&
                            DicomSetting.Default.MaxQueryResponses < resultCount)
                        {
                            SendBufferedResponses(server, presentationId, message);
                            throw new DicomException("Maximum Configured Query Responses Exceeded: " + resultCount);
                        }

                        var response = new DicomMessage();
                        PopulateStudy(response, tagList, study);
                        _responseQueue.Enqueue(response);

                        if (_responseQueue.Count >= DicomSetting.Default.BufferedQueryResponses)
                        {
                            SendBufferedResponses(server, presentationId, message);
                        }
                    }

                    SendBufferedResponses(server, presentationId, message);
                }
                catch (Exception e)
                {
                    if (_cancelReceived)
                    {
                        var errorResponse = new DicomMessage();
                        server.SendCFindResponse(presentationId, message.MessageId, errorResponse,
                                                 DicomStatuses.Cancel);
                    }

                    return;
                }
            }

            var finalResponse = new DicomMessage();
            server.SendCFindResponse(presentationId, message.MessageId, finalResponse, DicomStatuses.Success);
        }
Beispiel #18
0
        private bool GetSopListForSeries(PacsContext ctx, DicomMessage message, out string errorComment)
        {
            errorComment = string.Empty;

            var studyInstanctUid = message.DataSet[DicomTags.StudyInstanceUid].GetString(0, string.Empty);
            var seriesUidList = (string[]) message.DataSet[DicomTags.SeriesInstanceUid].Values;

            int studyPk = ctx.Studies.Where(s => s.StudyUid == studyInstanctUid).Select(s => s.Id).FirstOrDefault();

            var seriesPkList = (from s in ctx.Series where seriesUidList.Contains(s.SeriesUid) select s.Id).ToList();

            var sopList = (from s in ctx.Instances where seriesPkList.Contains(s.SeriesForeignKey) select s.Id).ToList();

            var fileList = (from f in ctx.Files where sopList.Contains(f.InstanceFk) select f).ToList();

            foreach (var file in fileList)
            {
                _theScu.AddStorageInstance(new StorageInstance(file.FilePath));
            }

            return true;
        }
Beispiel #19
0
        /// <summary>
        ///  Populate data from a <see cref="Patient"/> entity into a DICOM C-FIND-RSP message
        /// </summary>
        /// <param name="response"></param>
        /// <param name="tagList"></param>
        /// <param name="row"></param>
        private void PopulatePatient(DicomMessage response, IEnumerable<DicomTag> tagList, Patient row)
        {
            DicomAttributeCollection dataset = response.DataSet;

            dataset[DicomTags.RetrieveAeTitle].SetStringValue(base.Partition.AeTitle);

            // character set
            var characterSet = GetPreferredCharacterSet();
            if (!string.IsNullOrEmpty(characterSet))
            {
                dataset[DicomTags.SpecificCharacterSet].SetStringValue(characterSet);
                dataset.SpecificCharacterSet = characterSet;
            }

            var relatedStudies = row.Studies;
            Study study = null;
            if (relatedStudies.Count > 0)
                study = relatedStudies.First();

            foreach (DicomTag tag in tagList)
            {
                try
                {
                    switch (tag.TagValue)
                    {
                        case DicomTags.PatientsName:
                            dataset[DicomTags.PatientsName].SetStringValue(row.PatientName);
                            break;
                        case DicomTags.PatientId:
                            dataset[DicomTags.PatientId].SetStringValue(row.PatientId);
                            break;
                        case DicomTags.IssuerOfPatientId:
                            dataset[DicomTags.IssuerOfPatientId].SetStringValue(row.Issuer);
                            break;
                        case DicomTags.NumberOfPatientRelatedStudies:
                            dataset[DicomTags.NumberOfPatientRelatedStudies].AppendInt32(row.NumberOfRelatedStudies);
                            break;
                        case DicomTags.NumberOfPatientRelatedSeries:
                            dataset[DicomTags.NumberOfPatientRelatedSeries].AppendInt32(row.NumberOfRelatedSeries);
                            break;
                        case DicomTags.NumberOfPatientRelatedInstances:
                            dataset[DicomTags.NumberOfPatientRelatedInstances].AppendInt32(row.NumberOfRelatedInstances);
                            break;
                        case DicomTags.QueryRetrieveLevel:
                            dataset[DicomTags.QueryRetrieveLevel].SetStringValue("PATIENT");
                            break;
                        case DicomTags.PatientsSex:
                            if (study != null)
                            {
                                dataset[DicomTags.PatientsSex].SetStringValue(study.PatientSex);
                            }
                            else
                            {
                                dataset[DicomTags.PatientsSex].SetNullValue();
                            }
                            break;
                        case DicomTags.PatientsBirthDate:
                            dataset[DicomTags.PatientsBirthDate].SetStringValue(row.PatientBirthDate);
                            break;

                        // Meta tags that should have not been in the RQ, but we've already set
                        case DicomTags.RetrieveAeTitle:
                        case DicomTags.InstanceAvailability:
                        case DicomTags.SpecificCharacterSet:
                            break;

                        default:
                            if (!tag.IsPrivate)
                                dataset[tag].SetNullValue();

                            // extension ? 
                            break;
                    }
                }
                catch (Exception e)
                {
                    Platform.Log(LogLevel.Warn, e, "Unexpected error setting tag {0} in C-FIND-RSP",
                                dataset[tag].Tag.ToString());
                    if (!tag.IsPrivate)
                        dataset[tag].SetNullValue();
                }
            }

        }
Beispiel #20
0
        public override bool OnReceiveRequest(DicomServer server, ServerAssociationParameters association,
                                              byte presentationID, DicomMessage message)
        {
            bool finalResponseSent = false;
            string errorComment;

            try
            {
                // check for a Cancel Message, and cance the scu 
                if (message.CommandField == DicomCommandField.CCancelRequest)
                {
                    if (_theScu != null)
                    {
                        _theScu.Cancel();
                    }

                    return true;
                }

                string level = message.DataSet[DicomTags.QueryRetrieveLevel].GetString(0, string.Empty);

                string remoteAe = message.MoveDestination.Trim();

                // load remote device for move information 
                using (var ctx = new PacsContext())
                {
                    var device = (from d in ctx.Devices
                                  where d.ServerPartitionPK == Partition.Id && d.AeTitle == remoteAe
                                  select d).FirstOrDefault();

                    if (device == null)
                    {
                        errorComment = string.Format(
                            "Unknown move destination \"{0}\", failing C-MOVE-RQ from {1} to {2}",
                            remoteAe, association.CallingAE, association.CalledAE);
                        Platform.Log(LogLevel.Error, errorComment);
                        server.SendCMoveResponse(presentationID, message.MessageId, new DicomMessage(),
                                                 DicomStatuses.QueryRetrieveMoveDestinationUnknown, errorComment);
                        finalResponseSent = true;
                        return true;
                    }

                    // If the remote node is a DHCP node, use its IP address from the connection information, else
                    // use what is configured.  Always use the configured port. 
                    if (device.Dhcp)
                    {
                        device.Hostname = association.RemoteEndPoint.Address.ToString();
                    }

                    // now setup the storage scu component 
                    _theScu = new PacsStorageScu(Partition, device, association.CallingAE, message.MessageId);

                    bool bOnline;

                    if (level.Equals("PATIENT"))
                    {
                        bOnline = GetSopListForInstance(ctx, message, out errorComment);
                    }
                    else if (level.Equals("STUDY"))
                    {
                        bOnline = GetSopListForStudy(ctx, message, out errorComment);
                    }
                    else if (level.Equals("SERIES"))
                    {
                        bOnline = GetSopListForSeries(ctx, message, out errorComment);
                    }
                    else if (level.Equals("IMAGE"))
                    {
                        bOnline = GetSopListForInstance(ctx, message, out errorComment);
                    }
                    else
                    {
                        errorComment = string.Format("Unexpected Study Root Move Query/Retrieve level: {0}", level);
                        Platform.Log(LogLevel.Error, errorComment);

                        server.SendCMoveResponse(presentationID, message.MessageId, new DicomMessage(),
                                                 DicomStatuses.QueryRetrieveIdentifierDoesNotMatchSOPClass,
                                                 errorComment);
                        finalResponseSent = true;
                        return true;
                    }

                    // Could not find an online/readable location for the requested objects to move.
                    // Note that if the C-MOVE-RQ included a list of study instance uids, and some 
                    // were online and some offline, we don't fail now (ie, the check on the Count)
                    if (!bOnline || _theScu.StorageInstanceList.Count == 0)
                    {
                        Platform.Log(LogLevel.Error, "Unable to find online storage location for C-MOVE-RQ: {0}",
                                     errorComment);

                        server.SendCMoveResponse(presentationID, message.MessageId, new DicomMessage(),
                                                 DicomStatuses.QueryRetrieveUnableToPerformSuboperations,
                                                 string.IsNullOrEmpty(errorComment) ? string.Empty : errorComment);
                        finalResponseSent = true;
                        _theScu.Dispose();
                        _theScu = null;
                        return true;
                    }

                    _theScu.ImageStoreCompleted += delegate(Object sender, StorageInstance instance)
                        {
                            var scu = (StorageScu) sender;
                            var msg = new DicomMessage();
                            DicomStatus status;

                            if (instance.SendStatus.Status == DicomState.Failure)
                            {
                                errorComment =
                                    string.IsNullOrEmpty(instance.ExtendedFailureDescription)
                                        ? instance.SendStatus.ToString()
                                        : instance.ExtendedFailureDescription;
                            }

                            if (scu.RemainingSubOperations == 0)
                            {
                                foreach (StorageInstance sop in _theScu.StorageInstanceList)
                                {
                                    if ((sop.SendStatus.Status != DicomState.Success)
                                        && (sop.SendStatus.Status != DicomState.Warning))
                                        msg.DataSet[DicomTags.FailedSopInstanceUidList].AppendString(sop.SopInstanceUid);
                                }
                                if (scu.Status == ScuOperationStatus.Canceled)
                                    status = DicomStatuses.Cancel;
                                else if (scu.Status == ScuOperationStatus.ConnectFailed)
                                    status = DicomStatuses.QueryRetrieveMoveDestinationUnknown;
                                else if (scu.FailureSubOperations > 0)
                                    status = DicomStatuses.QueryRetrieveSubOpsOneOrMoreFailures;
                                else if (!bOnline)
                                    status = DicomStatuses.QueryRetrieveUnableToPerformSuboperations;
                                else
                                    status = DicomStatuses.Success;
                            }
                            else
                            {
                                status = DicomStatuses.Pending;

                                if ((scu.RemainingSubOperations%5) != 0)
                                    return;
                                // Only send a RSP every 5 to reduce network load
                            }
                            server.SendCMoveResponse(presentationID, message.MessageId,
                                                     msg, status,
                                                     (ushort) scu.SuccessSubOperations,
                                                     (ushort) scu.RemainingSubOperations,
                                                     (ushort) scu.FailureSubOperations,
                                                     (ushort) scu.WarningSubOperations,
                                                     status == DicomStatuses.QueryRetrieveSubOpsOneOrMoreFailures
                                                         ? errorComment
                                                         : string.Empty);


                            if (scu.RemainingSubOperations == 0)
                                finalResponseSent = true;
                        };

                    _theScu.BeginSend(
                        delegate(IAsyncResult ar)
                            {
                                if (_theScu != null)
                                {
                                    if (!finalResponseSent)
                                    {
                                        var msg = new DicomMessage();
                                        server.SendCMoveResponse(presentationID, message.MessageId,
                                                                 msg, DicomStatuses.QueryRetrieveSubOpsOneOrMoreFailures,
                                                                 (ushort) _theScu.SuccessSubOperations,
                                                                 0,
                                                                 (ushort)
                                                                 (_theScu.FailureSubOperations +
                                                                  _theScu.RemainingSubOperations),
                                                                 (ushort) _theScu.WarningSubOperations, errorComment);
                                        finalResponseSent = true;
                                    }

                                    _theScu.EndSend(ar);
                                    _theScu.Dispose();
                                    _theScu = null;
                                }
                            },
                        _theScu);

                    return true;
                }
            }
            catch (Exception e)
            {
                Platform.Log(LogLevel.Error, e, "Unexpected exception when processing C-MOVE-RQ");
                if (finalResponseSent == false)
                {
                    try
                    {
                        server.SendCMoveResponse(presentationID, message.MessageId, new DicomMessage(),
                                                 DicomStatuses.QueryRetrieveUnableToProcess, e.Message);
                        finalResponseSent = true;
                    }
                    catch (Exception x)
                    {
                        Platform.Log(LogLevel.Error, x,
                                     "Unable to send final C-MOVE-RSP message on association from {0} to {1}",
                                     association.CallingAE, association.CalledAE);
                        server.Abort();
                    }
                }
            }

            return false;
        }
Beispiel #21
0
        private void OnReceiveSeriesLevelQuery(DicomServer server, byte presentationId, DicomMessage message)
        {
            var tagList = new List<DicomTag>();

            using (var pacsContext = new PacsContext())
            {
                var adapter = (IObjectContextAdapter)pacsContext;
                var query = new ObjectQuery<Series>("Series", adapter.ObjectContext);

                DicomAttributeCollection data = message.DataSet;
                foreach (DicomAttribute attrib in data)
                {
                    tagList.Add(attrib.Tag);
                    if (!attrib.IsNull)
                    {
                        switch (attrib.Tag.TagValue)
                        {
                            case DicomTags.StudyInstanceUid:
                                {
                                    var uids = data[DicomTags.StudyInstanceUid].GetString(0, string.Empty);
                                    IQueryable<int> studyQuery = from s in pacsContext.Studies
                                                                 where uids.Contains(s.StudyUid)
                                                                 select s.Id;
                                    var result = studyQuery.ToArray();
                                    if (result.Length == 0)
                                    {
                                        server.SendCFindResponse(presentationId, message.MessageId, new DicomMessage(),
                                                             DicomStatuses.Success);
                                        return;
                                    }

                                    query = query.Where(QueryHelper.SetIntArrayCondition("StudyForeignKey", result));
                                }
                                break;
                            case DicomTags.SeriesInstanceUid:
                                {
                                    var cond = QueryHelper.SetStringArrayCondition("SeriesUid",
                                                                                   (string[])
                                                                                   data[DicomTags.SeriesInstanceUid]
                                                                                       .Values);
                                    query = query.Where(cond);
                                }
                                break;
                            case DicomTags.Modality:
                                {
                                    var cond = QueryHelper.SetStringCondition("Modality",
                                                                              data[DicomTags.Modality].GetString(0,
                                                                                                                 string
                                                                                                                     .Empty));
                                    query = query.Where(cond);
                                }
                                break;
                            case DicomTags.SeriesNumber:
                                {
                                    var cond = QueryHelper.SetStringCondition("SeriesNumber",
                                                                              data[DicomTags.SeriesNumber].GetString(0,
                                                                                                                     string
                                                                                                                         .Empty));
                                    query = query.Where(cond);
                                }
                                break;
                            case DicomTags.SeriesDescription:
                                {
                                    var cond = QueryHelper.SetStringCondition("SeriesDescription",
                                                                              data[DicomTags.StudyDescription].GetString
                                                                                  (0, string.Empty));
                                    query = query.Where(cond);
                                }
                                break;
                            case DicomTags.PerformedProcedureStepStartDate:
                                {
                                    var cond = QueryHelper.SetRangeCondition("PerformedProcedureStepStartDate",
                                                                             data[
                                                                                 DicomTags
                                                                                     .PerformedProcedureStepStartDate]
                                                                                 .GetString(0, string.Empty));
                                    query = query.Where(cond);
                                }
                                break;
                            case DicomTags.PerformedProcedureStepStartTime:
                                {
                                    var cond = QueryHelper.SetRangeCondition("PerformedProcedureStepStartTime",
                                                                             data[
                                                                                 DicomTags
                                                                                     .PerformedProcedureStepStartTime]
                                                                                 .GetString(0, string.Empty));
                                    query = query.Where(cond);
                                }
                                break;
                            case DicomTags.RequestAttributesSequence: // todo
                                break;
                            default:
                                break;
                        }
                    }
                }

                int resultCount = 0;
                try
                {
                    foreach (Series series in query)
                    {
                        if (_cancelReceived)
                        {
                            throw new DicomException("DICOM C-Cancel Received");
                        }

                        resultCount++;
                        if (DicomSetting.Default.MaxQueryResponses != -1 &&
                            DicomSetting.Default.MaxQueryResponses < resultCount)
                        {
                            SendBufferedResponses(server, presentationId, message);
                            throw new DicomException("Maximum Configured Query Responses Exceeded: " + resultCount);
                        }

                        var response = new DicomMessage();
                        PopulateSeries(message, response, tagList, series);
                        _responseQueue.Enqueue(response);

                        if (_responseQueue.Count >= DicomSetting.Default.BufferedQueryResponses)
                        {
                            SendBufferedResponses(server, presentationId, message);
                        }
                    }

                    SendBufferedResponses(server, presentationId, message);
                }
                catch (Exception e)
                {
                    if (_cancelReceived)
                    {
                        var errorResponse = new DicomMessage();
                        server.SendCFindResponse(presentationId, message.MessageId, errorResponse,
                                                 DicomStatuses.Cancel);
                    }
                }
            }

            var finalResponse = new DicomMessage();
            server.SendCFindResponse(presentationId, message.MessageId, finalResponse, DicomStatuses.Success);
        }
Beispiel #22
0
        public override bool OnReceiveRequest(DicomServer server, ServerAssociationParameters association,
                                              byte presentationID, DicomMessage message)
        {
            if (message.CommandField == DicomCommandField.CCancelRequest)
            {
                Platform.Log(LogLevel.Info, "Received Worklist-CANCEL-RQ message.");
                _cancelReceived = true;
                return true;
            }

            if (message.AffectedSopClassUid.Equals(SopClass.ModalityWorklistInformationModelFindUid))
            {
                // We use the ThreadPool to process the thread requests. This is so that we return back
                // to the main message loop, and continue to look for cancel request messages coming
                // in.  There's a small chance this may cause delays in responding to query requests if
                // the .NET Thread pool fills up.
                ThreadPool.QueueUserWorkItem(delegate
                {
                    try
                    {
                        OnReceiveMWLQuery(server, presentationID, message);
                    }
                    catch (Exception x)
                    {
                        Platform.Log(LogLevel.Error, x, "Unexpected exception in OnReceiveStudyLevelQuery.");
                    }
                });
                return true;
            }

            // no supported message type, send a failure status 
            server.SendCFindResponse(presentationID, message.MessageId, new DicomMessage(),
                DicomStatuses.QueryRetrieveIdentifierDoesNotMatchSOPClass);

            return true;
        }
Beispiel #23
0
        // what is the scenario about image level query 
        // TODO add support in Image Level Query 
        private void OnReceiveImageLevelQuery(DicomServer server, byte presentationId, DicomMessage message)
        {
            var tagList = new List<DicomTag>();

            using (var pacsContext = new PacsContext())
            {
                var adapter = (IObjectContextAdapter)pacsContext;
                var query = new ObjectQuery<Instance>("Instances", adapter.ObjectContext);

                DicomAttributeCollection data = message.DataSet;
                string studyInstanceUid = data[DicomTags.StudyInstanceUid].GetString(0, String.Empty);
                string seriesInstanceUid = data[DicomTags.SeriesInstanceUid].GetString(0, String.Empty);

                foreach (DicomAttribute attrib in data)
                {
                    if (attrib.Tag.TagValue.Equals(DicomTags.SpecificCharacterSet)
                        || attrib.Tag.TagValue.Equals(DicomTags.QueryRetrieveLevel))
                        continue;

                    tagList.Add(attrib.Tag);
                    if (!attrib.IsNull)
                    {
                        switch (attrib.Tag.TagValue)
                        {

                        }
                    }
                }

                int resultCount = 0;
                try
                {
                    foreach (Instance instance in query)
                    {
                        if (_cancelReceived)
                        {
                            throw new DicomException("DICOM C-Cancel Received");
                        }

                        resultCount++;
                        if (DicomSetting.Default.MaxQueryResponses != -1 &&
                            DicomSetting.Default.MaxQueryResponses < resultCount)
                        {
                            SendBufferedResponses(server, presentationId, message);
                            throw new DicomException("Maximum Configured Query Responses Exceeded: " + resultCount);
                        }

                        var response = new DicomMessage();
                        PopuldateInstance(message, response, tagList, instance);
                        _responseQueue.Enqueue(response);

                        if (_responseQueue.Count >= DicomSetting.Default.BufferedQueryResponses)
                        {
                            SendBufferedResponses(server, presentationId, message);
                        }
                    }

                    SendBufferedResponses(server, presentationId, message);
                }
                catch (Exception e)
                {
                    if (_cancelReceived)
                    {
                        var errorResponse = new DicomMessage();
                        server.SendCFindResponse(presentationId, message.MessageId, errorResponse,
                                                 DicomStatuses.Cancel);
                    }
                }
            }

            var finalResponse = new DicomMessage();
            server.SendCFindResponse(presentationId, message.MessageId, finalResponse, DicomStatuses.Success);
        }
 public override bool OnReceiveRequest(Dicom.Network.DicomServer server, ServerAssociationParameters association, byte presentationID,
                                       DicomMessage message)
 {
     throw new System.NotImplementedException();
 }
Beispiel #25
0
        private void SendBufferedResponses(DicomServer server, byte presentationId, DicomMessage requestMessage)
        {
            while (_responseQueue.Count > 0)
            {
                DicomMessage response = _responseQueue.Dequeue();

                server.SendCFindResponse(presentationId, requestMessage.MessageId, response, DicomStatuses.Pending);

                if (_cancelReceived)
                {
                    throw new DicomException("DICOM C-Cancel Received");
                }

                if (!server.NetworkActive)
                    throw new DicomException("Association is no longer valid.");
            }
        }
Beispiel #26
0
        /// <summary>
        /// Creates a new DicomFile instance from an existing <see cref="DicomMessage"/> instance.
        /// </summary>
        /// <remarks>
        /// <para>
        /// This routine assigns the existing <see cref="DicomMessage.DataSet"/> into the new 
        /// DicomFile instance.
        /// </para>
        /// <para>
        /// A new <see cref="DicomAttributeCollection"/> is created for the MetaInfo.  The 
        /// Media Storage SOP Instance UID, Media Storage SOP Class UID, Implementation Version Name,
        /// and Implementation Class UID tags are automatically set in the meta information.
        /// </para>
        /// </remarks>
        /// <param name="msg"></param>
        /// <param name="filename"></param>
        public DicomFile(DicomMessage msg, String filename)
        {
            MetaInfo = new DicomAttributeCollection(0x00020000, 0x0002FFFF);
            DataSet = msg.DataSet;

            MediaStorageSopInstanceUid = msg.AffectedSopInstanceUid;
            MediaStorageSopClassUid = msg.AffectedSopClassUid;
            ImplementationVersionName = DicomImplementation.Version;
            ImplementationClassUid = DicomImplementation.ClassUID.UID;
            if (msg.TransferSyntax.Encapsulated)
                MetaInfo[DicomTags.TransferSyntaxUid].SetStringValue(msg.TransferSyntax.UidString);
            else
                MetaInfo[DicomTags.TransferSyntaxUid].SetStringValue(TransferSyntax.ExplicitVrLittleEndian.UidString);
            MetaInfo[DicomTags.FileMetaInformationVersion].Values = new byte[] { 0x00, 0x01 };
            
            _filename = filename;
        }
Beispiel #27
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);

            var 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;
            }
            _moveMessageId = client.NextMessageID();
            client.SendCMoveRequest(pcid, _moveMessageId, _destinationAe, dicomMessage);
        }