protected override void Execute() { DicomMessage store1 = new DicomMessage(DvtkData.Dimse.DimseCommand.CSTORERQ); DicomMessage store2 = new DicomMessage(DvtkData.Dimse.DimseCommand.CSTORERQ); store1.DataSet.Read(DCMCompareForm.firstDCMFile); store2.DataSet.Read(DCMCompareForm.secondDCMFile); Validate(store1, store2, "All other attributes"); }
public void OnReceiveAssociateAccept(DicomClient client, ClientAssociationParameters association) { if (_type == TestTypes.AssociationReject) { Assert.Fail("Unexpected negotiated association on reject test."); } else if (_type == TestTypes.SendMR) { DicomMessage msg = new DicomMessage(); _test.SetupMR(msg.DataSet); byte id = association.FindAbstractSyntaxWithTransferSyntax(msg.SopClass, TransferSyntax.ExplicitVrLittleEndian); client.SendCStoreRequest(id, client.NextMessageID(), DicomPriority.Medium, msg); } else { Assert.Fail("Unexpected test type"); } }
/// <summary> /// Populate at the IMAGE level a response message. /// </summary> /// <param name="request"></param> /// <param name="response"></param> /// <param name="tagList"></param> /// <param name="theInstanceStream"></param> private void PopulateInstance(DicomAttributeCollection request, DicomMessage response, List <uint> tagList, InstanceXml theInstanceStream) { DicomAttributeCollection dataSet = response.DataSet; dataSet[DicomTags.RetrieveAeTitle].SetStringValue(Partition.AeTitle); dataSet[DicomTags.InstanceAvailability].SetStringValue("ONLINE"); DicomAttributeCollection sourceDataSet = theInstanceStream.Collection; if (false == sourceDataSet.Contains(DicomTags.SpecificCharacterSet)) { dataSet[DicomTags.SpecificCharacterSet].SetStringValue(sourceDataSet[DicomTags.SpecificCharacterSet].ToString()); dataSet.SpecificCharacterSet = sourceDataSet[DicomTags.SpecificCharacterSet].ToString(); // this will ensure the data is encoded using the specified character set } foreach (uint tag in tagList) { try { switch (tag) { case DicomTags.PatientId: dataSet[DicomTags.PatientId].SetStringValue(request[DicomTags.PatientId].ToString()); break; case DicomTags.StudyInstanceUid: dataSet[DicomTags.StudyInstanceUid].SetStringValue( request[DicomTags.StudyInstanceUid].ToString()); break; case DicomTags.SeriesInstanceUid: dataSet[DicomTags.SeriesInstanceUid].SetStringValue( request[DicomTags.SeriesInstanceUid].ToString()); break; case DicomTags.QueryRetrieveLevel: dataSet[DicomTags.QueryRetrieveLevel].SetStringValue("IMAGE"); break; default: if (sourceDataSet.Contains(tag)) { dataSet[tag] = sourceDataSet[tag].Copy(); } else { dataSet[tag].SetNullValue(); } 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; } } catch (Exception e) { Platform.Log(LogLevel.Warn, e, "Unexpected error setting tag {0} in C-FIND-RSP", dataSet[tag].Tag.ToString()); dataSet[tag].SetNullValue(); } } }
protected void CreateFilmBox(FilmSession filmSession, FilmBox filmBox) { var referencedFilmSessionSequence = new ReferencedInstanceSequenceIod { ReferencedSopClassUid = SopClass.BasicFilmSessionSopClassUid, ReferencedSopInstanceUid = filmSession.SopInstanceUid.UID }; filmBox.ReferencedFilmSessionSequenceList.Add(referencedFilmSessionSequence); var message = new DicomMessage(null, (DicomAttributeCollection)filmBox.DicomAttributeProvider); this.Client.SendNCreateRequest(null, GetPresentationContextId(this.AssociationParameters), this.Client.NextMessageID(), message, DicomUids.BasicFilmBoxSOP); _eventObject = EventObject.FilmBox; Platform.Log(LogLevel.Debug, "Creating film box..."); }
IDicomFilestreamHandler IDicomServerHandler.OnStartFilestream(DicomServer server, ServerAssociationParameters association, byte presentationId, DicomMessage message) { IDicomScp <TContext> scp = _extensionList[presentationId]; if (message.CommandField == DicomCommandField.CStoreRequest) { _instances.Add(new StorageInstance(message)); } return(scp.OnStartFilestream(server, association, presentationId, message)); }
/// <summary> /// Method to send a DICOM C-ECHO-RSP message. /// </summary> /// <param name="presentationID"></param> /// <param name="messageID"></param> /// <param name="status"></param> public void SendCEchoResponse(byte presentationID, ushort messageID, DicomStatus status) { DicomUid affectedClass = _assoc.GetAbstractSyntax(presentationID); var msg = new DicomMessage { MessageIdBeingRespondedTo = messageID, CommandField = DicomCommandField.CEchoResponse, AffectedSopClassUid = affectedClass.UID, DataSetType = 0x0101, Status = status }; SendDimse(presentationID, msg.CommandSet, null); }
/// <summary> /// Method to send a DICOM C-STORE-RQ message. /// </summary> /// <param name="presentationID"></param> /// <param name="messageID"></param> /// <param name="priority"></param> /// <param name="moveAE"></param> /// <param name="moveMessageID"></param> /// <param name="message"></param> /// <param name="overrideParameters"></param> public void SendCStoreRequest(byte presentationID, ushort messageID, DicomPriority priority, string moveAE, ushort moveMessageID, DicomMessage message, DicomCodecParameters overrideParameters) { DicomUid affectedClass = _assoc.GetAbstractSyntax(presentationID); if (!affectedClass.UID.Equals(message.SopClass.Uid)) throw new DicomException( String.Format( "SOP Class Uid in the message {0} does not match SOP Class UID for presentation context {1}", message.SopClass.Uid, affectedClass.UID)); DicomAttributeCollection command = message.MetaInfo; message.MessageId = messageID; message.CommandField = DicomCommandField.CStoreRequest; message.AffectedSopClassUid = message.SopClass.Uid; message.DataSetType = 0x0202; message.Priority = priority; String sopInstanceUid; bool ok = message.DataSet[DicomTags.SopInstanceUid].TryGetString(0, out sopInstanceUid); if (!ok) throw new DicomException("SOP Instance UID unexpectedly not set in CStore Message being sent."); message.AffectedSopInstanceUid = sopInstanceUid; if (!string.IsNullOrEmpty(moveAE)) { message.MoveOriginatorApplicationEntityTitle = moveAE; message.MoveOriginatorMessageId = moveMessageID; } // Handle compress/decompress if necessary TransferSyntax contextSyntax = _assoc.GetAcceptedTransferSyntax(presentationID); if ((contextSyntax != message.TransferSyntax) && (contextSyntax.Encapsulated || message.TransferSyntax.Encapsulated)) { if (overrideParameters != null) message.ChangeTransferSyntax(contextSyntax, null, overrideParameters); else message.ChangeTransferSyntax(contextSyntax); } SendDimse(presentationID, command, message.DataSet); }
/// <summary> /// Helper for sending N-Create, N-Set, and N-Delete Response messages. /// </summary> /// <param name="commandField">The type of message.</param> /// <param name="presentationId">The presentation context ID to send the message on.</param> /// <param name="messageId">The message ID to use for the message.</param> /// <param name="message">The actual message to send.</param> /// <param name="status">The response message.</param> private void SendNCreateNSetNDeleteHelper(DicomCommandField commandField, byte presentationId, ushort messageId, DicomMessage message, DicomStatus status) { message.CommandField = commandField; message.MessageIdBeingRespondedTo = messageId; message.AffectedSopClassUid = message.AffectedSopClassUid; if (message.DataSet == null || message.DataSet.IsEmpty()) message.DataSetType = 0x0101; else message.DataSetType = 0x0102; message.Status = status; SendDimse(presentationId, message.CommandSet, message.DataSet); }
protected virtual void OnDimseResponseSent(byte pcid, DicomMessage msg) { }
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); Platform.Log(LogLevel.Info, "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); Platform.Log(LogLevel.Info, "Message Dumped :\n" + message.Dump("", DicomDumpOptions.KeepGroupLengthElements)); // checking message for error and anomalies 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; } // wrong status if (mppsIod.PerformedProcedureStepInformation.PerformedProcedureStepStatus != ClearCanvas.Dicom.Iod.Modules.PerformedProcedureStepStatus.InProgress) { server.SendNCreateResponse(presentationID, message.MessageId, new DicomMessage(), DicomStatuses.InvalidAttributeValue); Platform.Log(LogLevel.Error, "Recieved N-Create Request with bad status."); return; } // pps already in cache (duplicated step) string cacheKeyId = message.DataSet[DicomTags.AffectedSopInstanceUid].GetString(0, string.Empty); bool alreadyCached; MPPSScp.CacheMppsEntity(association, cacheKeyId, mppsIod, out alreadyCached); if (alreadyCached) { server.SendNCreateResponse(presentationID, message.MessageId, new DicomMessage(), DicomStatuses.DuplicateSOPInstance); Platform.Log(LogLevel.Error, "Recieved duplicated N-Create Request."); return; } if (!ProcessNCreateRequest(server, presentationID, message)) { server.SendNCreateResponse(presentationID, message.MessageId, new DicomMessage(), DicomStatuses.ProcessingFailure); Platform.Log(LogLevel.Error, "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); Platform.Log(LogLevel.Info, "Message Dumped :\n" + message.Dump("", DicomDumpOptions.KeepGroupLengthElements)); // check if pps already in cache (duplicated step) string cacheKeyId = message.DataSet[DicomTags.AffectedSopInstanceUid].GetString(0, string.Empty); if (!IsMppsEntitycached(association, cacheKeyId)) { server.SendNCreateResponse(presentationID, message.MessageId, new DicomMessage(), DicomStatuses.NoSuchObjectInstance); Platform.Log(LogLevel.Error, "Received Unknown NSset SOP."); return; } // status diffrent from in progress if (mppsIod.PerformedProcedureStepInformation.PerformedProcedureStepStatus == ClearCanvas.Dicom.Iod.Modules.PerformedProcedureStepStatus.InProgress) { server.SendNCreateResponse(presentationID, message.MessageId, new DicomMessage(), DicomStatuses.InvalidAttributeValue); Platform.Log(LogLevel.Error, "Recieved N-Set Request with In Progress status."); return; } // checking the received mppsiod against cached one ModalityPerformedProcedureStepIod cachedMppsIod = GetCachedMppsIod(association, cacheKeyId); //assuming cachedMppsIod not null. 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; } 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(association, cacheKeyId); return; } #endregion //ignore all unsupported request server.SendAssociateAbort(DicomAbortSource.ServiceProvider, DicomAbortReason.UnexpectedPDU); Platform.Log(LogLevel.Info, "Unexpected Command. Send Associate Abort message from server to {0}.", association.CallingAE); return; }
/// <summary> /// This methid generate an XmlElement that contains the data necessary /// to create Performed Series Sequences. /// If modality return /// </summary> /// <param name="message"></param> /// <returns></returns> private static XmlElement GenerateXmlForPerformedSeriesSQ(DicomMessage message, string studyInstanceUID) { #region Sample Generated Node /* * <Root> * <Series> * <Images> * <Image/> * * </Series> * <Series> * <Images> * <Image/> * * </Series> * </Root> */ #endregion XmlDocument dom = new XmlDocument(); XmlElement result = dom.CreateElement("Root"); dom.AppendChild(result); //get StudyIsntanceUID DicomAttribute attribute = message.DataSet[DicomTags.PerformedSeriesSequence]; DicomAttributeSQ seriesSequence = attribute as DicomAttributeSQ; //sequence.Count should be at least 1. for (int i = 0; i < seriesSequence.Count; i++) { DicomSequenceItem seriesSqItem = seriesSequence[i]; System.Xml.XmlNode newSeries; newSeries = dom.CreateElement("Series"); //Set Attributes newSeries.Attributes.Append(dom.CreateAttribute("StudyInstanceUID")).Value = seriesSqItem[DicomTags.StudyInstanceUid].GetString(0, ""); newSeries.Attributes.Append(dom.CreateAttribute("PerformingPhysicianName")).Value = seriesSqItem[DicomTags.PerformingPhysiciansName].GetString(0, ""); string seriesInstanceUID = seriesSqItem[DicomTags.SeriesInstanceUid].GetString(0, DicomUid.GenerateUid().UID); newSeries.Attributes.Append(dom.CreateAttribute("SeriesInstanceUID")).Value = seriesInstanceUID; newSeries.Attributes.Append(dom.CreateAttribute("OperatorName")).Value = seriesSqItem[DicomTags.OperatorsName].GetString(0, ""); newSeries.Attributes.Append(dom.CreateAttribute("ProtocolName")).Value = seriesSqItem[DicomTags.ProtocolName].GetString(0, ""); newSeries.Attributes.Append(dom.CreateAttribute("SeriesDescription")).Value = seriesSqItem[DicomTags.SeriesDescription].GetString(0, ""); newSeries.Attributes.Append(dom.CreateAttribute("RetrieveAET")).Value = seriesSqItem[DicomTags.RetrieveAeTitle].GetString(0, ""); #region loop over Referenced Image Sequence //DicomAttribute referencedImageSQ = seriesSqItem.DataSet[DicomTags.ReferencedImageSequence]; #region ReferencedImageSequence DicomAttributeSQ imagesSequence = (seriesSqItem[DicomTags.ReferencedImageSequence]) as DicomAttributeSQ; for (int j = 0; j < imagesSequence.Count; j++) { DicomSequenceItem imagesSeqItem = imagesSequence[j]; System.Xml.XmlNode newImage; newImage = dom.CreateElement("Image"); //Set Attributes newImage.Attributes.Append(dom.CreateAttribute("SeriesInstanceUID")).Value = seriesInstanceUID; newImage.Attributes.Append(dom.CreateAttribute("ReferencedImageSopClassUID")).Value = imagesSeqItem[DicomTags.ReferencedSopClassUid].GetString(0, ""); newImage.Attributes.Append(dom.CreateAttribute("ReferencedImageSopInstanceUID")).Value = imagesSeqItem[DicomTags.ReferencedSopInstanceUid].GetString(0, DicomUid.GenerateUid().UID); newSeries.AppendChild(newImage); } #endregion #region ReferencedNonImageCompositeSopInstanceSequence DicomAttributeSQ nonImageCompositeSequence = (seriesSqItem[DicomTags.ReferencedNonImageCompositeSopInstanceSequence]) as DicomAttributeSQ; for (int k = 0; k < imagesSequence.Count; k++) { DicomSequenceItem nonImagesCompositeSeqItem = nonImageCompositeSequence[k]; System.Xml.XmlNode newNonImageComposite; newNonImageComposite = dom.CreateElement("Image"); //Set Attributes newNonImageComposite.Attributes.Append(dom.CreateAttribute("SeriesInstanceUID")).Value = seriesInstanceUID; newNonImageComposite.Attributes.Append(dom.CreateAttribute("ReferencedImageSopClassUID")).Value = nonImagesCompositeSeqItem[DicomTags.ReferencedSopClassUid].GetString(0, ""); newNonImageComposite.Attributes.Append(dom.CreateAttribute("ReferencedImageSopInstanceUID")).Value = nonImagesCompositeSeqItem[DicomTags.ReferencedSopInstanceUid].GetString(0, DicomUid.GenerateUid().UID); newSeries.AppendChild(newNonImageComposite); } #endregion #endregion result.AppendChild(newSeries); } return(result); }
private bool ProcessNCreateRequest(DicomServer server, byte presentationID, DicomMessage message) { return(ExamsScheduled.CreateModalityPerformedProcedureStep(message.DataSet[DicomTags.PerformedProcedureStepId].GetInt32(0, 0))); }
private bool ProcessNSetRequestForDiscontinued(DicomServer server, byte presentationID, DicomMessage message, XmlElement performedSeriesSQ) { return(ExamsScheduled.DiscontinueModalityPerformedProcedureStep(message.DataSet[DicomTags.PerformedProcedureStepId].GetInt32(0, 0), performedSeriesSQ)); }
abstract public void Apply(DicomMessage dicomMessage);
/// <summary> /// Called when [receive request 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 virtual void OnReceiveRequestMessage(DicomClient client, ClientAssociationParameters association, byte presentationID, DicomMessage message) { Platform.Log(LogLevel.Error, "Unexpected OnReceiveRequestMessage callback on client."); try { client.SendAssociateAbort(DicomAbortSource.ServiceUser, DicomAbortReason.NotSpecified); } catch (Exception ex) { Platform.Log(LogLevel.Error, ex, "Error aborting association"); } StopRunningOperation(ScuOperationStatus.UnexpectedMessage); throw new Exception("The method or operation is not implemented."); }
/// <summary> /// Called when received response message. This should be overridden by the subclass. /// </summary> /// <remarks>This is where we receive the message back in a CEcho or CFind, and for a CStore, we /// would send additional files if necessary. Note, the subclass should *not* call this method. Perhaps /// this is comfusing with <see cref="OnReceiveAssociateAccept"/> recommended to call the base class.? /// <para>Note, the overridden method in the subclass should call <see cref="StopRunningOperation"/> /// when operation is completed.</para> /// </remarks> /// <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 virtual void OnReceiveResponseMessage(DicomClient client, ClientAssociationParameters association, byte presentationID, DicomMessage message) { throw new NotImplementedException(); }
/// <summary> /// Sends an N-Create Request. /// </summary> /// <param name="affectedSopInstanceUid">The affected sop instance uid.</param> /// <param name="presentationID">The presentation ID.</param> /// <param name="messageID">The message ID.</param> /// <param name="message">The message.</param> /// <param name="affectedClass">The affected class.</param> public void SendNCreateRequest(DicomUid affectedSopInstanceUid, byte presentationID, ushort messageID, DicomMessage message, DicomUid affectedClass) { if (message.DataSet.IsEmpty()) throw new DicomException("Unexpected empty DataSet when sending N-CREATE-RQ."); if (affectedClass == null) affectedClass = _assoc.GetAbstractSyntax(presentationID); message.CommandSet[DicomTags.AffectedSopClassUid].SetStringValue(affectedClass.UID); message.CommandSet[DicomTags.MessageId].SetUInt16(0, messageID); message.CommandSet[DicomTags.CommandField].SetUInt16(0, (ushort) DicomCommandField.NCreateRequest); message.CommandSet[DicomTags.DataSetType].SetUInt16(0, 0x0102); if (affectedSopInstanceUid != null) message.CommandSet[DicomTags.AffectedSopInstanceUid].SetStringValue(affectedSopInstanceUid.UID); SendDimse(presentationID, message.CommandSet, message.DataSet); }
/// <summary> /// Called when received response message. Sets the <see cref="Results"/> property as appropriate. /// </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) { if (message.Status.Status == DicomState.Pending) { // one result sent back, add to result list _results.Add(message.DataSet); if (_maxResults != -1 && !_cancelSent && _results.Count > _maxResults) { client.SendCFindCancelRequest(presentationID, message.MessageIdBeingRespondedTo); _cancelSent = true; } } else { _cancelSent = false; DicomStatus status = DicomStatuses.LookupQueryRetrieve(message.Status.Code); if (status.Status != DicomState.Success) { if (status.Status == DicomState.Cancel) { if (LogInformation) { LogAdapter.Logger.InfoWithFormat("Cancel status received in Find Scu: {0}", status); } Status = ScuOperationStatus.Canceled; } else if (status.Status == DicomState.Failure) { LogAdapter.Logger.ErrorWithFormat("Failure status received in Find Scu: {0}", status); Status = ScuOperationStatus.Failed; FailureDescription = status.ToString(); } else if (status.Status == DicomState.Warning) { LogAdapter.Logger.WarnWithFormat("Warning status received in Find Scu: {0}", status); } else if (Status == ScuOperationStatus.Canceled) { if (LogInformation) { LogAdapter.Logger.Info("Client cancelled Find Scu operation."); } } } else { if (LogInformation) { LogAdapter.Logger.Info("Success status received in Find Scu!"); } } if (!ReuseAssociation) { client.SendReleaseRequest(); StopRunningOperation(); } else { ProgressEvent.Set(); } } }
/// <summary> /// Sends an N-Delete Request. /// </summary> /// <param name="presentationID">The presentation ID.</param> /// <param name="messageID">The message ID.</param> /// <param name="message">The message.</param> public void SendNDeleteRequest(byte presentationID, ushort messageID, DicomMessage message) { message.CommandSet[DicomTags.MessageId].SetUInt16(0, messageID); message.CommandSet[DicomTags.CommandField].SetUInt16(0, (ushort)DicomCommandField.NDeleteRequest); if (message.DataSet == null || message.DataSet.IsEmpty()) message.CommandSet[DicomTags.DataSetType].SetUInt16(0, 0x101); else message.CommandSet[DicomTags.DataSetType].SetUInt16(0, 0x102); SendDimse(presentationID, message.CommandSet, message.DataSet); }
public void OnReceiveRequestMessage(DicomServer server, ServerAssociationParameters association, byte presentationID, DicomMessage message) { if (_type == TestTypes.SendMR) { DicomAttributeCollection testSet = new DicomAttributeCollection(); _test.SetupMR(testSet); bool same = testSet.Equals(message.DataSet); string studyId = message.DataSet[DicomTags.StudyId].GetString(0, ""); Assert.AreEqual(studyId, "1933"); DicomUid sopInstanceUid; bool ok = message.DataSet[DicomTags.SopInstanceUid].TryGetUid(0, out sopInstanceUid); if (!ok) { server.SendAssociateAbort(DicomAbortSource.ServiceUser, DicomAbortReason.NotSpecified); return; } server.SendCStoreResponse(presentationID, message.MessageId, sopInstanceUid.UID, DicomStatuses.Success); } else if (_type == TestTypes.Receive) { DicomUid sopInstanceUid; bool ok = message.DataSet[DicomTags.SopInstanceUid].TryGetUid(0, out sopInstanceUid); if (!ok) { server.SendAssociateAbort(DicomAbortSource.ServiceUser, DicomAbortReason.InvalidPDUParameter); return; } server.SendCStoreResponse(presentationID, message.MessageId, sopInstanceUid.UID, DicomStatuses.Success); } else { Platform.Log(LogLevel.Error, "Unexpected test type mode"); server.SendAssociateAbort(DicomAbortSource.ServiceUser, DicomAbortReason.InvalidPDUParameter); return; } }
protected virtual void OnReceiveDimseResponse(byte pcid, DicomMessage msg) { }
public void OnReceiveResponseMessage(DicomServer server, ServerAssociationParameters association, byte presentationID, DicomMessage message) { server.SendAssociateAbort(DicomAbortSource.ServiceUser, DicomAbortReason.NotSpecified); Assert.Fail("Unexpected OnReceiveResponseMessage"); }
protected virtual void OnDimseSent(byte pcid, DicomAttributeCollection command, DicomAttributeCollection dataset) { var msg = new DicomMessage(command, dataset); DicomCommandField commandField = msg.CommandField; if ((commandField == DicomCommandField.CStoreRequest) || (commandField == DicomCommandField.CCancelRequest) || (commandField == DicomCommandField.CEchoRequest) || (commandField == DicomCommandField.CFindRequest) || (commandField == DicomCommandField.CGetRequest) || (commandField == DicomCommandField.CMoveRequest) || (commandField == DicomCommandField.NActionRequest) || (commandField == DicomCommandField.NCreateRequest) || (commandField == DicomCommandField.NDeleteRequest) || (commandField == DicomCommandField.NEventReportRequest) || (commandField == DicomCommandField.NGetRequest) || (commandField == DicomCommandField.NSetRequest)) { OnDimseRequestSent(pcid, msg); if (MessageSent != null) MessageSent(_assoc, msg); } if ((commandField == DicomCommandField.CStoreResponse) || (commandField == DicomCommandField.CEchoResponse) || (commandField == DicomCommandField.CFindResponse) || (commandField == DicomCommandField.CGetResponse) || (commandField == DicomCommandField.CMoveResponse) || (commandField == DicomCommandField.NActionResponse) || (commandField == DicomCommandField.NCreateResponse) || (commandField == DicomCommandField.NDeleteResponse) || (commandField == DicomCommandField.NEventReportResponse) || (commandField == DicomCommandField.NGetResponse) || (commandField == DicomCommandField.NSetResponse)) { OnDimseResponseSent(pcid, msg); if (MessageSent != null) MessageSent(_assoc, msg); } }
public void OnReceiveRequestMessage(DicomClient client, ClientAssociationParameters association, byte presentationID, DicomMessage message) { Assert.Fail("Incorrectly received OnReceiveRequestMessage callback"); }
/// <summary> /// Method to send a DICOM C-STORE-RQ message. /// </summary> /// <param name="presentationID"></param> /// <param name="messageID"></param> /// <param name="priority"></param> /// <param name="message"></param> /// <param name="overrideParameters"></param> public void SendCStoreRequest(byte presentationID, ushort messageID, DicomPriority priority, DicomMessage message, DicomCodecParameters overrideParameters) { SendCStoreRequest(presentationID, messageID, priority, null, 0, message, overrideParameters); }
public void OnReceiveResponseMessage(DicomClient client, ClientAssociationParameters association, byte presentationID, DicomMessage message) { client.SendReleaseRequest(); Assert.AreEqual(message.Status.Code, DicomStatuses.Success.Code, "Incorrect DICOM status returned"); }
/// <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) { try { this.ResultStatus = message.Status.Status; switch (this.ResultStatus) { case DicomState.Cancel: case DicomState.Pending: case DicomState.Failure: Platform.Log(LogLevel.Error, string.Format("{0} status received in Print Scu response message", message.Status.Status)); this.FailureDescription = SR.MessagePrinterError; this.ReleaseConnection(client); return; case DicomState.Warning: Platform.Log(LogLevel.Warn, string.Format("{0} status received in Print Scu response message", message.Status.Status)); break; case DicomState.Success: break; } EventsHelper.Fire(this.ProgressUpdated, this, new ProgressUpdateEventArgs(_numberOfImageBoxesSent)); if (Canceled) { Platform.Log(LogLevel.Info, "Cancel requested by user. Closing association."); client.SendAssociateAbort(DicomAbortSource.ServiceUser, DicomAbortReason.NotSpecified); return; } Platform.Log(LogLevel.Info, "Success status received in Print Scu"); var affectedUid = new DicomUid(message.AffectedSopInstanceUid, "Instance UID", UidType.SOPInstance); switch (message.CommandField) { case DicomCommandField.NCreateResponse: switch (_eventObject) { case EventObject.FilmSession: _filmSession.OnCreated(affectedUid); break; case EventObject.FilmBox: { var responseFilmBoxModule = new BasicFilmBoxModuleIod(message.DataSet); _filmSession.OnFilmBoxCreated(affectedUid, CollectionUtils.Map<ReferencedInstanceSequenceIod, DicomUid>( responseFilmBoxModule.ReferencedImageBoxSequenceList, imageBoxModule => new DicomUid(imageBoxModule.ReferencedSopInstanceUid, "Instance UID", UidType.SOPInstance) )); } break; } break; case DicomCommandField.NDeleteResponse: switch (_eventObject) { case EventObject.FilmSession: _filmSession.OnDeleted(); this.ReleaseConnection(client); break; case EventObject.FilmBox: _filmSession.OnFilmBoxDeleted(); break; } break; case DicomCommandField.NSetResponse: _numberOfImageBoxesSent++; _filmSession.OnImageBoxSet(affectedUid); break; case DicomCommandField.NActionResponse: _filmSession.OnFilmBoxPrinted(affectedUid); break; default: break; } } catch (Exception ex) { this.FailureDescription = ex.Message; Platform.Log(LogLevel.Error, ex.ToString()); ReleaseConnection(client); throw; } }
/// <summary> /// Method to send a DICOM C-MOVE-RSP message. /// </summary> /// <param name="presentationID"></param> /// <param name="messageID"></param> /// <param name="message"></param> /// <param name="status"></param> /// <param name="numberOfCompletedSubOperations"></param> /// <param name="numberOfRemainingSubOperations"></param> /// <param name="numberOfFailedSubOperations"></param> /// <param name="numberOfWarningSubOperations"></param> public void SendCMoveResponse(byte presentationID, ushort messageID, DicomMessage message, DicomStatus status, ushort numberOfCompletedSubOperations, ushort numberOfRemainingSubOperations, ushort numberOfFailedSubOperations, ushort numberOfWarningSubOperations) { SendCMoveResponse(presentationID, messageID, message, status, numberOfCompletedSubOperations, numberOfRemainingSubOperations, numberOfFailedSubOperations, numberOfWarningSubOperations, string.Empty); }
protected void PrintFilmBox(FilmBox filmBox) { var message = new DicomMessage(null, null) { RequestedSopInstanceUid = filmBox.SopInstanceUid.UID, RequestedSopClassUid = SopClass.BasicFilmBoxSopClassUid, ActionTypeId = 1 }; this.Client.SendNActionRequest(GetPresentationContextId(this.AssociationParameters), this.Client.NextMessageID(), message); _eventObject = EventObject.FilmBox; Platform.Log(LogLevel.Debug, "Printing film box..."); }
/// <summary> /// Sends an N-Get request. /// </summary> /// <param name="requestedSopInstanceUid">The requested sop instance uid.</param> /// <param name="presentationID">The presentation ID.</param> /// <param name="messageID">The message ID.</param> /// <param name="message">The message.</param> public void SendNGetRequest(DicomUid requestedSopInstanceUid, byte presentationID, ushort messageID, DicomMessage message) { if (message.DataSet.IsEmpty()) throw new DicomException("Unexpected empty DataSet when sending N-GET-RQ."); DicomUid affectedClass = _assoc.GetAbstractSyntax(presentationID); message.AffectedSopClassUid = affectedClass.UID; message.MessageId = messageID; message.CommandField = DicomCommandField.NGetRequest; message.DataSetType = 0x0102; message.CommandSet[DicomTags.RequestedSopClassUid].SetStringValue(affectedClass.UID); message.CommandSet[DicomTags.RequestedSopInstanceUid].SetStringValue(requestedSopInstanceUid.UID); SendDimse(presentationID, message.CommandSet, message.DataSet); }
public bool CompleteStream(DicomServer server, ServerAssociationParameters assoc, byte presentationId, DicomMessage message) { DicomProcessingResult result; try { if (_fileStream != null) { _fileStream.Flush(true); _fileStream.Close(); _fileStream.Dispose(); _fileStream = null; } var importer = new SopInstanceImporter(_importContext); result = importer.ImportFile(message, _sourceFilename); if (result.Successful) { if (!String.IsNullOrEmpty(result.AccessionNumber)) { Platform.Log(LogLevel.Info, "Received SOP Instance {0} from {1} to {2} (A#:{3} StudyUid:{4})", result.SopInstanceUid, assoc.CallingAE, assoc.CalledAE, result.AccessionNumber, result.StudyInstanceUid); } else { Platform.Log(LogLevel.Info, "Received SOP Instance {0} from {1} to {2} (StudyUid:{3})", result.SopInstanceUid, assoc.CallingAE, assoc.CalledAE, result.StudyInstanceUid); } } } catch (Exception e) { result = new DicomProcessingResult { DicomStatus = DicomStatuses.ProcessingFailure, ErrorMessage = e.Message }; } if (!result.Successful) { Platform.Log(LogLevel.Warn, "Failure importing sop: {0}", result.ErrorMessage); } CleanupDirectory(); server.SendCStoreResponse(presentationId, message.MessageId, message.AffectedSopInstanceUid, result.DicomStatus); return(true); }
public override bool OnReceiveRequest(DicomServer server, ServerAssociationParameters association, byte presentationID, DicomMessage message) { try { SopInstanceImporterContext context = new SopInstanceImporterContext( String.Format("{0}_{1}", association.CallingAE, association.TimeStamp.ToString("yyyyMMddhhmmss")), association.CallingAE, association.CalledAE); SopInstanceImporter importer = new SopInstanceImporter(context); DicomProcessingResult result = importer.Import(message); if (result.Successful) { if (!String.IsNullOrEmpty(result.AccessionNumber)) { Platform.Log(LogLevel.Info, "Received SOP Instance {0} from {1} to {2} (A#:{3} StudyUid:{4})", result.SopInstanceUid, association.CallingAE, association.CalledAE, result.AccessionNumber, result.StudyInstanceUid); } else { Platform.Log(LogLevel.Info, "Received SOP Instance {0} from {1} to {2} (StudyUid:{3})", result.SopInstanceUid, association.CallingAE, association.CalledAE, result.StudyInstanceUid); } } else { Platform.Log(LogLevel.Warn, "Failure importing sop: {0}", result.ErrorMessage); } server.SendCStoreResponse(presentationID, message.MessageId, message.AffectedSopInstanceUid, result.DicomStatus); return(true); } 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 } }
/// <summary> /// Method to send a DICOM C-MOVE-RSP message. /// </summary> /// <param name="presentationID"></param> /// <param name="messageID"></param> /// <param name="message"></param> /// <param name="status"></param> /// <param name="numberOfCompletedSubOperations"></param> /// <param name="numberOfRemainingSubOperations"></param> /// <param name="numberOfFailedSubOperations"></param> /// <param name="numberOfWarningSubOperations"></param> /// <param name="errorComment">An extended textual error comment. The comment will be truncated to 64 characters. </param> public void SendCMoveResponse(byte presentationID, ushort messageID, DicomMessage message, DicomStatus status, ushort numberOfCompletedSubOperations, ushort numberOfRemainingSubOperations, ushort numberOfFailedSubOperations, ushort numberOfWarningSubOperations, string errorComment) { message.CommandField = DicomCommandField.CMoveResponse; message.Status = status; message.MessageIdBeingRespondedTo = messageID; message.AffectedSopClassUid = _assoc.GetAbstractSyntax(presentationID).UID; message.NumberOfCompletedSubOperations = numberOfCompletedSubOperations; message.NumberOfRemainingSubOperations = numberOfRemainingSubOperations; message.NumberOfFailedSubOperations = numberOfFailedSubOperations; message.NumberOfWarningSubOperations = numberOfWarningSubOperations; message.DataSetType = message.DataSet.IsEmpty() ? (ushort)0x0101 : (ushort)0x0202; if (!string.IsNullOrEmpty(errorComment)) message.ErrorComment = errorComment.Substring(0, (int)Math.Min(DicomVr.LOvr.MaximumLength, errorComment.Length)); SendDimse(presentationID, message.CommandSet, message.DataSet); }
public override bool OnReceiveRequest(DicomServer server, ServerAssociationParameters association, byte presentationId, DicomMessage message) { server.SendCEchoResponse(presentationId, message.MessageId, DicomStatuses.Success); return(true); }
/// <summary> /// Sends an N-Create request, affected class is the one associated with the <paramref name="presentationID"/>. /// </summary> /// <param name="affectedSopInstanceUid">The affected sop instance uid.</param> /// <param name="presentationID">The presentation ID.</param> /// <param name="messageID">The message ID.</param> /// <param name="message">The message.</param> public void SendNCreateRequest(DicomUid affectedSopInstanceUid, byte presentationID, ushort messageID, DicomMessage message) { SendNCreateRequest(affectedSopInstanceUid, presentationID, messageID, message, null); }
/// <summary> /// Called when received response message. Sets the <see cref="Result"/> property as appropriate. /// </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) { if (message.Status.Status != DicomState.Success) { Platform.Log(LogLevel.Error, "Failure status received in sending verification: {0}", message.Status.Description); _verificationResult = VerificationResult.Failed; } else if (_verificationResult == VerificationResult.Canceled) { Platform.Log(LogLevel.Info, "Verification was canceled"); } else { Platform.Log(LogLevel.Info, "Success status received in sending verification!"); _verificationResult = VerificationResult.Success; } client.SendReleaseRequest(); StopRunningOperation(); }
/// <summary> /// Sends an N-Set request. /// </summary> /// <param name="presentationID">The presentation context ID to send the request over.</param> /// <param name="messageID">The message ID.</param> /// <param name="message">The message.</param> public void SendNSetRequest(byte presentationID, ushort messageID, DicomMessage message) { if (message.DataSet.IsEmpty()) throw new DicomException("Unexpected empty DataSet when sending N-SET-RQ."); message.CommandSet[DicomTags.MessageId].SetUInt16(0, messageID); message.CommandSet[DicomTags.CommandField].SetUInt16(0, (ushort)DicomCommandField.NSetRequest); message.CommandSet[DicomTags.DataSetType].SetUInt16(0, 0x0102); SendDimse(presentationID, message.CommandSet, message.DataSet); }
/// <summary> /// Main routine for processing C-MOVE-RQ messages. Called by the <see cref="DicomScp{TContext}" /> component. /// </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) { var 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); } var level = message.DataSet[DicomTags.QueryRetrieveLevel].GetString(0, string.Empty); var remoteAe = message.MoveDestination.Trim(); // load remote device for move information var device = IoC.Get <IDeviceManager>().LookupDevice(Partition, remoteAe); 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 && association.CallingAE.Equals(remoteAe)) { 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 = GetSopListForPatient(message, out errorComment); } else if (level.Equals("STUDY")) { bOnline = GetSopListForStudy(message, out errorComment); } else if (level.Equals("SERIES")) { bOnline = GetSopListForSeries(message, out errorComment); } else if (level.Equals("IMAGE")) { bOnline = GetSopListForInstance(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, ImageStoreEventArgs eventArgs) { StorageInstance instance = eventArgs.StorageInstance; 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 (var 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); }
/// <summary> /// Sends an N-Delete Response. /// </summary> /// <param name="presentationID">The presentation context ID to send the response message on.</param> /// <param name="messageID">The message ID of the request message being responded to.</param> /// <param name="message">The response message to send.</param> /// <param name="status">The status to send in the response message.</param> public void SendNDeleteResponse(byte presentationID, ushort messageID, DicomMessage message, DicomStatus status) { SendNCreateNSetNDeleteHelper(DicomCommandField.NDeleteResponse, presentationID, messageID, message, status); }
protected override void Execute() { if (_presentationContexts.Length != 0) { SendAssociateRq(_presentationContexts); } else { WriteError("There is no presentation context available for proposing."); return; } DulMessage dulMsg = ReceiveAssociateRp(); if (dulMsg is AssociateAc) { AssociateAc assocAc = (AssociateAc)dulMsg; foreach (PresentationContext acceptedPC in assocAc.PresentationContexts) { if (acceptedPC.Result == 0) { string msg = string.Format("Accepted Presentation Context: Abstract Syntax - {0}, Transfer Syntax - {1}", acceptedPC.AbstractSyntax, acceptedPC.TransferSyntax); WriteInformation(msg); string sopClassUid = ""; string sopInstUid = ""; string transferSyntax = ""; foreach (DicomFile dcmFile in _dicomFileCollection) { // Get the SOP Class UID Values values = dcmFile.DataSet["0x00080016"].Values; sopClassUid = values[0]; // Get the SOP Instance UID Values sopClassUidvalues = dcmFile.DataSet["0x00080018"].Values; sopInstUid = sopClassUidvalues[0]; Values transferSyntaxes = dcmFile.FileMetaInformation["0x00020010"].Values; transferSyntax = transferSyntaxes[0]; // try for a match if ((acceptedPC.Result == 0) && (acceptedPC.AbstractSyntax == sopClassUid) && acceptedPC.TransferSyntax == transferSyntax) { DicomMessage storeMsg = new DicomMessage(DvtkData.Dimse.DimseCommand.CSTORERQ, dcmFile.DataSet); string message = string.Format("Sending DICOM object with PC ID - {0}", acceptedPC.ID); WriteInformation(message); System.Diagnostics.Debug.WriteLine(storeMsg.DataSet.Dump("set-")); Send(storeMsg, acceptedPC.ID); DicomMessage rspMsg = ReceiveDicomMessage(); Int32 statusVal = Int32.Parse(rspMsg.CommandSet.GetValues("0x00000900")[0]); if (statusVal == 0) { string infoMsg = string.Format("Image with SOP Instance UID{0} stored successfully.", sopInstUid); WriteInformation(infoMsg); } else { string warnMsg = string.Format("Non-zero status returned. Image with SOP Instance UID{0} storage failed.", sopInstUid); WriteWarning(warnMsg); } } } } else { string resultStr = convertAccResult(acceptedPC.Result); string message = string.Format("Can't store DICOM object with Rejected Abstract Syntax - {0}, PC ID - {1}, Reason - {2}", acceptedPC.AbstractSyntax, acceptedPC.ID, resultStr); WriteWarning(message); } } SendReleaseRq(); ReceiveReleaseRp(); } else if (dulMsg is AssociateRj) { AssociateRj assocRj = (AssociateRj)dulMsg; string msg = string.Format("Association Rejected for proposed presentation contexts:\nResult - {0}({1})\nSource - {2}({3})\nReason - {4}({5})", assocRj.Result, convertResult(assocRj.Result), assocRj.Source, convertSource(assocRj.Source), assocRj.Reason, convertReason(assocRj.Source, assocRj.Reason)); WriteInformation(msg); } else { WriteInformation("Unknown message is received from SCP."); } }
/// <summary> /// Sends an N-Event-Report Response. /// </summary> /// <param name="presentationID">The presentation context ID</param> /// <param name="requestMessage">The message being responsed to.</param> /// <param name="message">The response message to send.</param> /// <param name="status">The status to send.</param> public void SendNEventReportResponse(byte presentationID, DicomMessage requestMessage, DicomMessage message, DicomStatus status) { message.CommandSet[DicomTags.CommandField].SetUInt16(0, (ushort)DicomCommandField.NEventReportResponse); message.CommandSet[DicomTags.MessageIdBeingRespondedTo].SetUInt16(0, requestMessage.MessageId); message.CommandSet[DicomTags.EventTypeId].SetUInt16(0, requestMessage.EventTypeId); message.CommandSet[DicomTags.AffectedSopClassUid].SetStringValue(requestMessage.AffectedSopClassUid); message.CommandSet[DicomTags.AffectedSopInstanceUid].SetStringValue(requestMessage.AffectedSopInstanceUid); message.CommandSet[DicomTags.Status].SetUInt16(0, status.Code); message.CommandSet[DicomTags.DataSetType].SetUInt16(0, 0x0101); SendDimse(presentationID, message.CommandSet, message.DataSet); }
protected override void Execute() { PresentationContext presentationContext = new PresentationContext("1.2.840.10008.1.20.1", // Abstract Syntax Name "1.2.840.10008.1.2"); // Transfer Syntax Name(s) PresentationContext[] presentationContexts = new PresentationContext[1]; presentationContexts[0] = presentationContext; SendAssociateRq(presentationContexts); ReceiveAssociateAc(); if (_nActionMessage != null) { WriteInformation("N-Action Request Information" + "\n" + _nActionMessage.DataSet.Dump("")); Send(_nActionMessage); } ReceiveDicomMessage(); if (_Delay < 0) { // Async storage commitment SendReleaseRq(); ReceiveReleaseRp(); // Start the Storage commit SCP for receiving N-EVENTREPORT EmulateStorageCommitSCP(); } else { string info; if (_Delay == 0) { //Wait for 24 hrs(infinite) int waitingTime = 24 * 60 * 60; _Delay = (short)waitingTime; info = "Waiting forever for N-Event-Report."; } else { info = string.Format("Waiting for N-Event-Report for {0} secs", _Delay); } WriteInformation(info); int waitedTime = 0; if (WaitForPendingDataInNetworkInputBuffer(_Delay * 1000, ref waitedTime)) { DicomMessage nEventReportResponse = ReceiveDicomMessage(); if (nEventReportResponse.CommandSet.DimseCommand == DvtkData.Dimse.DimseCommand.NEVENTREPORTRQ) { // set up the default N-EVENT-REPORT-RSP with a successful status DicomMessage responseMessage = new DicomMessage(DvtkData.Dimse.DimseCommand.NEVENTREPORTRSP); responseMessage.Set("0x00000900", DvtkData.Dimse.VR.US, 0); // send the response this.Send(responseMessage); string msg = "N-Event-Report is received from PACS."; WriteInformation(msg); WriteInformation("N-Event-Report Information\n" + nEventReportResponse.DataSet.Dump("")); SendReleaseRq(); ReceiveReleaseRp(); return; } } else { SendReleaseRq(); ReceiveReleaseRp(); // Start the Storage commit SCP for receiving N-EVENTREPORT EmulateStorageCommitSCP(); } } }
protected virtual void OnDimseRequestSent(byte pcid, DicomMessage msg) { }
private void SendCreateFilmBoxRequest(DicomClient client, ClientAssociationParameters association, DicomMessage responseMessage) { ReferencedInstanceSequenceIod referencedFilmSessionSequence = new ReferencedInstanceSequenceIod(); referencedFilmSessionSequence.ReferencedSopClassUid = SopClass.BasicFilmSessionSopClassUid; referencedFilmSessionSequence.ReferencedSopInstanceUid = responseMessage.AffectedSopInstanceUid; _basicFilmBoxModuleIod.ReferencedFilmSessionSequenceList.Add(referencedFilmSessionSequence); DicomMessage newRequestMessage = new DicomMessage(null, (DicomAttributeCollection)_basicFilmBoxModuleIod.DicomAttributeProvider); byte pcid = association.FindAbstractSyntaxOrThrowException(SopClass.BasicGrayscalePrintManagementMetaSopClass); _nextRequestType = RequestType.ImageBox; client.SendNCreateRequest(DicomUid.GenerateUid(), pcid, client.NextMessageID(), newRequestMessage, DicomUids.BasicFilmBoxSOP); }
private bool OnReceiveDimse(byte pcid, DicomAttributeCollection command, DicomAttributeCollection dataset) { var msg = new DicomMessage(command, dataset); DicomCommandField commandField = msg.CommandField; if ((commandField == DicomCommandField.CStoreRequest) || (commandField == DicomCommandField.CCancelRequest) || (commandField == DicomCommandField.CEchoRequest) || (commandField == DicomCommandField.CFindRequest) || (commandField == DicomCommandField.CGetRequest) || (commandField == DicomCommandField.CMoveRequest) || (commandField == DicomCommandField.NActionRequest) || (commandField == DicomCommandField.NCreateRequest) || (commandField == DicomCommandField.NDeleteRequest) || (commandField == DicomCommandField.NEventReportRequest) || (commandField == DicomCommandField.NGetRequest) || (commandField == DicomCommandField.NSetRequest)) { msg.TransferSyntax = _assoc.GetAcceptedTransferSyntax(pcid); OnReceiveDimseRequest(pcid, msg); if (MessageReceived != null) MessageReceived(_assoc, msg); return true; } if ((commandField == DicomCommandField.CStoreResponse) || (commandField == DicomCommandField.CEchoResponse) || (commandField == DicomCommandField.CFindResponse) || (commandField == DicomCommandField.CGetResponse) || (commandField == DicomCommandField.CMoveResponse) || (commandField == DicomCommandField.NActionResponse) || (commandField == DicomCommandField.NCreateResponse) || (commandField == DicomCommandField.NDeleteResponse) || (commandField == DicomCommandField.NEventReportResponse) || (commandField == DicomCommandField.NGetResponse) || (commandField == DicomCommandField.NSetResponse)) { OnReceiveDimseResponse(pcid, msg); if (MessageReceived != null) MessageReceived(_assoc, msg); return true; } return false; }
private void SendDeleteFilmBoxRequest(DicomClient client, ClientAssociationParameters association, DicomMessage responseMessage) { if (_filmBoxUids.Count == 0) { // no more film boxes left to delete - so send delete film session SendDeleteFilmSessionRequest(client, association); } else { string currentFilmBoxUid = _filmBoxUids[0]; _filmBoxUids.Remove(currentFilmBoxUid); DicomMessage newRequestMessage = new DicomMessage(null, null); newRequestMessage.RequestedSopInstanceUid = currentFilmBoxUid; newRequestMessage.RequestedSopClassUid = SopClass.BasicFilmBoxSopClassUid; newRequestMessage.Priority = DicomPriority.Medium; _nextRequestType = RequestType.DeleteFilmBox; byte pcid = association.FindAbstractSyntaxOrThrowException(SopClass.BasicGrayscalePrintManagementMetaSopClass); client.SendNDeleteRequest(pcid, client.NextMessageID(), newRequestMessage); } }
/// <summary> /// Method to send a DICOM C-ECHO-RQ message. /// </summary> /// <param name="presentationID">The presentation context to send the request on.</param> /// <param name="messageID">The messageID to use.</param> public void SendCEchoRequest(byte presentationID, ushort messageID) { Platform.Log(LogLevel.Info, "Sending C Echo request, pres ID: {0}, messageID = {1}", presentationID, messageID); var msg = new DicomMessage { MessageId = messageID, CommandField = DicomCommandField.CEchoRequest, AffectedSopClassUid = _assoc.GetAbstractSyntax(presentationID).UID, DataSetType = 0x0101 }; SendDimse(presentationID, msg.CommandSet, null); }
/// <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) { try { base.ResultStatus = message.Status.Status; if (message.Status.Status == DicomState.Success) { if (message.CommandField == DicomCommandField.NCreateResponse && message.AffectedSopClassUid == SopClass.BasicFilmSessionSopClassUid) { _filmSessionUid = message.AffectedSopInstanceUid; } else if (message.CommandField == DicomCommandField.NCreateResponse && message.AffectedSopClassUid == SopClass.BasicFilmBoxSopClassUid) { _filmBoxUids.Add(message.AffectedSopInstanceUid); _filmBoxResponseMessages.Add(message.AffectedSopInstanceUid, message.DataSet); } Platform.Log(LogLevel.Info, "Success status received in Printer Status Scu!"); _results = message.DataSet; switch (_nextRequestType) { case RequestType.FilmBox: SendCreateFilmBoxRequest(client, association, message); break; case RequestType.ImageBox: SendSetImageBoxRequest(client, association); break; case RequestType.PrintAction: SendActionPrintRequest(client, association); break; case RequestType.DeleteFilmBox: SendDeleteFilmBoxRequest(client, association, message); break; case RequestType.DeleteFilmSession: SendDeleteFilmSessionRequest(client, association); break; case RequestType.Close: base.ReleaseConnection(client); break; case RequestType.None: default: // TODO: throw error.... break; } } else { // TODO: Handle this... check for warnings - they are OK? throw exception on errors... ? } } catch (Exception ex) { Platform.Log(LogLevel.Error, ex.ToString()); base.ReleaseConnection(client); throw; } }
/// <summary> /// Method to send a DICOM C-STORE-RQ message. /// </summary> /// <param name="presentationID"></param> /// <param name="messageID"></param> /// <param name="priority"></param> /// <param name="message"></param> public void SendCStoreRequest(byte presentationID, ushort messageID, DicomPriority priority, DicomMessage message) { SendCStoreRequest(presentationID, messageID, priority, null, 0, message); }
/// <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(); } }
/// <summary> /// Method to send a DICOM C-STORE-RQ message. /// </summary> /// <param name="presentationID"></param> /// <param name="messageID"></param> /// <param name="priority"></param> /// <param name="moveAE"></param> /// <param name="moveMessageID"></param> /// <param name="message"></param> public void SendCStoreRequest(byte presentationID, ushort messageID, DicomPriority priority, string moveAE, ushort moveMessageID, DicomMessage message) { SendCStoreRequest(presentationID, messageID, priority, moveAE, moveMessageID, message, null); }
void IDicomServerHandler.OnReceiveRequestMessage(DicomServer server, ServerAssociationParameters association, byte presentationID, DicomMessage message) { if (message.CommandField == DicomCommandField.CEchoRequest) { server.SendCEchoResponse(presentationID, message.MessageId, DicomStatuses.Success); return; } String studyInstanceUid = null; String seriesInstanceUid = null; DicomUid sopInstanceUid = null; String patientName = null; String accession = null; String instanceNumber = null; 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) { ok = message.DataSet[DicomTags.PatientsName].TryGetString(0, out patientName); } if (ok) { ok = message.DataSet[DicomTags.AccessionNumber].TryGetString(0, out accession); } if (ok) { ok = message.DataSet[DicomTags.InstanceNumber].TryGetString(0, out instanceNumber); } if (!ok) { Platform.Log(LogLevel.Error, "Unable to retrieve UIDs from request message, sending failure status."); server.SendCStoreResponse(presentationID, message.MessageId, sopInstanceUid.UID, DicomStatuses.ProcessingFailure); return; } TransferSyntax syntax = association.GetPresentationContext(presentationID).AcceptedTransferSyntax; if (List) { Platform.Log(LogLevel.Info, message.Dump()); } if (Bitbucket) { Platform.Log(LogLevel.Debug, "Received SOP Instance: {0} for patient {1} in syntax {2}", sopInstanceUid, patientName, syntax.Name); server.SendCStoreResponse(presentationID, message.MessageId, sopInstanceUid.UID, DicomStatuses.Success); return; } if (!Directory.Exists(StorageLocation)) { Directory.CreateDirectory(StorageLocation); } var path = new StringBuilder(); var series = seriesInstanceUid.Length > 8 ? seriesInstanceUid.Substring(seriesInstanceUid.Length - 8) : seriesInstanceUid; path.AppendFormat("{0}{1}{2}{3}{4}", StorageLocation, Path.DirectorySeparatorChar, accession, Path.DirectorySeparatorChar, series); Directory.CreateDirectory(path.ToString()); path.AppendFormat("{0}{1}.dcm", Path.DirectorySeparatorChar, instanceNumber); var dicomFile = new ClearCanvas.Dicom.DicomFile(message, path.ToString()) { TransferSyntaxUid = syntax.UidString, MediaStorageSopInstanceUid = sopInstanceUid.UID, ImplementationClassUid = DicomImplementation.ClassUID.UID, ImplementationVersionName = DicomImplementation.Version, SourceApplicationEntityTitle = association.CallingAE, MediaStorageSopClassUid = message.SopClass.Uid }; dicomFile.Save(DicomWriteOptions.None); Platform.Log(LogLevel.Debug, "Received SOP Instance: {0} for patient {1} in syntax {2}", sopInstanceUid, patientName, syntax.Name); server.SendCStoreResponse(presentationID, message.MessageId, sopInstanceUid.UID, DicomStatuses.Success); }
public override void OnReceiveRequestMessage(DicomClient client, ClientAssociationParameters association, byte presentationID, DicomMessage message) { try { // We only handle NEventReport request messages if (message.CommandField != DicomCommandField.NEventReportRequest || message.AffectedSopClassUid != SopClass.PrinterSopClassUid) { base.OnReceiveRequestMessage(client, association, presentationID, message); return; } var printerStatus = IodBase.ParseEnum(message.EventTypeId.ToString(), PrinterStatus.None); var printerModule = new PrinterModuleIod(message.DataSet); var logMessage = string.Format("Received NEventReportRequest, Printer Status: {0}, Status Info = {1}", printerStatus, printerModule.PrinterStatusInfo); //Always respond. Client.SendNEventReportResponse(GetPresentationContextId(this.AssociationParameters), message, new DicomMessage(), DicomStatuses.Success); switch (printerStatus) { case PrinterStatus.Failure: Platform.Log(LogLevel.Error, logMessage); this.FailureDescription = SR.MessagePrinterError; this.ReleaseConnection(client); return; case PrinterStatus.Warning: Platform.Log(LogLevel.Warn, logMessage); break; case PrinterStatus.None: case PrinterStatus.Normal: default: Platform.Log(LogLevel.Debug, logMessage); break; } } catch (Exception ex) { this.FailureDescription = ex.Message; Platform.Log(LogLevel.Error, ex.ToString()); ReleaseConnection(client); throw; } }
void IDicomServerHandler.OnReceiveResponseMessage(DicomServer server, ServerAssociationParameters association, byte presentationID, DicomMessage message) { Platform.Log(LogLevel.Error, "Unexpectedly received response mess on server."); server.SendAssociateAbort(DicomAbortSource.ServiceUser, DicomAbortReason.UnrecognizedPDU); }
protected void CreateFilmSession(FilmSession filmSession) { var message = new DicomMessage(null, (DicomAttributeCollection)filmSession.DicomAttributeProvider); this.Client.SendNCreateRequest(null, GetPresentationContextId(this.AssociationParameters), this.Client.NextMessageID(), message, DicomUids.BasicFilmSession); _eventObject = EventObject.FilmSession; Platform.Log(LogLevel.Debug, "Creating film session..."); }
public IDicomFilestreamHandler OnStartFilestream(DicomServer server, ServerAssociationParameters association, byte presentationId, DicomMessage message) { // Should not be called bcause OnReceiveDimseCommand isn't doing anything throw new NotImplementedException(); }
protected void SetImageBox(ImageBox imageBox) { var message = new DicomMessage(null, (DicomAttributeCollection)imageBox.DicomAttributeProvider) { RequestedSopClassUid = this.ColorMode == ColorMode.Color ? SopClass.BasicColorImageBoxSopClassUid : SopClass.BasicGrayscaleImageBoxSopClassUid, RequestedSopInstanceUid = imageBox.SopInstanceUid.UID }; this.Client.SendNSetRequest(GetPresentationContextId(this.AssociationParameters), this.Client.NextMessageID(), message); _eventObject = EventObject.ImageBox; Platform.Log(LogLevel.Debug, "Setting image box {0}...", _numberOfImageBoxesSent); }
/// <summary> /// This method is called after a N-ACTION-RQ message has been received but before it /// (possibly) will be handled by the (zero or more) MessageHandler objects that /// are attached to this object. /// /// Default, nothing is done in this method. Override if needed. /// </summary> /// <param name="dicomMessage">The received N-ACTION-RQ message.</param> protected virtual void BeforeHandlingNActionRequest(DicomMessage dicomMessage) { // Do nothing. }
protected void DeleteFilmSession(FilmSession filmSession) { var message = new DicomMessage(null, null) { RequestedSopInstanceUid = filmSession.SopInstanceUid.UID, RequestedSopClassUid = SopClass.BasicFilmSessionSopClassUid }; this.Client.SendNDeleteRequest(GetPresentationContextId(this.AssociationParameters), this.Client.NextMessageID(), message); _eventObject = EventObject.FilmSession; Platform.Log(LogLevel.Debug, "Deleting film session..."); }
void IDicomServerHandler.OnReceiveResponseMessage(DicomServer server, ServerAssociationParameters association, byte presentationID, DicomMessage message) { LogAdapter.Logger.Error("Unexpectedly received OnReceiveResponseMessage callback from {0} to {1}. Aborting association.", association.CallingAE, association.CalledAE); server.SendAssociateAbort(DicomAbortSource.ServiceUser, DicomAbortReason.UnexpectedPDU); }