private void SaveDimseToFile(DcmDimseInfo dimse, byte pcid, string fileName) { string path = Path.GetFullPath(fileName); for (int i = 1; File.Exists(path); i++) { path = Path.GetFullPath(fileName); string ext = Path.GetExtension(path); path = path.Substring(0, path.Length - ext.Length); path += String.Format(" ({0})", i); path += ext; } if (String.IsNullOrEmpty(dimse.DatasetFile)) { DcmPresContext pres = Associate.GetPresentationContext(pcid); DicomFileFormat ff = new DicomFileFormat(); ff.FileMetaInfo.FileMetaInformationVersion = DcmFileMetaInfo.Version; ff.FileMetaInfo.MediaStorageSOPClassUID = pres.AbstractSyntax; ff.FileMetaInfo.MediaStorageSOPInstanceUID = dimse.Command.AffectedSOPInstanceUID; ff.FileMetaInfo.TransferSyntax = pres.AcceptedTransferSyntax; ff.FileMetaInfo.ImplementationClassUID = Implementation.ClassUID; ff.FileMetaInfo.ImplementationVersionName = Implementation.Version; ff.FileMetaInfo.SourceApplicationEntityTitle = Associate.CalledAE; ff.Save(fileName, DicomWriteOptions.Default); } long pos = dimse.DatasetStream.Position; using (FileStream fs = File.OpenWrite(fileName)) { fs.Seek(0, SeekOrigin.End); dimse.DatasetStream.Seek(0, SeekOrigin.Begin); StreamUtility.Copy(dimse.DatasetStream, fs); } dimse.DatasetStream.Position = pos; }
private bool ProcessNextPDU() { RawPDU raw = new RawPDU(_network); if (raw.Type == 0x04) { if (_dimse == null) { _dimse = new DcmDimseInfo(); } } try { raw.ReadPDU(); switch (raw.Type) { case 0x01: { _assoc = new DcmAssociate(); AAssociateRQ pdu = new AAssociateRQ(_assoc); pdu.Read(raw); Log.Info("{0} <- Association request:\n{1}", LogID, Associate.ToString()); OnReceiveAssociateRequest(_assoc); return true; } case 0x02: { AAssociateAC pdu = new AAssociateAC(_assoc); pdu.Read(raw); Log.Info("{0} <- Association accept:\n{1}", LogID, Associate.ToString()); OnReceiveAssociateAccept(_assoc); return true; } case 0x03: { AAssociateRJ pdu = new AAssociateRJ(); pdu.Read(raw); Log.Info("{0} <- Association reject [result: {1}; source: {2}; reason: {3}]", LogID, pdu.Result, pdu.Source, pdu.Reason); OnReceiveAssociateReject(pdu.Result, pdu.Source, pdu.Reason); return true; } case 0x04: { PDataTF pdu = new PDataTF(); pdu.Read(raw); //Log.Debug("{0} <- P-Data-TF", LogID); return ProcessPDataTF(pdu); } case 0x05: { AReleaseRQ pdu = new AReleaseRQ(); pdu.Read(raw); Log.Info("{0} <- Association release request", LogID); OnReceiveReleaseRequest(); return true; } case 0x06: { AReleaseRP pdu = new AReleaseRP(); pdu.Read(raw); Log.Info("{0} <- Association release response", LogID); OnReceiveReleaseResponse(); return true; } case 0x07: { AAbort pdu = new AAbort(); pdu.Read(raw); Log.Info("{0} <- Association abort: {1} - {2}", LogID, pdu.Source, pdu.Reason); OnReceiveAbort(pdu.Source, pdu.Reason); return true; } case 0xFF: { return false; } default: throw new DicomNetworkException("Unknown PDU type"); } } catch (SocketException) { throw; } catch (Exception e) { #if DEBUG Log.Error("{0} -> Error reading PDU [type: 0x{1:x2}]: {2}", LogID, raw.Type, e.ToString()); #else Log.Error("{0} -> Error reading PDU [type: 0x{1:x2}]: {2}", LogID, raw.Type, e.Message); #endif OnNetworkError(e); //String file = String.Format(@"{0}\Errors\{1}.pdu", // Dicom.Debug.GetStartDirectory(), DateTime.Now.Ticks); //Directory.CreateDirectory(Dicom.Debug.GetStartDirectory() + @"\Errors"); //raw.Save(file); return false; } }
private bool ProcessPDataTF(PDataTF pdu) { try { byte pcid = 0; foreach (PDV pdv in pdu.PDVs) { pcid = pdv.PCID; if (pdv.IsCommand) { if (_dimse.CommandData == null) _dimse.CommandData = new ChunkStream(); _dimse.CommandData.AddChunk(pdv.Value); if (_dimse.Command == null) { _dimse.Command = new DcmCommand(); } if (_dimse.CommandReader == null) { _dimse.CommandReader = new DicomStreamReader(_dimse.CommandData); _dimse.CommandReader.Dataset = _dimse.Command; } _dimse.CommandReader.Read(null, DicomReadOptions.Default); _dimse.Progress.BytesTransfered += pdv.Value.Length; _dimse.Progress.EstimatedCommandLength = (int)_dimse.CommandReader.BytesEstimated; if (pdv.IsLastFragment) { _dimse.CloseCommand(); bool isLast = true; if (_dimse.Command.Contains(DicomTags.DataSetType)) { if (_dimse.Command.GetUInt16(DicomTags.DataSetType, 0x0101) != 0x0101) { isLast = false; DcmCommandField commandField = (DcmCommandField)_dimse.Command.GetUInt16(DicomTags.CommandField, 0); if (commandField == DcmCommandField.CStoreRequest) { ushort messageID = _dimse.Command.GetUInt16(DicomTags.MessageID, 1); DcmPriority priority = (DcmPriority)_dimse.Command.GetUInt16(DicomTags.Priority, 0); DicomUID affectedInstance = _dimse.Command.GetUID(DicomTags.AffectedSOPInstanceUID); string moveAE = _dimse.Command.GetString(DicomTags.MoveOriginatorApplicationEntityTitle, null); ushort moveMessageID = _dimse.Command.GetUInt16(DicomTags.MoveOriginatorMessageID, 1); OnPreReceiveCStoreRequest(pcid, messageID, affectedInstance, priority, moveAE, moveMessageID, out _dimse.DatasetFile); if (_dimse.DatasetFile != null) { DcmPresContext pres = Associate.GetPresentationContext(pcid); DicomFileFormat ff = new DicomFileFormat(); ff.FileMetaInfo.FileMetaInformationVersion = DcmFileMetaInfo.Version; ff.FileMetaInfo.MediaStorageSOPClassUID = pres.AbstractSyntax; ff.FileMetaInfo.MediaStorageSOPInstanceUID = affectedInstance; ff.FileMetaInfo.TransferSyntax = pres.AcceptedTransferSyntax; ff.FileMetaInfo.ImplementationClassUID = Implementation.ClassUID; ff.FileMetaInfo.ImplementationVersionName = Implementation.Version; ff.FileMetaInfo.SourceApplicationEntityTitle = Associate.CalledAE; ff.Save(_dimse.DatasetFile, DicomWriteOptions.Default); _dimse.DatasetFileStream = new FileStream(_dimse.DatasetFile, FileMode.Open); _dimse.DatasetFileStream.Seek(0, SeekOrigin.End); _dimse.DatasetStream = _dimse.DatasetFileStream; } } } } if (isLast) { if (_dimse.IsNewDimse) OnReceiveDimseBegin(pcid, _dimse.Command, _dimse.Dataset, _dimse.Progress); OnReceiveDimseProgress(pcid, _dimse.Command, _dimse.Dataset, _dimse.Progress); OnReceiveDimse(pcid, _dimse.Command, _dimse.Dataset, _dimse.Progress); ProcessDimse(pcid); _dimse = null; return true; } } } else { if (_dimse.DatasetFile != null) { long pos = _dimse.DatasetFileStream.Position; _dimse.DatasetFileStream.Seek(0, SeekOrigin.End); _dimse.DatasetFileStream.Write(pdv.Value, 0, pdv.Value.Length); _dimse.DatasetFileStream.Position = pos; } else { if (_dimse.DatasetData == null) { _dimse.DatasetData = new ChunkStream(); _dimse.DatasetStream = _dimse.DatasetData; } _dimse.DatasetData.AddChunk(pdv.Value); } if (_dimse.Dataset == null) { DicomTransferSyntax ts = _assoc.GetAcceptedTransferSyntax(pdv.PCID); _dimse.Dataset = new DcmDataset(ts); } if ((EnableStreamParse && !_dimse.Dataset.InternalTransferSyntax.IsDeflate) || pdv.IsLastFragment) { if (_dimse.DatasetReader == null) { if (_dimse.Dataset.InternalTransferSyntax.IsDeflate) { // DicomStreamReader needs a seekable stream MemoryStream ms = StreamUtility.Deflate(_dimse.DatasetStream, false); _dimse.DatasetReader = new DicomStreamReader(ms); } else _dimse.DatasetReader = new DicomStreamReader(_dimse.DatasetStream); _dimse.DatasetReader.Dataset = _dimse.Dataset; } _dimse.Progress.BytesTransfered += pdv.Value.Length; long remaining = _dimse.DatasetReader.BytesRemaining + pdv.Value.Length; if (remaining >= _dimse.DatasetReader.BytesNeeded || pdv.IsLastFragment) { if (_dimse.DatasetReader.Read(null, DicomReadOptions.Default) != DicomReadStatus.Success && pdv.IsLastFragment) { // ??? } _dimse.Progress.EstimatedDatasetLength = (int)_dimse.DatasetReader.BytesEstimated; } } if (pdv.IsLastFragment) { _dimse.Close(); if (_dimse.IsNewDimse) OnReceiveDimseBegin(pcid, _dimse.Command, _dimse.Dataset, _dimse.Progress); OnReceiveDimseProgress(pcid, _dimse.Command, _dimse.Dataset, _dimse.Progress); OnReceiveDimse(pcid, _dimse.Command, _dimse.Dataset, _dimse.Progress); ProcessDimse(pcid); _dimse = null; return true; } } } if (_dimse.IsNewDimse) { OnReceiveDimseBegin(pcid, _dimse.Command, _dimse.Dataset, _dimse.Progress); _dimse.IsNewDimse = false; } else { OnReceiveDimseProgress(pcid, _dimse.Command, _dimse.Dataset, _dimse.Progress); } return true; } catch (Exception e) { #if DEBUG Log.Error("{0} -> Error reading DIMSE: {1}", LogID, e.ToString()); #else Log.Error("{0} -> Error reading DIMSE: {1}", LogID, e.ToString());//e.Message); #endif _dimse.Abort(); _dimse = null; return false; } }
private void Process() { try { OnConnected(); _disableTimeout = false; DateTime timeout = DateTime.Now.AddSeconds(DimseTimeout); while (!_stop) { if (_socket.Poll(1000000, SelectMode.SelectRead)) { if (_socket.Available == 0) break; ProcessNextPDU(); timeout = DateTime.Now.AddSeconds(DimseTimeout); } else if (_disableTimeout) { timeout = DateTime.Now.AddSeconds(DimseTimeout); } else if (DimseTimeout != 0 && DateTime.Now > timeout) { Log.Error("{0} -> DIMSE timeout after {1} seconds", LogID, DimseTimeout); OnDimseTimeout(); _stop = true; } else if (!_socket.Connected) break; } Log.Info("{0} -> Connection closed", LogID); OnConnectionClosed(); } catch (SocketException e) { if (e.SocketErrorCode == SocketError.TimedOut) Log.Error("{0} -> Network timeout after {1} seconds", LogID, SocketTimeout); else Log.Error("{0} -> Network error: {1}", LogID, e.Message); OnNetworkError(e); OnConnectionClosed(); } catch (Exception e) { #if DEBUG Log.Error("{0} -> Processing failure: {1}", LogID, e.ToString()); #else Log.Error("{0} -> Processing failure: {1}", LogID, e.Message); #endif OnNetworkError(e); Log.Info("{0} -> Connection closed", LogID); OnConnectionClosed(); } finally { try { _network.Close(); } catch { } _network = null; try { _socket.Close(); } catch { } _socket = null; _isRunning = false; _dimse = null; } }