Ejemplo n.º 1
0
        private static void CacheMppsEntity(ServerAssociationParameters association,
                                            string key,
                                            ModalityPerformedProcedureStepIod ie,
                                            out bool alreadyCached)
        {
            alreadyCached = false;
            ListDictionary mppsAssociationList;

            if (_mppsCache.TryGetValue(association.GetHashCode(), out mppsAssociationList))
            {
                if (mppsAssociationList.Contains(key))
                {
                    alreadyCached = true;
                }
                else
                {
                    mppsAssociationList.Add(key, ie);
                }
            }
            else
            {
                ListDictionary newList = new ListDictionary();
                newList.Add(key, ie);
                _mppsCache.Add(association.GetHashCode(), newList);
            }
        }
Ejemplo n.º 2
0
        private bool CheckNSetDataSetConformance(DicomServer server, ServerAssociationParameters association, byte presentationID,
                                                 ModalityPerformedProcedureStepIod cachedMppsIod,
                                                 ModalityPerformedProcedureStepIod receivedMppsIod, bool logFirstAnomalyOnly)
        {
            bool   anomaly  = false;
            string comments = "";

            try
            {
                do
                {
                    // We are not going to verify sop instance UID neither status - those 2 tests will be done in main processing.

                    #region Character Set
                    if (cachedMppsIod.SopCommon.SpecificCharacterSet != null)
                    {
                        if (receivedMppsIod.SopCommon.SpecificCharacterSet == null)
                        {
                            anomaly   = true;
                            comments += string.Format("Received MPPS Sop instance has no SpecificCharacterSet while it was cached with {0}.\n",
                                                      cachedMppsIod.SopCommon.SpecificCharacterSet);
                            if (logFirstAnomalyOnly)
                            {
                                break;
                            }
                        }
                        if (cachedMppsIod.SopCommon.SpecificCharacterSet != receivedMppsIod.SopCommon.SpecificCharacterSet)
                        {
                            anomaly   = true;
                            comments += "Received MPPS Sop instance has a different SpecificCharacterSet from the one cached .\n";
                            if (logFirstAnomalyOnly)
                            {
                                break;
                            }
                        }
                    }
                    else
                    {
                        if (receivedMppsIod.SopCommon.SpecificCharacterSet != null)
                        {
                            anomaly   = true;
                            comments += "Received MPPS Sop instance has a SpecificCharacterSet while it was cached without.\n";
                            if (logFirstAnomalyOnly)
                            {
                                break;
                            }
                        }
                    }
                    #endregion
                } while (false);

                if (anomaly)
                {
                    Platform.Log(LogLevel.Warn, "Invalid Modality Performed Procedute Step SOP N-SET data received from {0} .",
                                 server.AssociationParams.CallingAE);
                    Platform.Log(LogLevel.Warn, "-- Details : {0}," + comments);
                }
                return(anomaly);
            }
            catch (Exception ex)
            {
                Platform.Log(LogLevel.Error, ex, "Exception Occured while checking the the SOPN-SET data  received from {0} .",
                             server.AssociationParams.CallingAE);
                anomaly = true;
                return(anomaly);
            }
        }
Ejemplo n.º 3
0
        private bool CheckNCreateDataSetConformance(DicomServer server, ServerAssociationParameters association, byte presentationID,
                                                    ModalityPerformedProcedureStepIod mppsIod,
                                                    bool logFirstAnomalyOnly)
        {
            bool   anomaly  = false;
            string comments = "";

            try
            {
                do
                {
                    #region Checking Type 1 Attributes (existance and values)
                    if (mppsIod.PerformedProcedureStepRelationship == null)
                    {
                        anomaly   = true;
                        comments += "Performed Procedure Step Relationship Sequence Absent.\n";
                        if (logFirstAnomalyOnly)
                        {
                            break;
                        }
                    }
                    if (mppsIod.PerformedProcedureStepRelationship.ScheduledStepAttributesSequenceList == null)
                    {
                        anomaly   = true;
                        comments += "Scheduled Step Attributes Sequence Absent.\n";
                        if (logFirstAnomalyOnly)
                        {
                            break;
                        }
                    }
                    if (mppsIod.PerformedProcedureStepRelationship.ScheduledStepAttributesSequenceList.FirstSequenceItem == null)
                    {
                        anomaly   = true;
                        comments += "Scheduled Step Attributes Sequence Empty.\n";
                        if (logFirstAnomalyOnly)
                        {
                            break;
                        }
                    }

                    if (string.IsNullOrEmpty(mppsIod.PerformedProcedureStepRelationship.
                                             ScheduledStepAttributesSequenceList.
                                             FirstSequenceItem.StudyInstanceUid.Trim()))
                    {// we  can add more control here (to check the id root for exmaple).
                        anomaly   = true;
                        comments += "Invalid Study Instance Uid.\n";
                        if (logFirstAnomalyOnly)
                        {
                            break;
                        }
                    }

                    if (mppsIod.PerformedProcedureStepInformation == null)
                    {
                        anomaly   = true;
                        comments += "Performed Procedure Step Information module missing.\n";
                        if (logFirstAnomalyOnly)
                        {
                            break;
                        }
                    }
                    if (mppsIod.PerformedProcedureStepInformation.PerformedProcedureStepId == null)
                    {
                        anomaly   = true;
                        comments += "Performed Procedure StepId missing.\n";
                        if (logFirstAnomalyOnly)
                        {
                            break;
                        }
                    }
                    if (string.IsNullOrEmpty(mppsIod.PerformedProcedureStepInformation.PerformedProcedureStepId))
                    {
                        anomaly   = true;
                        comments += "Performed Procedure Step Information attribute invalid value.\n";
                        if (logFirstAnomalyOnly)
                        {
                            break;
                        }
                    }

                    if (mppsIod.PerformedProcedureStepInformation.PerformedStationAeTitle == null)
                    {
                        anomaly   = true;
                        comments += "Performed Station Ae Title missing.\n";
                        if (logFirstAnomalyOnly)
                        {
                            break;
                        }
                    }
                    if (string.IsNullOrEmpty(mppsIod.PerformedProcedureStepInformation.PerformedStationAeTitle))
                    {
                        anomaly   = true;
                        comments += "Performed Station Ae Title attribute invalid value.\n";
                        if (logFirstAnomalyOnly)
                        {
                            break;
                        }
                    }


                    if (mppsIod.PerformedProcedureStepInformation.PerformedProcedureStepStartDate == null)
                    {
                        anomaly   = true;
                        comments += "Performed Procedure Step Start Date missing.\n";
                        if (logFirstAnomalyOnly)
                        {
                            break;
                        }
                    }

                    if (!mppsIod.DicomAttributeProvider[DicomTags.PerformedProcedureStepStartDate].GetDateTime(0).HasValue)
                    {
                        anomaly   = true;
                        comments += "Performed Procedure Step Start Date invalid value.\n";
                        if (logFirstAnomalyOnly)
                        {
                            break;
                        }
                    }

                    if (mppsIod.DicomAttributeProvider[DicomTags.PerformedProcedureStepStartTime] == null)
                    {
                        anomaly   = true;
                        comments += "Performed Procedure Step Start Time missing.\n";
                        if (logFirstAnomalyOnly)
                        {
                            break;
                        }
                    }
                    if (!mppsIod.DicomAttributeProvider[DicomTags.PerformedProcedureStepStartTime].GetDateTime(0).HasValue)
                    {
                        anomaly   = true;
                        comments += "Performed Procedure Step Start Time invalid value.\n";
                        if (logFirstAnomalyOnly)
                        {
                            break;
                        }
                    }
                    //checking only the status existance
                    if (mppsIod.DicomAttributeProvider[DicomTags.PerformedProcedureStepStatus] == null)
                    {
                        anomaly   = true;
                        comments += "Performed Procedure Step Status Missing.\n";
                        if (logFirstAnomalyOnly)
                        {
                            break;
                        }
                    }

                    if (mppsIod.DicomAttributeProvider[DicomTags.Modality] == null)
                    {
                        anomaly   = true;
                        comments += "Modlity Missing.\n";
                        if (logFirstAnomalyOnly)
                        {
                            break;
                        }
                    }

                    if (mppsIod.DicomAttributeProvider[DicomTags.Modality].GetString(0, "") == "")
                    {
                        anomaly   = true;
                        comments += "Modlity invalid value.\n";
                        if (logFirstAnomalyOnly)
                        {
                            break;
                        }
                    }
                    #endregion

                    #region Check Type 2 attributes
                    // TODO to check all other attributes.

                    if (mppsIod.PerformedProcedureStepRelationship.
                        ScheduledStepAttributesSequenceList.
                        FirstSequenceItem.DicomSequenceItem[DicomTags.ReferencedStudySequence] == null)
                    {// we  can add more control here
                        anomaly   = true;
                        comments += "Referenced Study Sequence Abscent.\n";
                        if (logFirstAnomalyOnly)
                        {
                            break;
                        }
                    }
                    //TODO :  ReferencedStudySequence FirstItem checking
                    { }
                    if (mppsIod.PerformedProcedureStepRelationship.PatientsName == null)
                    {
                        anomaly   = true;
                        comments += "Referenced Study Sequence Abscent.\n";
                        if (logFirstAnomalyOnly)
                        {
                            break;
                        }
                    }
                    //etc..
                    #endregion
                } while (false);

                if (anomaly)
                {
                    Platform.Log(LogLevel.Warn, "Invalid Modality Performed Procedute Step SOP N-CREATE data received from {0} .",
                                 server.AssociationParams.CallingAE);
                    Platform.Log(LogLevel.Warn, "-- Details : {0}," + comments);
                }
                return(anomaly);
            }
            catch (Exception ex)
            {
                Platform.Log(LogLevel.Error, ex, "Exception Occured while checking the mppsIod", mppsIod);

                anomaly = true;
                return(anomaly);
            }
        }
Ejemplo n.º 4
0
        void IDicomServerHandler.OnReceiveRequestMessage(DicomServer server, ServerAssociationParameters association, byte presentationID, DicomMessage message)
        {
            _sessionDebug.SetAssociationDumpString(association);
            _sessionDebug._request = message.Dump();

            #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 MPPS NCreate Request
            if (message.CommandField == DicomCommandField.NCreateRequest)
            {
                // june -1st-2009 :
                // Unlike the "ModalityWorklistIod"  class, the 'partially' implemented ModalityPerformedProcedureStepIod class could
                // be usefull here.

                ModalityPerformedProcedureStepIod mppsIod = new ModalityPerformedProcedureStepIod(message.DataSet);

                Logger.LogInfo("Message Dumped :\n" + message.Dump("", DicomDumpOptions.KeepGroupLengthElements));

                // checking message for error and anomalies

                bool anomalyExist = CheckNCreateDataSetConformance(server, association, presentationID, mppsIod, true);

                if (anomalyExist)
                {
                    server.SendNCreateResponse(presentationID, message.MessageId, new DicomMessage(), DicomStatuses.InvalidAttributeValue);
                    Logger.LogError("Sending Invalid Attributes Response.");
                    return;
                }

                // wrong status
                if (mppsIod.PerformedProcedureStepInformation.PerformedProcedureStepStatus != ClearCanvas.Dicom.Iod.Modules.PerformedProcedureStepStatus.InProgress)
                {
                    server.SendNCreateResponse(presentationID, message.MessageId, new DicomMessage(), DicomStatuses.InvalidAttributeValue);
                    Logger.LogError("Recieved N-Create Request with bad status.");
                    return;
                }
                // pps already in cache (duplicated step)
                string cacheKeyId = message.AffectedSopInstanceUid;
                bool   alreadyCached;
                MPPSScp.CacheMppsEntity(association, cacheKeyId, mppsIod, out alreadyCached);
                if (alreadyCached)
                {
                    server.SendNCreateResponse(presentationID, message.MessageId, new DicomMessage(), DicomStatuses.DuplicateSOPInstance);
                    Logger.LogError("Recieved duplicated N-Create Request.");
                    return;
                }
                if (!ProcessNCreateRequest(server, presentationID, message))
                {
                    server.SendNCreateResponse(presentationID, message.MessageId, new DicomMessage(), DicomStatuses.ProcessingFailure);
                    Logger.LogError("Sending Processing due to NCreate request Failure.");
                    return;
                }
                server.SendNCreateResponse(presentationID, message.MessageId, new DicomMessage(), DicomStatuses.Success);
                return;
            }
            #endregion

            #region MPPS NSet Request
            if (message.CommandField == DicomCommandField.NSetRequest)
            {
                // june -1st-2009 :
                // Unlike the "ModalityWorklistIod"  class, the ModalityPerformedProcedureStepIod is fully implemented
                // we can use it here.
                ModalityPerformedProcedureStepIod mppsIod = new ModalityPerformedProcedureStepIod(message.DataSet);

                Logger.LogInfo("Message Dumped :\n" + message.Dump("", DicomDumpOptions.KeepGroupLengthElements));

                // check if pps already in cache (duplicated step)
                string cacheKeyId = message.RequestedSopInstanceUid;

                if (!IsMppsEntitycached(cacheKeyId))
                {
                    server.SendNCreateResponse(presentationID, message.MessageId, new DicomMessage(), DicomStatuses.NoSuchObjectInstance);
                    Logger.LogError("Received Unknown NSset SOP.");
                    return;
                }

                // status diffrent from in progress
                if (mppsIod.PerformedProcedureStepInformation.PerformedProcedureStepStatus == ClearCanvas.Dicom.Iod.Modules.PerformedProcedureStepStatus.InProgress)
                {
                    server.SendNSetResponse(presentationID, message.MessageId, new DicomMessage(), DicomStatuses.InvalidAttributeValue);
                    Logger.LogError("Recieved N-Set Request with In Progress status.");
                    RemoveMppsEntityFromCache(cacheKeyId);
                    return;
                }

                // checking the received mppsiod against cached one
                ModalityPerformedProcedureStepIod cachedMppsIod = GetCachedMppsIod(cacheKeyId);
                //assuming cachedMppsIod not null.
                bool anomaly = CheckNSetDataSetConformance(server, association, presentationID, cachedMppsIod, mppsIod, true);

                if (anomaly)
                {
                    server.SendNSetResponse(presentationID, message.MessageId, new DicomMessage(), DicomStatuses.InvalidAttributeValue);
                    Logger.LogError("Sending Failure Response.");
                    RemoveMppsEntityFromCache(cacheKeyId);
                    return;
                }

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

                XmlElement performedSeriesSQ = GenerateXmlForPerformedSeriesSQ(message, studyInstanceUID);

                bool success = true;

                if (mppsIod.PerformedProcedureStepInformation.PerformedProcedureStepStatus
                    == ClearCanvas.Dicom.Iod.Modules.PerformedProcedureStepStatus.Completed)
                {
                    success = ProcessNSetRequestForCompleted(server, presentationID, message, performedSeriesSQ);
                }

                if (mppsIod.PerformedProcedureStepInformation.PerformedProcedureStepStatus
                    == ClearCanvas.Dicom.Iod.Modules.PerformedProcedureStepStatus.Discontinued)
                {
                    success = ProcessNSetRequestForDiscontinued(server, presentationID, message, performedSeriesSQ);
                }

                if (success)
                {
                    server.SendNSetResponse(presentationID, message.MessageId, new DicomMessage(), DicomStatuses.Success);
                }
                else
                {
                    server.SendNSetResponse(presentationID, message.MessageId, new DicomMessage(), DicomStatuses.ProcessingFailure);
                }

                MPPSScp.RemoveMppsEntityFromCache(cacheKeyId);

                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;
        }