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