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; }
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); }
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."); } }
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; }
// 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); }
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); }
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); }
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); }
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; }