示例#1
0
        public void OnReceiveRequestMessage(DicomServer server, ServerAssociationParameters association, byte presentationID, ClearCanvas.Dicom.DicomMessage message)
        {
            foreach (byte pcid in association.GetPresentationContextIDs())
            {
                DicomPresContext context = association.GetPresentationContext(pcid);
                if (context.Result == DicomPresContextResult.Accept)
                {
                    if (context.AbstractSyntax == SopClass.StudyRootQueryRetrieveInformationModelFind)
                    {
                        DicomMessage response = new DicomMessage();
                        response.DataSet[DicomTags.StudyInstanceUid].SetStringValue("1.2.3");
                        response.DataSet[DicomTags.PatientId].SetStringValue("1");
                        response.DataSet[DicomTags.PatientsName].SetStringValue("test");
                        response.DataSet[DicomTags.StudyId].SetStringValue("1");
                        response.DataSet[DicomTags.StudyDescription].SetStringValue("dummy");
                        server.SendCFindResponse(presentationID, message.MessageId, response, DicomStatuses.Pending);

                        DicomMessage finalResponse = new DicomMessage();
                        server.SendCFindResponse(presentationID, message.MessageId, finalResponse, DicomStatuses.Success);
                    }
                    else if (context.AbstractSyntax == SopClass.VerificationSopClass)
                    {
                        server.SendCEchoResponse(presentationID, message.MessageId, DicomStatuses.Success);
                    }
                }
            }
        }
示例#2
0
        void IDicomServerHandler.OnReceiveRequestMessage(DicomServer server, ServerAssociationParameters association, byte presentationID, DicomMessage message)
        {
            _sessionDebug.SetAssociationDumpString(association);
            _sessionDebug._request = message.Dump();

            #region Cancel request
            if (message.CommandField == DicomCommandField.CCancelRequest)
            {
                Logger.LogInfo("Received CANCEL-RQ message from {0}.", association.CallingAE);
                _cancelReceived = true;
                return;
            }
            #endregion

            #region CEcho request
            if (message.CommandField == DicomCommandField.CEchoRequest)
            {
                server.SendCEchoResponse(presentationID, message.MessageId, DicomStatuses.Success);
                Logger.LogInfo("Received ECHO-RQ message from {0}.", association.CallingAE);
                return;
            }
            #endregion

            #region MWL C-FIND request
            if (message.CommandField == DicomCommandField.CFindRequest)
            {
                Logger.LogInfo("Message Dumped :\n" + message.Dump("", DicomDumpOptions.KeepGroupLengthElements));

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

                _cancelReceived = false;

                if (message.AffectedSopClassUid.Equals(SopClass.ModalityWorklistInformationModelFindUid))
                {
                    OnReceiveMWLQuery(server, presentationID, message);
                }
                else
                {
                    // Not supported message type, send a failure status.
                    server.SendCFindResponse(presentationID, message.MessageId, new DicomMessage(),
                                             DicomStatuses.QueryRetrieveIdentifierDoesNotMatchSOPClass);
                }
                return;
            }
            #endregion

            //ignore all unsupported request

            server.SendAssociateAbort(DicomAbortSource.ServiceProvider, DicomAbortReason.UnexpectedPDU);
            Logger.LogInfo("Unexpected Command. Send Associate Abort message from server to {0}.", association.CallingAE);
            return;
        }
示例#3
0
 private void SendBufferedResponses(DicomServer server, byte presentationId, DicomMessage requestMessage, DicomStatus pendingStatus)
 {
     while (_responseQueue.Count > 0)
     {
         DicomMessage response = _responseQueue.Dequeue();
         _sessionDebug._responses.Add(response.Dump());
         server.SendCFindResponse(presentationId, requestMessage.MessageId, response,
                                  pendingStatus);
         Platform.Log(LogLevel.Info, "Sending a Worklist Response ");
         if (_cancelReceived)
         {
             throw new DicomException("DICOM C-Cancel Received");
         }
     }
 }
示例#4
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.");
                }
            }
        }
示例#5
0
        public override bool OnReceiveRequest(DicomServer server, ServerAssociationParameters association,
                                              byte presentationID, DicomMessage message)
        {
            if (message.CommandField == DicomCommandField.CCancelRequest)
            {
                LogAdapter.Logger.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)
                    {
                        LogAdapter.Logger.TraceException(x);
                    }
                });
                return(true);
            }

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

            return(true);
        }
示例#6
0
        private void OnReceivePatientQuery(DicomServer server, byte presentationId, DicomMessage message)
        {
            var tagList = message.DataSet.Select(attrib => attrib.Tag).ToList();

            ISopQuery query = IoC.Get <ISopQuery>();

            int resultCount = 0;

            try
            {
                query.OnPatientQuery(message, delegate(IPatientData row)
                {
                    if (CancelReceived)
                    {
                        throw new DicomException("DICOM C-Cancel Received");
                    }

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

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

                    if (_responseQueue.Count >= _bufferedQueryResponses)
                    {
                        SendBufferedResponses(server, presentationId, message);
                    }
                });
            }
            catch (Exception)
            {
                if (CancelReceived)
                {
                    var errorResponse = new DicomMessage();
                    server.SendCFindResponse(presentationId, message.MessageId, errorResponse,
                                             DicomStatuses.Cancel);
                }
                else if (_maxQueryResponses != -1 &&
                         _maxQueryResponses < resultCount)
                {
                    Log.Logger.Warn("Maximum Configured Query Responses Exceeded: {0} on query from {1}",
                                    resultCount, server.AssociationParams.CallingAE);
                    var errorResponse = new DicomMessage();
                    server.SendCFindResponse(presentationId, message.MessageId, errorResponse,
                                             DicomStatuses.Success);
                }
                else
                {
                    Log.Logger.Error("Unexpected exception when processing FIND request.");
                    var errorResponse = new DicomMessage();
                    server.SendCFindResponse(presentationId, message.MessageId, errorResponse,
                                             DicomStatuses.QueryRetrieveUnableToProcess);
                }
                return;
            }

            SendBufferedResponses(server, presentationId, message);
            var finalResponse = new DicomMessage();

            server.SendCFindResponse(presentationId, message.MessageId, finalResponse, DicomStatuses.Success);

            return;
        }
示例#7
0
        /// <summary>
        /// Extension method called when a new DICOM Request message has been called that the
        /// extension will process.
        /// </summary>
        /// <param name="server"></param>
        /// <param name="association"></param>
        /// <param name="presentationId"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        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)
            {
                Log.Logger.Info("Received C-FIND-CANCEL-RQ message.");
                CancelReceived = true;
                return(true);
            }

            CancelReceived = false;

            if (message.AffectedSopClassUid.Equals(SopClass.StudyRootQueryRetrieveInformationModelFindUid))
            {
                if (level.Equals("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)
                        {
                            Log.Logger.Error("Unexpected exception in OnReceiveStudyLevelQuery.", x);
                        }
                    });
                    return(true);
                }
                if (level.Equals("SERIES"))
                {
                    ThreadPool.QueueUserWorkItem(delegate
                    {
                        try
                        {
                            OnReceiveSeriesLevelQuery(server, presentationId, message);
                        }
                        catch (Exception x)
                        {
                            Log.Logger.Error("Unexpected exception in OnReceiveSeriesLevelQuery.", x);
                        }
                    });
                    return(true);
                }


                if (level.Equals("IMAGE"))
                {
                    ThreadPool.QueueUserWorkItem(delegate
                    {
                        try
                        {
                            OnReceiveImageLevelQuery(server, presentationId, message);
                        }
                        catch (Exception x)
                        {
                            Log.Logger.Error("Unexpected exception in OnReceiveImageLevelQuery.", x);
                        }
                    });
                    return(true);
                }


                Log.Logger.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))
            {
                if (level.Equals("PATIENT"))
                {
                    ThreadPool.QueueUserWorkItem(delegate
                    {
                        try
                        {
                            OnReceivePatientQuery(server, presentationId, message);
                        }
                        catch (Exception x)
                        {
                            Log.Logger.Error("Unexpected exception in OnReceivePatientQuery.", x);
                        }
                    });

                    return(true);
                }
                if (level.Equals("STUDY"))
                {
                    ThreadPool.QueueUserWorkItem(delegate
                    {
                        try
                        {
                            OnReceiveStudyLevelQuery(server, presentationId, message);
                        }
                        catch (Exception x)
                        {
                            Log.Logger.Error("Unexpected exception in OnReceiveStudyLevelQuery.", x);
                        }
                    });
                    return(true);
                }
                if (level.Equals("SERIES"))
                {
                    ThreadPool.QueueUserWorkItem(delegate
                    {
                        try
                        {
                            OnReceiveSeriesLevelQuery(server, presentationId, message);
                        }
                        catch (Exception x)
                        {
                            Log.Logger.Error("Unexpected exception in OnReceiveSeriesLevelQuery.", x);
                        }
                    });
                    return(true);
                }

                /*
                 * if (level.Equals("IMAGE"))
                 * {
                 *  ThreadPool.QueueUserWorkItem(delegate
                 *  {
                 *      try
                 *      {
                 *          OnReceiveImageLevelQuery(server, presentationId, message);
                 *      }
                 *      catch (Exception x)
                 *      {
                 *          Log.Logger.Error("Unexpected exception in OnReceiveImageLevelQuery.", x);
                 *      }
                 *  });
                 *  return true;
                 * } */

                Log.Logger.Error("Unexpected IPatientData Root Query/Retrieve level: {0}", level);

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

            // Not supported message type, send a failure status.
            server.SendCFindResponse(presentationId, message.MessageId, new DicomMessage(),
                                     DicomStatuses.QueryRetrieveIdentifierDoesNotMatchSOPClass);
            return(true);
        }
示例#8
0
        private bool CheckForMissingRequiredMatchingKey(DicomServer server, byte presentationID, DicomMessage message)
        {
            DicomAttribute attrib;
            bool           requiredMatchingKeyMissing = false;
            string         comment = ""; // will receive a description of the first encountred missing r key.

            // we don't need to collect all missing keys to speed up processing.
            do
            {
                attrib = message.DataSet[DicomTags.ScheduledProcedureStepSequence];
                if (attrib.IsNull)
                {
                    requiredMatchingKeyMissing = true;
                    comment = "Missing Scheduled Procedure Step Sequence";
                    break;
                }
                DicomAttributeSQ sequence = attrib as DicomAttributeSQ;
                if (attrib.Count == 0)
                {
                    requiredMatchingKeyMissing = true;
                    comment = "Scheduled Procedure Step Sequence is empty";
                    break;
                }
                if (attrib.Count > 1)
                {
                    requiredMatchingKeyMissing = true;
                    comment = "Found Multiple Items in Scheduled Procedure Step Sequence";
                    break;
                }

                DicomSequenceItem sequenceSubItems = sequence[0];

                if (sequenceSubItems[DicomTags.ScheduledStationAeTitle].IsNull)
                {
                    requiredMatchingKeyMissing = true;
                    comment = "Missing Scheduled Station Ae Title";
                    break;
                }

                if (sequenceSubItems[DicomTags.Modality].IsNull)
                {
                    requiredMatchingKeyMissing = true;
                    comment = "Missing Modality";
                    break;
                }

                if (sequenceSubItems[DicomTags.ScheduledPerformingPhysiciansName].IsNull)
                {
                    requiredMatchingKeyMissing = true;
                    comment = "Missing Scheduled Performing Physicians Name";
                    break;
                }

                if (sequenceSubItems[DicomTags.ScheduledProcedureStepStartDate].IsNull)
                {
                    requiredMatchingKeyMissing = true;
                    comment = "Missing ScheduledProcedureStepStartDate";
                    break;
                }

                if (sequenceSubItems[DicomTags.ScheduledProcedureStepStartTime].IsNull)
                {
                    requiredMatchingKeyMissing = true;
                    comment = "Missing Scheduled Procedure Step Start Time";
                    break;
                }
            } while (false);

            // send specific error status to the calling AE
            if (requiredMatchingKeyMissing)
            {
                Platform.Log(LogLevel.Error, "Required matching key missing on query from {0}," +
                             "\n Sending Failure Status Identifier Does Not Match SOPClass.",
                             server.AssociationParams.CallingAE);
                Platform.Log(LogLevel.Error, "Error Details : {0}", comment);
                DicomMessage errorResponse = new DicomMessage();
                server.SendCFindResponse(presentationID, message.MessageId, errorResponse,
                                         DicomStatuses.QueryRetrieveIdentifierDoesNotMatchSOPClass);
            }

            return(requiredMatchingKeyMissing);
        }
示例#9
0
        private void OnReceiveMWLQuery(DicomServer server, byte presentationID, DicomMessage message)
        {
            #region Non conformance checking    - Unsopported Optional matching key checking

            if (CheckForMissingRequiredMatchingKey(server, presentationID, message))
            {
                return; //this mean sending failure message response.
            }
            DicomStatus pendingStatus = DicomStatuses.Pending;

            bool optionalMatchingKeyPresentButNotSupported =
                CheckForUnSupportedOptionalMatchingKey(server, presentationID, message, false);

            if (optionalMatchingKeyPresentButNotSupported)
            {
                pendingStatus = DicomStatuses.QueryRetrieveOptionalKeysNotSupported;
            }
            #endregion

            List <uint> tagList = new List <uint>();

            string sqlWhereClause = " where 1=1 ";

            DicomAttributeCollection data = message.DataSet;

            string specificCharacterSet = "";

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

                if (!attrib.IsNull)
                {
                    switch (attrib.Tag.TagValue)
                    {
                    case DicomTags.SpecificCharacterSet:
                        specificCharacterSet = data[DicomTags.SpecificCharacterSet].GetString(0, string.Empty);
                        break;

                        #region Case Scheduled procedure Step Seq
                    case DicomTags.ScheduledProcedureStepSequence:
                        DicomAttributeSQ  sequence         = attrib as DicomAttributeSQ;
                        DicomSequenceItem sequenceSubItems = sequence[0];
                        foreach (DicomAttribute seqAttrib in sequenceSubItems)
                        {
                            if (seqAttrib.IsNull)
                            {
                                continue;
                            }

                            tagList.Add(seqAttrib.Tag.TagValue);
                            switch (seqAttrib.Tag.TagValue)
                            {
                            // Required matching keys in ScheduledProcedureStepSequence
                            case DicomTags.ScheduledStationName:
                                SetStringCondition(ref sqlWhereClause, "ScheduledAET",
                                                   sequenceSubItems[DicomTags.ScheduledStationName].GetString(0, string.Empty));
                                break;

                            case DicomTags.Modality:
                                SetStringCondition(ref sqlWhereClause, "Modality",
                                                   sequenceSubItems[DicomTags.Modality].GetString(0, string.Empty));
                                break;

                            case DicomTags.ScheduledPerformingPhysiciansName:
                                SetStringCondition(ref sqlWhereClause, "PerformingPhysician",
                                                   sequenceSubItems[DicomTags.ScheduledPerformingPhysiciansName].GetString(0, string.Empty));
                                break;

                            case DicomTags.ScheduledProcedureStepStartDate:
                                SetDateRangeCondition(ref sqlWhereClause, "ExamScheduledDateAndTime",
                                                      sequenceSubItems[DicomTags.ScheduledProcedureStepStartDate].GetString(0, string.Empty));
                                break;

                            case DicomTags.ScheduledProcedureStepStartTime:
                                SetTimeRangeCondition(ref sqlWhereClause, "ExamScheduledDateAndTime",
                                                      sequenceSubItems[DicomTags.ScheduledProcedureStepStartTime].GetString(0, string.Empty));
                                break;

                            // Optional matching keys
                            case DicomTags.ScheduledProcedureStepLocation:
                                SetStringCondition(ref sqlWhereClause, "ExamRoom",
                                                   sequenceSubItems[DicomTags.ScheduledProcedureStepLocation].GetString(0, string.Empty));
                                break;

                            case DicomTags.ScheduledProcedureStepDescription:
                                SetStringCondition(ref sqlWhereClause, "ExamDescription",
                                                   sequenceSubItems[DicomTags.ScheduledProcedureStepDescription].GetString(0, string.Empty));
                                break;

                            case DicomTags.RequestedProcedureId:
                                SetInt32Condition(ref sqlWhereClause, "ProcedureID",
                                                  sequenceSubItems[DicomTags.RequestedProcedureId].GetString(0, string.Empty));
                                break;

                            case DicomTags.ScheduledProcedureStepId:
                                SetInt32Condition(ref sqlWhereClause, "ProcedureStepID",
                                                  sequenceSubItems[DicomTags.ScheduledProcedureStepId].GetString(0, string.Empty));
                                break;

                            default:
                                break;
                            }
                        }
                        break;
                        #endregion

                    case DicomTags.PatientId:
                        SetInt32Condition(ref sqlWhereClause, "PatientID",
                                          data[DicomTags.PatientId].GetString(0, string.Empty));
                        break;

                    case DicomTags.PatientsName:
                        SetStringCondition(ref sqlWhereClause, "FullName",
                                           data[DicomTags.PatientsName].GetString(0, string.Empty));
                        break;

                    // Optional matching keys
                    case DicomTags.AccessionNumber:
                        SetInt32Condition(ref sqlWhereClause, "AccessionNumber",
                                          data[DicomTags.AccessionNumber].GetString(0, string.Empty));
                        break;

                    case DicomTags.ReferringPhysiciansName:
                        SetStringCondition(ref sqlWhereClause, "ReferringPhysician",
                                           data[DicomTags.ReferringPhysiciansName].GetString(0, string.Empty));
                        break;

                    default:
                        break;
                    }
                }
            }

            int resultCount = 0;
            try
            {
                _sessionDebug._searchCriteriaDumpString = sqlWhereClause;
                List <ExamsScheduled> list = DBBroker.ExamsScheduled.GetWorkList(sqlWhereClause);
                foreach (ExamsScheduled row in list)
                {
                    if (_cancelReceived)
                    {
                        throw new DicomException("DICOM C-Cancel Received");
                    }

                    resultCount++;
                    if (_maxQueryResponses != -1 &&
                        _maxQueryResponses < resultCount)
                    {
                        SendBufferedResponses(server, presentationID, message, pendingStatus);
                        throw new DicomException("Maximum Configured Query Responses Exceeded: " + resultCount);
                    }

                    DicomMessage response = new DicomMessage();
                    PopulateResponse(response, tagList, row, specificCharacterSet);
                    _responseQueue.Enqueue(response);

                    if (_responseQueue.Count >= _bufferedQueryResponses)
                    {
                        SendBufferedResponses(server, presentationID, message, pendingStatus);
                    }
                }

                SendBufferedResponses(server, presentationID, message, pendingStatus);
                Platform.Log(LogLevel.Info, "All Worklist have been sent successfully.");
            }
            catch (Exception e)
            {
                if (_cancelReceived)
                {
                    DicomMessage errorResponse = new DicomMessage();
                    server.SendCFindResponse(presentationID, message.MessageId, errorResponse,
                                             DicomStatuses.Cancel);
                }
                else if (_maxQueryResponses != -1 &&
                         _maxQueryResponses < resultCount)
                {
                    Platform.Log(LogLevel.Warn, "Maximum Configured Query Responses Exceeded: {0} on query from {1}", resultCount, server.AssociationParams.CallingAE);
                    DicomMessage errorResponse = new DicomMessage();
                    server.SendCFindResponse(presentationID, message.MessageId, errorResponse,
                                             DicomStatuses.QueryRetrieveOutOfResources);
                }
                else
                {
                    Platform.Log(LogLevel.Error, e, "Unexpected exception when processing FIND request.");
                    DicomMessage errorResponse = new DicomMessage();
                    server.SendCFindResponse(presentationID, message.MessageId, errorResponse,
                                             DicomStatuses.QueryRetrieveUnableToProcess);
                }
                return;
            }


            DicomMessage finalResponse = new DicomMessage();
            server.SendCFindResponse(presentationID, message.MessageId, finalResponse, DicomStatuses.Success);
            return;
        }
示例#10
0
        void IDicomServerHandler.OnReceiveRequestMessage(DicomServer server, ServerAssociationParameters association, byte presentationID, DicomMessage message)
        {
            //C-ECHO
            if (message.CommandField == DicomCommandField.CEchoRequest)
            {
                server.SendCEchoResponse(presentationID, message.MessageId, DicomStatuses.Success);
                return;
            }
            //C-Storage
            else if (message.CommandField == DicomCommandField.CStoreRequest)
            {
                String   studyInstanceUid  = null;
                String   seriesInstanceUid = null;
                DicomUid sopInstanceUid;

                bool ok = message.DataSet[DicomTags.SopInstanceUid].TryGetUid(0, out sopInstanceUid);
                if (ok)
                {
                    ok = message.DataSet[DicomTags.SeriesInstanceUid].TryGetString(0, out seriesInstanceUid);
                }
                if (ok)
                {
                    ok = message.DataSet[DicomTags.StudyInstanceUid].TryGetString(0, out studyInstanceUid);
                }

                if (!ok)
                {
                    Logger.LogError("Unable to retrieve UIDs from request message, sending failure status.");

                    server.SendCStoreResponse(presentationID, message.MessageId, sopInstanceUid.UID,
                                              DicomStatuses.ProcessingFailure);
                    return;
                }

                if (!Directory.Exists(StorageScp.StorageLocation))
                {
                    Directory.CreateDirectory(StorageScp.StorageLocation);
                }

                StringBuilder path = new StringBuilder();
                path.AppendFormat("{0}{1}{2}{3}{4}", StorageScp.StorageLocation, Path.DirectorySeparatorChar,
                                  studyInstanceUid, Path.DirectorySeparatorChar, seriesInstanceUid);

                Directory.CreateDirectory(path.ToString());

                path.AppendFormat("{0}{1}.dcm", Path.DirectorySeparatorChar, sopInstanceUid.UID);

                DicomFile dicomFile = new DicomFile(message, path.ToString());

                dicomFile.TransferSyntaxUid            = TransferSyntax.ExplicitVrLittleEndianUid;
                dicomFile.MediaStorageSopInstanceUid   = sopInstanceUid.UID;
                dicomFile.ImplementationClassUid       = DicomImplementation.ClassUID.UID;
                dicomFile.ImplementationVersionName    = DicomImplementation.Version;
                dicomFile.SourceApplicationEntityTitle = association.CallingAE;
                dicomFile.MediaStorageSopClassUid      = message.SopClass.Uid;

                dicomFile.Save(DicomWriteOptions.None);
                #region Database Insert
                String PatientsName = dicomFile.DataSet[DicomTags.PatientsName].GetString(0, "");
                String PatientId    = dicomFile.DataSet[DicomTags.PatientId].GetString(0, "");
                String StudyId      = dicomFile.DataSet[DicomTags.StudyId].GetString(0, "");
                String StudyTime    = dicomFile.DataSet[DicomTags.StudyTime].GetString(0, "");
                String SopClassUid  = dicomFile.DataSet[DicomTags.SopClassUid].GetString(0, "");

                SqlParameter[] sqlParameters = new SqlParameter[] {
                    new SqlParameter("@SopInstanceUid", SqlDbType.VarChar),
                    new SqlParameter("@SqlClassUid", SqlDbType.VarChar),
                    new SqlParameter("@Path", SqlDbType.VarChar),
                    new SqlParameter("@PatientId", SqlDbType.VarChar),
                    new SqlParameter("@PatientsName", SqlDbType.VarChar),
                    new SqlParameter("@StudyId", SqlDbType.VarChar),
                    new SqlParameter("@StudyTime", SqlDbType.VarChar),
                    new SqlParameter("@StudyInstanceUid", SqlDbType.VarChar),
                    new SqlParameter("@SeriesInstanceUid", SqlDbType.VarChar),
                    new SqlParameter("@ImageId", SqlDbType.VarChar)
                };
                sqlParameters[0].Value = sopInstanceUid.ToString();
                sqlParameters[1].Value = SopClassUid;
                sqlParameters[2].Value = path.ToString();
                sqlParameters[3].Value = PatientId;
                sqlParameters[4].Value = PatientsName;
                sqlParameters[5].Value = StudyId;
                sqlParameters[6].Value = StudyTime;
                sqlParameters[7].Value = dicomFile.DataSet[DicomTags.StudyInstanceUid].GetString(0, "");
                sqlParameters[8].Value = dicomFile.DataSet[DicomTags.SeriesInstanceUid].GetString(0, "");
                sqlParameters[9].Value = dicomFile.DataSet[DicomTags.ImageId].GetString(0, "");
                String sql = @"INSERT INTO DICOMLIB VALUES(@SopInstanceUid,@SqlClassUid,@Path,@PatientId,@PatientsName,@StudyId,@StudyTime,@StudyInstanceUid,@SeriesInstanceUid,@ImageId)";
                SqlHelper.ExecuteNonQuery(SqlHelper.GetConnSting(), CommandType.Text, sql, sqlParameters);
                #endregion
                Logger.LogInfo("Received SOP Instance: {0} for patient {1}", sopInstanceUid, PatientsName);
                server.SendCStoreResponse(presentationID, message.MessageId,
                                          sopInstanceUid.UID,
                                          DicomStatuses.Success);
            }
            //C-Find
            else if (message.CommandField == DicomCommandField.CFindRequest)
            {
                //TODO:读取数据库
                //foreach(构造N+1个Message,SendCFindResponse());
                #region 找出筛选条件
                String[] Patameters = new string[4];
                Patameters[0] = message.DataSet[DicomTags.PatientId].ToString();
                Patameters[1] = message.DataSet[DicomTags.PatientsName].ToString();
                Patameters[2] = message.DataSet[DicomTags.StudyId].ToString();
                Patameters[3] = message.DataSet[DicomTags.StudyTime].ToString();
                String level = message.DataSet[DicomTags.QueryRetrieveLevel].ToString();
                String OnlyFliter = ""; Int32 i = 0;
                while (i < 4)
                {
                    if (Patameters[i] != "")
                    {
                        OnlyFliter = Patameters[i]; break;
                    }
                    i++;
                }
                SqlParameter sqlParameter = null;
                String       sql          = "";
                if (OnlyFliter == "")
                {
                    sql = @"SELECT * FROM DICOMLIB";
                }
                else
                {
                    switch (i)
                    {
                    case 0:
                        sqlParameter       = new SqlParameter("@PatientId", SqlDbType.VarChar);
                        sqlParameter.Value = OnlyFliter; sql = @"SELECT * FROM DICOMLIB WHERE PatientId=@PatientId"; break;

                    case 1:
                        sqlParameter       = new SqlParameter("@PatientsName", SqlDbType.VarChar);
                        sqlParameter.Value = OnlyFliter; sql = @"SELECT * FROM DICOMLIB WHERE PatientsName=@PatientsName"; break;

                    case 2:
                        sqlParameter       = new SqlParameter("@StudyId", SqlDbType.VarChar);
                        sqlParameter.Value = OnlyFliter; sql = @"SELECT * FROM DICOMLIB WHERE StudyId=@StudyId"; break;

                    case 3:
                        sqlParameter       = new SqlParameter("@StudyTime", SqlDbType.VarChar);
                        sqlParameter.Value = OnlyFliter; sql = @"SELECT * FROM DICOMLIB WHERE StudyTime=@StudyTime"; break;
                    }
                }

                #endregion
                DataSet      ds          = SqlHelper.ExecuteDataset(SqlHelper.GetConnSting(), CommandType.Text, sql, sqlParameter);
                int          rows        = ds.Tables[0].Rows.Count;
                DicomMessage tempMessage = message;
                for (int mi = 0; mi < rows; mi++)
                {
                    tempMessage.DataSet[DicomTags.PatientsName].SetString(0, ds.Tables[0].Rows[mi]["PatientsName"].ToString());
                    tempMessage.DataSet[DicomTags.PatientId].SetString(0, ds.Tables[0].Rows[mi]["PatientId"].ToString());
                    tempMessage.DataSet[DicomTags.StudyId].SetString(0, ds.Tables[0].Rows[mi]["StudyId"].ToString());
                    tempMessage.DataSet[DicomTags.StudyTime].SetString(0, ds.Tables[0].Rows[mi]["StudyTime"].ToString());
                    tempMessage.DataSet[DicomTags.SopInstanceUid].SetString(0, ds.Tables[0].Rows[mi]["SopInstanceUid"].ToString());
                    tempMessage.DataSet[DicomTags.SopClassUid].SetString(0, ds.Tables[0].Rows[mi]["SqlClassUid"].ToString());
                    tempMessage.DataSet[DicomTags.StudyInstanceUid].SetString(0, ds.Tables[0].Rows[mi]["StudyInstanceUid"].ToString());
                    tempMessage.DataSet[DicomTags.SeriesInstanceUid].SetString(0, ds.Tables[0].Rows[mi]["SeriesInstanceUid"].ToString());
                    tempMessage.DataSet[DicomTags.ImageId].SetString(0, ds.Tables[0].Rows[mi]["ImageId"].ToString());
                    server.SendCFindResponse(presentationID, tempMessage.MessageId, tempMessage, DicomStatuses.Pending);
                }
                server.SendCFindResponse(presentationID, tempMessage.MessageId, tempMessage, DicomStatuses.Success);
            }
            else if (message.CommandField == DicomCommandField.CMoveRequest)
            {
                //检索数据库,找到文件
                //发送
                #region 查询数据库

                String sql = "";

                String       QueryRetrieveLevel = message.DataSet[DicomTags.QueryRetrieveLevel].ToString();
                SqlParameter sqlParameter       = null;
                if (QueryRetrieveLevel == "PATIENT")
                {
                    sqlParameter       = new SqlParameter("@PatientId", SqlDbType.VarChar);
                    sqlParameter.Value = message.DataSet[DicomTags.PatientId].ToString();
                    sql = "SELECT Path FROM DICOMLIB WHERE PatientId = @PatientId";
                }
                else if (QueryRetrieveLevel == "STUDY")
                {
                    sqlParameter       = new SqlParameter("@StudyInstanceUid", SqlDbType.VarChar);
                    sqlParameter.Value = message.DataSet[DicomTags.StudyInstanceUid].ToString();
                    sql = "SELECT Path FROM DICOMLIB WHERE StudyInstanceUid = @StudyInstanceUid";
                }
                else if (QueryRetrieveLevel == "SERIES")
                {
                    sqlParameter       = new SqlParameter("@SeriesInstanceUid", SqlDbType.VarChar);
                    sqlParameter.Value = message.DataSet[DicomTags.SeriesInstanceUid].ToString();
                    sql = "SELECT Path FROM DICOMLIB WHERE SeriesInstanceUid = @SeriesInstanceUid";
                }
                else if (QueryRetrieveLevel == "IMAG")
                {
                    sqlParameter       = new SqlParameter("@ImageId", SqlDbType.VarChar);
                    sqlParameter.Value = message.DataSet[DicomTags.ImageId].ToString();
                    sql = "SELECT Path FROM DICOMLIB WHERE ImageId = @ImageId";
                }
                DataSet ds = SqlHelper.ExecuteDataset(SqlHelper.GetConnSting(), CommandType.Text, sql, sqlParameter);

                #endregion
                DicomFile dicomFile       = new DicomFile(message, message.DataSet[DicomTags.ImageId].ToString());
                String    MoveDestination = message.MoveDestination.ToString();

                StorageScu _storagescu = new StorageScu();
                if (ds.Tables[0].Rows.Count > 0)
                {
                    for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
                    {
                        String path = ds.Tables[0].Rows[i]["Path"].ToString();
                        _storagescu.AddFileToSend(path);
                    }
                    if (MoveDestination == Samples.Properties.Settings.Default.AETs)
                    {
                        _storagescu.Send(Samples.Properties.Settings.Default.ScpAETitle, Properties.Settings.Default.AETs, Properties.Settings.Default.RemoteHost, Properties.Settings.Default.RemotePort);
                    }
                }
                else
                {
                    Logger.LogInfo("NoFiles");
                }
            }
        }
示例#11
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:
                        DicomElementSq    sequence   = attrib as DicomElementSq;
                        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>();
            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);
        }