private void NCreate(MessageType control, DataSet dicom) { if (MessageControl.IsCommand(control)) { Logging.Log("<< N-CREATE-RSP"); AffectedSOPClassUID = (string)dicom[t.AffectedSOPClassUID].Value; AffectedSOPInstanceUID = (string)dicom[t.AffectedSOPInstanceUID].Value; if ((DataSetType)dicom[t.CommandDataSetType].Value == DataSetType.DataSetNotPresent) { completeEvent.Set(); } } else { Logging.Log("<< N-CREATE-RSP-DATA"); if (AffectedSOPClassUID == SOPClass.PresentationLUTSOPClass) { // update the plut } else { Logging.Log("N-CREATE:Unknown SOP class {0}", AffectedSOPClassUID); return; } completeEvent.Set(); } }
public void OnData(MessageType control, Message message) { // TODO put a lock on the pdu array // TODO interpret the commands Logging.Log("CMoveServiceSCU({0}).OnData", Reflection.GetName(typeof(SOPClass), this.SOPClassUId)); DataSet dicom = message.Dicom; if (MessageControl.IsCommand(control)) { ushort status = (ushort)dicom[t.Status].Value; bool last = !(status == 0xFF00); DataSetType present = (DataSetType)dicom[t.CommandDataSetType].Value; Logging.Log("<< {0} {1},{2}", Enum.Parse(typeof(CommandType), dicom[t.CommandField].Value.ToString()), (last) ? "LAST FRAGMENT" : "NOT-LAST FRAGMENT", present.ToString()); //dicom.Dump(); string text = String.Empty; if (dicom.Contains(t.NumberofRemainingSuboperations)) { text += String.Format("remaining={0} ", dicom[t.NumberofRemainingSuboperations].Value); results.Set(t.NumberofRemainingSuboperations, dicom[t.NumberofRemainingSuboperations].Value); } if (dicom.Contains(t.NumberofCompletedSuboperations)) { text += String.Format("completed={0} ", dicom[t.NumberofCompletedSuboperations].Value); results.Set(t.NumberofCompletedSuboperations, dicom[t.NumberofCompletedSuboperations].Value); } if (dicom.Contains(t.NumberofFailedSuboperations)) { text += String.Format("failed={0} ", dicom[t.NumberofFailedSuboperations].Value); results.Set(t.NumberofFailedSuboperations, dicom[t.NumberofFailedSuboperations].Value); } if (dicom.Contains(t.NumberofWarningSuboperations)) { text += String.Format("warning={0} ", dicom[t.NumberofWarningSuboperations].Value); results.Set(t.NumberofWarningSuboperations, dicom[t.NumberofWarningSuboperations].Value); } if (this.ImageMoved != null) { ImageMoved(this, new CMoveEventArgs(dicom)); } Logging.Log(text); if (last) { dicom.Remove(t.NumberofRemainingSuboperations); // TODO do we reset the state to Open here completeEvent.Set(); } } else { Logging.Log("<< P-DATA-TF"); } }
private void NEventReport(MessageType control, DataSet dicom) { if (!MessageControl.IsCommand(control)) { Logging.Log("<< N-EVENT-REPORT-DATA"); if (StorageCommitReport != null) { StorageCommitReport(this, new StorageCommitEventArgs(dicom, StorageCommitEventType.Report)); } PresentationDataValue pdv = new PresentationDataValue(PresentationContextId, Syntaxes[0], MessageType.LastCommand); DataSet fragment = new DataSet(); fragment.Part10Header = false; fragment.Add(t.GroupLength(0), (uint)0); fragment.Add(t.AffectedSOPClassUID, SOPClass.StorageCommitmentPushModelSOPClass); fragment.Add(t.CommandField, (ushort)CommandType.N_EVENT_REPORT_RSP); fragment.Add(t.MessageIdBeingRespondedTo, MessageId); fragment.Add(t.CommandDataSetType, (ushort)DataSetType.DataSetNotPresent); fragment.Add(t.Status, (ushort)0); fragment.Add(t.AffectedSOPInstanceUID, SOPClass.StorageCommitmentPushModelSOPInstance); fragment.Add(t.ActionTypeID, "1"); pdv.Dicom = fragment; PresentationDataPdu request = new PresentationDataPdu(syntaxes[0]); request.Values.Add(pdv); SendPdu("N-EVENT-REPORT-RSP", request); } }
internal bool SendPdu(ServiceClass service, MessageType type, string message, DataSet dicom) { bool result = true; if (State == State.Aborted) { throw AbortException; } if (service != null) { service.LastMessage = null; } dicom.Part10Header = false; dicom.TransferSyntaxUID = MessageControl.IsCommand(type) ? Syntax.ImplicitVrLittleEndian : service.Syntaxes[0]; MemoryStream memory = new MemoryStream(); dicom.Write(memory); byte[] bytes = memory.ToArray(); PresentationDataPdu pdu = null; PresentationDataValue pdv = null; int index = 0; int remaining = (int)memory.Length; int size = this.packetSize - 128; State = (State != State.Closing) ? State.Waiting : State; while (remaining > this.packetSize && result) { pdu = new PresentationDataPdu(service.Syntaxes[0]); pdv = new PresentationDataValue(service.PresentationContextId, service.Syntaxes[0], type, bytes, index, size); pdu.Values.Add(pdv); result = Send(message, pdu); index += size; remaining -= size; } if (result) { pdu = new PresentationDataPdu(service.Syntaxes[0]); pdv = new PresentationDataValue(service.PresentationContextId, service.Syntaxes[0], type + 2, bytes, index, remaining); pdu.Values.Add(pdv); result = Send(message, pdu); } return(result); }
private void NSet(MessageType control, DataSet dicom) { if (MessageControl.IsCommand(control)) { Logging.Log("<< N-SET-RSP"); if ((DataSetType)dicom[t.CommandDataSetType].Value == DataSetType.DataSetNotPresent) { completeEvent.Set(); } } else { Logging.Log("<< N-SET-RSP-DATA"); completeEvent.Set(); } }
private void NCreate(MessageType control, DataSet dicom) { if (MessageControl.IsCommand(control)) { Logging.Log("<< N-CREATE-RQ"); AffectedSOPClassUID = (string)dicom[t.AffectedSOPClassUID].Value; AffectedSOPInstanceUID = (string)dicom[t.AffectedSOPInstanceUID].Value; MessageId = (ushort)dicom[t.MessageId].Value; } else { Logging.Log("<< N-CREATE-DATA"); if (AffectedSOPClassUID == SOPClass.PresentationLUTSOPClass) { //PresentationLUT plut = new PresentationLUT(); //plut.Dicom = dicom; } else { Logging.Log("N-SET: Unknown SOP class {0}", AffectedSOPClassUID); return; } PresentationDataValue pdv = new PresentationDataValue(PresentationContextId, Syntaxes[0], MessageType.LastCommand); DataSet fragment = new DataSet(); fragment.Add(t.GroupLength(0), (uint)0); // fragment.Add(t.AffectedSOPClassUID, AffectedSOPClassUID); // fragment.Add(t.CommandField, (ushort)CommandType.N_CREATE_RSP); // fragment.Add(t.MessageIdBeingRespondedTo, MessageId); fragment.Add(t.CommandDataSetType, (ushort)DataSetType.DataSetNotPresent); // fragment.Add(t.Status, (ushort)0); fragment.Add(t.AffectedSOPInstanceUID, AffectedSOPInstanceUID); pdv.Dicom = fragment; PresentationDataPdu request = new PresentationDataPdu(syntaxes[0]); request.Values.Add(pdv); SendPdu("N-CREATE-RSP", request); } }
public void OnData(MessageType control, Message message) { Logging.Log("PLUTServiceSCU.OnData"); DataSet dicom = message.Dicom; if (MessageControl.IsCommand(control)) { command = (ushort)dicom[t.CommandField].Value; } Logging.Log(String.Format("PLUTServiceSCU.OnData: command={0:x4}", command)); switch ((CommandType)command) { case CommandType.N_CREATE_RSP: NCreate(control, dicom); break; } }
private void NAction(MessageType control, DataSet dicom) { if (MessageControl.IsCommand(control)) { Logging.Log("<< N-ACTION-RQ"); RequestedSOPClassUID = (string)dicom[t.RequestedSOPClassUID].Value; RequestedSOPInstanceUID = (string)dicom[t.RequestedSOPInstanceUID].Value; MessageId = (ushort)dicom[t.MessageId].Value; } else { Logging.Log("<< N-ACTION-DATA"); if (StorageCommitRequest != null) { var args = new StorageCommitEventArgs(dicom, StorageCommitEventType.Request) { CallingAeIpAddress = association.CallingAeIpAddress, CallingAeTitle = association.CallingAeTitle }; StorageCommitRequest(this, args); } PresentationDataValue pdv = new PresentationDataValue(PresentationContextId, Syntaxes[0], MessageType.LastCommand); DataSet fragment = new DataSet(); fragment.Part10Header = false; fragment.TransferSyntaxUID = Syntax.ImplicitVrLittleEndian; fragment.Add(t.GroupLength(0), (uint)0); // fragment.Add(t.CommandField, (ushort)CommandType.N_ACTION_RSP); // fragment.Add(t.MessageIdBeingRespondedTo, MessageId); fragment.Add(t.CommandDataSetType, (ushort)DataSetType.DataSetNotPresent); fragment.Add(t.Status, (ushort)0); pdv.Dicom = fragment; PresentationDataPdu request = new PresentationDataPdu(syntaxes[0]); request.Values.Add(pdv); SendPdu("N-ACTION-RSP", request); } }
public void OnData(MessageType control, Message message) { Logging.Log("AnnotationServiceSCP.OnData"); DataSet dicom = message.Dicom; if (MessageControl.IsCommand(control)) { command = (ushort)dicom[t.CommandField].Value; } switch ((CommandType)command) { case CommandType.N_SET_RQ: NSet(control, dicom); break; case CommandType.N_DELETE_RQ: NDelete(control, dicom); break; } }
public void OnData(MessageType control, Message message) { // TODO put a lock on the pdu array // TODO interpret the commands Logging.Log("CFindServiceSCU({0}).OnData", Reflection.GetName(typeof(SOPClass), this.SOPClassUId)); DataSet dicom = message.Dicom; if (MessageControl.IsCommand(control)) { ushort status = (ushort)dicom[t.Status].Value; bool last = !(status == 0xFF00 || status == 0xFF01); //if (!last && status == 0xFF01) //{ // Logging.Log("Warning that one or more Optional Keys were not supported for existence and/or matching for this Identifier."); //} DataSetType present = (DataSetType)dicom[t.CommandDataSetType].Value; Logging.Log("<< C-FIND-RSP {0},{1}", (last) ? "LAST FRAGMENT" : "NOT-LAST FRAGMENT", present.ToString()); //dicom.Dump(); if (last) { // TODO do we reset the state to Open here completeEvent.Set(); } } else { Logging.Log("<< P-DATA-TF"); if (records == null) { records = new RecordCollection(); } records.Add(dicom.Elements); } }
public void OnData(MessageType control, Message message) { DataSet dicom = message.Dicom; if (MessageControl.IsCommand(control)) { command = (ushort)dicom[t.CommandField].Value; MessageId = (ushort)dicom[t.MessageId].Value; } else { switch ((CommandType)command) { case CommandType.N_EVENT_REPORT_RQ: NEventReport(control, dicom); break; case CommandType.N_ACTION_RQ: NAction(control, dicom); break; } } }
public void OnData(MessageType control, Message message) { Logging.Log("StorageServiceSCP.OnData"); DataSet dicom = message.Dicom; if (MessageControl.IsCommand(control)) { AffectedSOPInstanceUID = (string)dicom[t.AffectedSOPInstanceUID].Value; MessageId = (ushort)dicom[t.MessageId].Value; } else { dicom.Add(t.GroupLength(2), (ulong)0); dicom.Add(t.FileMetaInformationVersion, new byte[] { 0, 1 }); dicom.Add(t.MediaStorageSOPClassUID, this.SOPClassUId); dicom.Add(t.MediaStorageSOPInstanceUID, this.AffectedSOPInstanceUID); dicom.Add(t.TransferSyntaxUID, this.syntaxes[0]); dicom.Add(t.ImplementationClassUID, "1.2.3.4"); dicom.Add(t.ImplementationVersionName, "not specified"); dicom.Part10Header = true; dicom.TransferSyntaxUID = syntaxes[0]; int status = 0x0000; ImageStoredEventArgs image = new ImageStoredEventArgs(dicom); image.CallingAeTitle = association.CallingAeTitle; image.CallingAeIpAddress = association.CallingAeIpAddress; if (ImageStored != null) { try { ImageStored(this, image); if (image.Cancel) { status = 0xC000; } } catch (Exception ex) { status = 0xA700; Logging.Log(LogLevel.Error, String.Format("Exception caught from ImageStored, {0}", ex.Message)); } } #if DEBUG else { string uid = (string)dicom[t.SOPInstanceUID].Value; dicom.Write(uid + ".dcm"); } #endif DataSet response = new DataSet(); response.Add(t.GroupLength(0), (uint)144); // the number is calculated later anyway response.Add(t.AffectedSOPClassUID, this.SOPClassUId); // response.Add(t.CommandField, (ushort)CommandType.C_STORE_RSP); // response.Add(t.MessageIdBeingRespondedTo, MessageId); response.Add(t.CommandDataSetType, (ushort)DataSetType.DataSetNotPresent); // response.Add(t.Status, status); response.Add(t.AffectedSOPInstanceUID, AffectedSOPInstanceUID); SendCommand("C-STORE-RSP", response); } }
public void OnData(MessageType control, Message message) { Logging.Log("MppsServiceSCP.OnData"); DataSet dicom = message.Dicom; if (MessageControl.IsCommand(control)) { command = (ushort)dicom[t.CommandField].Value; SOPInstanceUID = (command == (ushort)CommandType.N_CREATE_RQ) ? (string)dicom[t.AffectedSOPInstanceUID].Value : (string)dicom[t.RequestedSOPInstanceUID].Value; MessageId = (ushort)dicom[t.MessageId].Value; } else { dicom.Add(t.GroupLength(2), (ulong)0); dicom.Add(t.FileMetaInformationVersion, new byte[] { 0, 1 }); dicom.Add(t.MediaStorageSOPClassUID, this.SOPClassUId); dicom.Add(t.MediaStorageSOPInstanceUID, this.SOPInstanceUID); dicom.Add(t.TransferSyntaxUID, this.syntaxes[0]); dicom.Add(t.ImplementationClassUID, "1.2.3.4"); dicom.Add(t.ImplementationVersionName, "not specified"); dicom.Part10Header = true; dicom.TransferSyntaxUID = syntaxes[0]; MppsEventArgs mpps = new MppsEventArgs(SOPInstanceUID, command, dicom); mpps.CallingAeTitle = association.CallingAeTitle; mpps.CallingAeIpAddress = association.CallingAeIpAddress; if (command == (ushort)CommandType.N_CREATE_RQ && MppsCreate != null) { MppsCreate(this, mpps); } else if (command == (ushort)CommandType.N_SET_RQ && MppsSet != null) { MppsSet(this, mpps); } else { string uid = (string)dicom[t.SOPInstanceUID].Value; dicom.Write(uid + ".dcm"); } PresentationDataValue pdv = new PresentationDataValue(PresentationContextId, Syntaxes[0], MessageType.LastCommand); DataSet fragment = new DataSet(); fragment.Add(t.GroupLength(0), (uint)144); // fragment.Add(t.AffectedSOPClassUID, this.SOPClassUId); // fragment.Add(t.CommandField, (ushort)command | 0x8000); // fragment.Add(t.MessageIdBeingRespondedTo, MessageId); fragment.Add(t.CommandDataSetType, (ushort)DataSetType.DataSetNotPresent); // fragment.Add(t.Status, (int)((mpps.Cancel) ? 0xC000 : 0)); fragment.Add(t.AffectedSOPInstanceUID, SOPInstanceUID); pdv.Dicom = fragment; PresentationDataPdu request = new PresentationDataPdu(syntaxes[0]); request.Values.Add(pdv); SendPdu((command == (ushort)CommandType.N_CREATE_RQ) ? "N-CREATE-RSP" : ">> N-SET-RSP", request); } }
public void OnData(MessageType control, Message message) { Logging.Log("\nCMoveServiceSCP({0}).OnData", Reflection.GetName(typeof(SOPClass), this.SOPClassUId)); DataSet dicom = message.Dicom; if (MessageControl.IsCommand(control)) { MessageId = (ushort)dicom[t.MessageId].Value; // TODO accomodate trailing spaces destination = ((string)dicom[t.MoveDestination].Value).TrimEnd(); } else { PresentationDataValue pdv; PresentationDataPdu command; DataSet fragment = new DataSet(); if (!this.Association.Hosts.ContainsKey(destination)) { pdv = new PresentationDataValue(PresentationContextId, Syntaxes[0], MessageType.LastCommand); fragment.Part10Header = false; fragment.TransferSyntaxUID = syntaxes[0]; fragment.Add(t.GroupLength(0), (uint)0); fragment.Add(t.AffectedSOPClassUID, this.SOPClassUId); fragment.Add(t.CommandField, (ushort)CommandType.C_MOVE_RSP); fragment.Add(t.MessageIdBeingRespondedTo, MessageId); fragment.Add(t.CommandDataSetType, (ushort)DataSetType.DataSetNotPresent); fragment.Add(t.Status, (ushort)0xA801); pdv.Dicom = fragment; command = new PresentationDataPdu(syntaxes[0]); command.Values.Add(pdv); SendPdu("C-MOVE-RSP", command); return; } ApplicationEntity host = this.Association.Hosts[destination]; List <string> imagelist = Query(dicom); int failed = 0; for (int n = 0; n < imagelist.Count; n++) { if (!SendImage(host, imagelist[n])) { failed++; } pdv = new PresentationDataValue(PresentationContextId, Syntaxes[0], MessageType.LastCommand); fragment = new DataSet(); fragment.Part10Header = false; fragment.TransferSyntaxUID = syntaxes[0]; fragment.Add(t.GroupLength(0), (uint)0); fragment.Add(t.AffectedSOPClassUID, this.SOPClassUId); fragment.Add(t.CommandField, (ushort)CommandType.C_MOVE_RSP); fragment.Add(t.MessageIdBeingRespondedTo, MessageId); fragment.Add(t.CommandDataSetType, (ushort)DataSetType.DataSetPresent); fragment.Add(t.Status, (ushort)0xff00); fragment.Set(t.NumberofRemainingSuboperations, imagelist.Count - n - 1); fragment.Set(t.NumberofCompletedSuboperations, n + 1 - failed); fragment.Set(t.NumberofFailedSuboperations, failed); fragment.Set(t.NumberofWarningSuboperations, 0); pdv.Dicom = fragment; command = new PresentationDataPdu(syntaxes[0]); command.Values.Add(pdv); SendPdu("C-MOVE-RSP", command); } int status = (failed > 0) ? 0xB000 : 0x0000; pdv = new PresentationDataValue(PresentationContextId, Syntaxes[0], MessageType.LastCommand); fragment = new DataSet(); fragment.Part10Header = false; fragment.TransferSyntaxUID = syntaxes[0]; fragment.Add(t.GroupLength(0), (uint)0); fragment.Add(t.AffectedSOPClassUID, this.SOPClassUId); fragment.Add(t.CommandField, (ushort)CommandType.C_FIND_RSP); fragment.Add(t.MessageIdBeingRespondedTo, MessageId); fragment.Add(t.CommandDataSetType, (ushort)DataSetType.DataSetNotPresent); fragment.Add(t.Status, (ushort)status); fragment.Set(t.NumberofCompletedSuboperations, imagelist.Count); fragment.Set(t.NumberofFailedSuboperations, 0); fragment.Set(t.NumberofWarningSuboperations, 0); pdv.Dicom = fragment; command = new PresentationDataPdu(syntaxes[0]); command.Values.Add(pdv); SendPdu("C-MOVE-RSP", command); } }
public void OnData(MessageType control, Message message) { Logging.Log("\nCFindServiceSCP({0}).OnData", Reflection.GetName(typeof(SOPClass), this.SOPClassUId)); DataSet dicom = message.Dicom; if (MessageControl.IsCommand(control)) { MessageId = (ushort)dicom[t.MessageId].Value; } else { PresentationDataValue pdv; PresentationDataPdu command; DataSet fragment = new DataSet(); RecordCollection worklist; if (Query != null) { QueryEventArgs args = new QueryEventArgs(dicom); Query(this, args); if (args.Cancel) { association.Abort(); return; } worklist = args.Records; } else { worklist = InternalQuery(dicom.Elements); } foreach (Elements procedure in worklist) { fragment = new DataSet(); pdv = new PresentationDataValue(PresentationContextId, Syntaxes[0], MessageType.LastCommand); fragment.Add(t.GroupLength(0), (uint)0); fragment.Add(t.AffectedSOPClassUID, this.SOPClassUId); fragment.Add(t.CommandField, (ushort)CommandType.C_FIND_RSP); fragment.Add(t.MessageIdBeingRespondedTo, MessageId); fragment.Add(t.CommandDataSetType, (ushort)DataSetType.DataSetPresent); fragment.Add(t.Status, (ushort)0xff00); pdv.Dicom = fragment; command = new PresentationDataPdu(syntaxes[0]); command.Values.Add(pdv); PresentationDataValue response = new PresentationDataValue(PresentationContextId, Syntaxes[0], MessageType.LastDataSet); DataSet temp = new DataSet(); temp.Elements = procedure; temp.Part10Header = false; temp.TransferSyntaxUID = syntaxes[0]; response.Dicom = temp; command.Values.Add(response); Logging.Log(command.Dump()); SendPdu("C-FIND-RSP", command); } pdv = new PresentationDataValue(PresentationContextId, Syntaxes[0], MessageType.LastCommand); fragment = new DataSet(); fragment.Add(t.GroupLength(0), (uint)0); fragment.Add(t.AffectedSOPClassUID, this.SOPClassUId); fragment.Add(t.CommandField, (ushort)CommandType.C_FIND_RSP); fragment.Add(t.MessageIdBeingRespondedTo, MessageId); fragment.Add(t.CommandDataSetType, (ushort)DataSetType.DataSetNotPresent); fragment.Add(t.Status, (ushort)0x0000); pdv.Dicom = fragment; command = new PresentationDataPdu(syntaxes[0]); command.Values.Add(pdv); Logging.Log(command.Dump()); SendPdu("C-FIND-RSP", command); } }
private void PduDataReceived(byte[] pdu) { //Logging.Log("PduDataReceived {0}", pdu); //Dump("<< P-DATA-TF", pdu); // TODO this must be able to handle multiple pdvs string syntax = Syntax.ImplicitVrLittleEndian; ServiceClass service = FindServiceClass(pdu[10]); if (service != null) { syntax = service.Syntaxes[0]; } // TODO currently assuming that a Command comes in a single pdu // TODO all DataSet fragments are combined into a single Message if (MessageControl.IsDataSet((MessageType)pdu[11])) { //Logging.Log("dataset"); if (MessageControl.IsNotLast((MessageType)pdu[11])) { //Logging.Log("not last fragment"); if (file == null) { file = new FileStream(Guid.NewGuid().ToString() + ".tmp", FileMode.Create, FileAccess.ReadWrite); //Dump("PduDataReceived1 ...", pdu); } else { //Logging.Log("Receiving {0} bytes", pdu.Length - 12); } file.Write(pdu, 12, pdu.Length - 12); return; } else { //Logging.Log("last fragment"); if (file != null) { Dump("PduDataReceived2 ...", pdu); file.Write(pdu, 12, pdu.Length - 12); file.Flush(); DataSet dicom = new DataSet(); dicom.TransferSyntaxUID = syntax; file.Seek(0, SeekOrigin.Begin); dicom.Read(file); if (service != null) { try { service.LastMessage = new Message(dicom); ((IPresentationDataSink)service).OnData(MessageType.LastDataSet, service.LastMessage); } catch (Exception ex) { Logging.Log(LogLevel.Error, "Exception in OnData for SOPClassUId={0}, {1}", service.SOPClassUId, ex.Message); } } file.Close(); File.Delete(file.Name); file = null; return; } } } // parse response MemoryStream memory = new MemoryStream(pdu, 0, pdu.Length); PresentationDataPdu response = new PresentationDataPdu(syntax); response.Read(memory); response.Dump(); foreach (PresentationDataValue pdv in response.Values) { service = FindServiceClass(pdv.context); if (service != null && service is IPresentationDataSink) { service.LastMessage = new Message(pdv.Dicom); ((IPresentationDataSink)service).OnData(pdv.control, service.LastMessage); } } }