public PDataTFStream(Stream network, byte pcid, int max) { _network = network; _command = true; _pcid = pcid; _max = (max == 0) ? MaxPduSizeLimit : Math.Min(max, MaxPduSizeLimit); _pdu = new PDataTF(); _buffer = new MemoryStream(_max * 2); }
public PDataTFStream(DicomService service, byte pcid, int max) { _service = service; _command = true; _pcid = pcid; _max = (max == 0) ? MaxPduSizeLimit : Math.Min(max, MaxPduSizeLimit); _pdu = new PDataTF(); _buffer = new MemoryStream((int)_max * 2); }
public PDataTFStream(DicomService service, byte pcid, uint max) { _service = service; _command = true; _pcid = pcid; _pduMax = Math.Min(max, Int32.MaxValue); _max = (_pduMax == 0) ? _service.Options.MaxCommandBuffer : Math.Min(_pduMax, _service.Options.MaxCommandBuffer); _pdu = new PDataTF(); // Max PDU Size - Current Size - Size of PDV header _bytes = new byte[_max - CurrentPduSize() - 6]; }
private void WritePDU(bool last) { if (_pdu.PDVs.Count == 0 || ((CurrentPduSize() + 6) < _max && GetBufferLength() > 0)) { CreatePDV(); } if (_pdu.PDVs.Count > 0) { if (last) { _pdu.PDVs[_pdu.PDVs.Count - 1].IsLastFragment = true; } _service.SendPDU(_pdu); _pdu = new PDataTF(); } }
private void WritePDU(bool last) { if (_length > 0) { CreatePDV(last); } if (_pdu.PDVs.Count > 0) { if (last) { _pdu.PDVs[_pdu.PDVs.Count - 1].IsLastFragment = true; } _service.SendPDU(_pdu); _pdu = new PDataTF(); } }
private void WritePDU(bool last) { if (_pdu.PDVs.Count == 0 || ((CurrentPduSize() + 6) < _max && GetBufferLength() > 0)) { CreatePDV(); } if (_pdu.PDVs.Count > 0) { if (last) { _pdu.PDVs[_pdu.PDVs.Count - 1].IsLastFragment = true; } RawPDU raw = _pdu.Write(); raw.WritePDU(_network); if (OnPduSent != null) { OnPduSent(); } _pdu = new PDataTF(); } }
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 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; } }
/// <summary> /// Process P-DATA-TF PDUs. /// </summary> /// <param name="pdu">PDU to process.</param> private async Task ProcessPDataTFAsync(PDataTF pdu) { try { foreach (var pdv in pdu.PDVs) { if (_dimse == null) { // create stream for receiving command if (_dimseStream == null) { _dimseStream = new MemoryStream(); _dimseStreamFile = null; } } else { // create stream for receiving dataset if (_dimseStream == null) { if (_dimse.Type == DicomCommandField.CStoreRequest) { var pc = Association.PresentationContexts.FirstOrDefault(x => x.ID == pdv.PCID); var file = new DicomFile(); file.FileMetaInfo.MediaStorageSOPClassUID = pc.AbstractSyntax; file.FileMetaInfo.MediaStorageSOPInstanceUID = _dimse.Command.Get<DicomUID>(DicomTag.AffectedSOPInstanceUID); file.FileMetaInfo.TransferSyntax = pc.AcceptedTransferSyntax; file.FileMetaInfo.ImplementationClassUID = Association.RemoteImplemetationClassUID; file.FileMetaInfo.ImplementationVersionName = Association.RemoteImplementationVersion; file.FileMetaInfo.SourceApplicationEntityTitle = Association.CallingAE; CreateCStoreReceiveStream(file); } else { _dimseStream = new MemoryStream(); _dimseStreamFile = null; } } } await this._dimseStream.WriteAsync(pdv.Value, 0, pdv.Value.Length).ConfigureAwait(false); if (pdv.IsLastFragment) { if (pdv.IsCommand) { _dimseStream.Seek(0, SeekOrigin.Begin); var command = new DicomDataset(); var reader = new DicomReader(); reader.IsExplicitVR = false; reader.Read(new StreamByteSource(_dimseStream), new DicomDatasetReaderObserver(command)); _dimseStream = null; _dimseStreamFile = null; var type = command.Get<DicomCommandField>(DicomTag.CommandField); switch (type) { case DicomCommandField.CStoreRequest: _dimse = new DicomCStoreRequest(command); break; case DicomCommandField.CStoreResponse: _dimse = new DicomCStoreResponse(command); break; case DicomCommandField.CFindRequest: _dimse = new DicomCFindRequest(command); break; case DicomCommandField.CFindResponse: _dimse = new DicomCFindResponse(command); break; case DicomCommandField.CMoveRequest: _dimse = new DicomCMoveRequest(command); break; case DicomCommandField.CMoveResponse: _dimse = new DicomCMoveResponse(command); break; case DicomCommandField.CEchoRequest: _dimse = new DicomCEchoRequest(command); break; case DicomCommandField.CEchoResponse: _dimse = new DicomCEchoResponse(command); break; case DicomCommandField.NActionRequest: _dimse = new DicomNActionRequest(command); break; case DicomCommandField.NActionResponse: _dimse = new DicomNActionResponse(command); break; case DicomCommandField.NCreateRequest: _dimse = new DicomNCreateRequest(command); break; case DicomCommandField.NCreateResponse: _dimse = new DicomNCreateResponse(command); break; case DicomCommandField.NDeleteRequest: _dimse = new DicomNDeleteRequest(command); break; case DicomCommandField.NDeleteResponse: _dimse = new DicomNDeleteResponse(command); break; case DicomCommandField.NEventReportRequest: _dimse = new DicomNEventReportRequest(command); break; case DicomCommandField.NEventReportResponse: _dimse = new DicomNEventReportResponse(command); break; case DicomCommandField.NGetRequest: _dimse = new DicomNGetRequest(command); break; case DicomCommandField.NGetResponse: _dimse = new DicomNGetResponse(command); break; case DicomCommandField.NSetRequest: _dimse = new DicomNSetRequest(command); break; case DicomCommandField.NSetResponse: _dimse = new DicomNSetResponse(command); break; default: _dimse = new DicomMessage(command); break; } _dimse.PresentationContext = Association.PresentationContexts.FirstOrDefault(x => x.ID == pdv.PCID); if (!_dimse.HasDataset) { this.PerformDimse(this._dimse); _dimse = null; return; } } else { if (_dimse.Type != DicomCommandField.CStoreRequest) { _dimseStream.Seek(0, SeekOrigin.Begin); var pc = Association.PresentationContexts.FirstOrDefault(x => x.ID == pdv.PCID); _dimse.Dataset = new DicomDataset(); _dimse.Dataset.InternalTransferSyntax = pc.AcceptedTransferSyntax; var source = new StreamByteSource(_dimseStream); source.Endian = pc.AcceptedTransferSyntax.Endian; var reader = new DicomReader(); reader.IsExplicitVR = pc.AcceptedTransferSyntax.IsExplicitVR; reader.Read(source, new DicomDatasetReaderObserver(_dimse.Dataset)); _dimseStream = null; _dimseStreamFile = null; } else { var request = _dimse as DicomCStoreRequest; try { var dicomFile = GetCStoreDicomFile(); _dimseStream = null; _dimseStreamFile = null; // NOTE: dicomFile will be valid with the default implementation of CreateCStoreReceiveStream() and // GetCStoreDicomFile(), but can be null if a child class overrides either method and changes behavior. // See documentation on CreateCStoreReceiveStream() and GetCStoreDicomFile() for information about why // this might be desired. request.File = dicomFile; if (request.File != null) { request.Dataset = request.File.Dataset; } } catch (Exception e) { // failed to parse received DICOM file; send error response instead of aborting connection SendResponse( new DicomCStoreResponse( request, new DicomStatus(DicomStatus.ProcessingFailure, e.Message))); Logger.Error("Error parsing C-Store dataset: {@error}", e); (this as IDicomCStoreProvider).OnCStoreRequestException( _dimseStreamFile != null ? _dimseStreamFile.Name : null, e); return; } } this.PerformDimse(this._dimse); _dimse = null; } } } } catch (Exception e) { SendAbort(DicomAbortSource.ServiceUser, DicomAbortReason.NotSpecified); Logger.Error("Exception processing P-Data-TF PDU: {@error}", e); } finally { SendNextMessage(); } }
private async void ReadAndProcessPDUs() { try { while (this.IsConnected) { // Read PDU header _readLength = 6; var buffer = new byte[6]; var count = await this._network.ReadAsync(buffer, 0, 6).ConfigureAwait(false); do { if (count == 0) { // disconnected this.CloseConnection(null); return; } this._readLength -= count; if (this._readLength > 0) { count = await this._network.ReadAsync(buffer, 6 - this._readLength, this._readLength) .ConfigureAwait(false); } } while (this._readLength > 0); var length = BitConverter.ToInt32(buffer, 2); length = Endian.Swap(length); this._readLength = length; Array.Resize(ref buffer, length + 6); count = await this._network.ReadAsync(buffer, 6, length).ConfigureAwait(false); // Read PDU do { if (count == 0) { // disconnected this.CloseConnection(null); return; } this._readLength -= count; if (this._readLength > 0) { count = await this._network.ReadAsync(buffer, buffer.Length - this._readLength, this._readLength) .ConfigureAwait(false); } } while (this._readLength > 0); var raw = new RawPDU(buffer); switch (raw.Type) { case 0x01: { Association = new DicomAssociation(); var pdu = new AAssociateRQ(Association); pdu.Read(raw); LogID = Association.CallingAE; if (Options.UseRemoteAEForLogName) Logger = LogManager.GetLogger(LogID); Logger.Info( "{callingAE} <- Association request:\n{association}", LogID, Association.ToString()); if (this is IDicomServiceProvider) (this as IDicomServiceProvider).OnReceiveAssociationRequest(Association); break; } case 0x02: { var pdu = new AAssociateAC(Association); pdu.Read(raw); LogID = Association.CalledAE; Logger.Info( "{calledAE} <- Association accept:\n{assocation}", LogID, Association.ToString()); if (this is IDicomServiceUser) (this as IDicomServiceUser).OnReceiveAssociationAccept(Association); break; } case 0x03: { var pdu = new AAssociateRJ(); pdu.Read(raw); Logger.Info( "{logId} <- Association reject [result: {pduResult}; source: {pduSource}; reason: {pduReason}]", LogID, pdu.Result, pdu.Source, pdu.Reason); if (this is IDicomServiceUser) (this as IDicomServiceUser).OnReceiveAssociationReject( pdu.Result, pdu.Source, pdu.Reason); break; } case 0x04: { var pdu = new PDataTF(); pdu.Read(raw); if (Options.LogDataPDUs) Logger.Info("{logId} <- {@pdu}", LogID, pdu); await this.ProcessPDataTFAsync(pdu).ConfigureAwait(false); break; } case 0x05: { var pdu = new AReleaseRQ(); pdu.Read(raw); Logger.Info("{logId} <- Association release request", LogID); if (this is IDicomServiceProvider) (this as IDicomServiceProvider).OnReceiveAssociationReleaseRequest(); break; } case 0x06: { var pdu = new AReleaseRP(); pdu.Read(raw); Logger.Info("{logId} <- Association release response", LogID); if (this is IDicomServiceUser) (this as IDicomServiceUser).OnReceiveAssociationReleaseResponse(); CloseConnection(null); return; } case 0x07: { var pdu = new AAbort(); pdu.Read(raw); Logger.Info( "{logId} <- Abort: {pduSource} - {pduReason}", LogID, pdu.Source, pdu.Reason); if (this is IDicomServiceProvider) (this as IDicomServiceProvider).OnReceiveAbort(pdu.Source, pdu.Reason); else if (this is IDicomServiceUser) (this as IDicomServiceUser).OnReceiveAbort(pdu.Source, pdu.Reason); CloseConnection(null); return; } case 0xFF: { break; } default: throw new DicomNetworkException("Unknown PDU type"); } } } catch (ObjectDisposedException) { // silently ignore CloseConnection(null); } catch (NullReferenceException) { // connection already closed; silently ignore CloseConnection(null); } catch (IOException e) { LogIOException(this.Logger, e, true); CloseConnection(e); } catch (Exception e) { Logger.Error("Exception processing PDU: {@error}", e); CloseConnection(e); } }
private async Task WritePDUAsync(bool last) { if (_length > 0) await CreatePDV(last).ConfigureAwait(false); if (_pdu.PDVs.Count > 0) { if (last) _pdu.PDVs[_pdu.PDVs.Count - 1].IsLastFragment = true; await _service.SendPDUAsync(_pdu).ConfigureAwait(false); _pdu = new PDataTF(); } }
private void EndReadPDU(IAsyncResult result) { try { byte[] buffer = (byte[])result.AsyncState; int count = _network.EndRead(result); if (count == 0) { // disconnected CloseConnection(0); return; } _readLength -= count; if (_readLength > 0) { _network.BeginRead(buffer, buffer.Length - _readLength, _readLength, EndReadPDU, buffer); return; } var raw = new RawPDU(buffer); switch (raw.Type) { case 0x01: { Association = new DicomAssociation(); var pdu = new AAssociateRQ(Association); pdu.Read(raw); LogID = Association.CallingAE; if (Options.UseRemoteAEForLogName) { Logger = LogManager.Default.GetLogger(LogID); } Logger.Info("{0} <- Association request:\n{1}", LogID, Association.ToString()); if (this is IDicomServiceProvider) { (this as IDicomServiceProvider).OnReceiveAssociationRequest(Association); } break; } case 0x02: { var pdu = new AAssociateAC(Association); pdu.Read(raw); LogID = Association.CalledAE; Logger.Info("{0} <- Association accept:\n{1}", LogID, Association.ToString()); if (this is IDicomServiceUser) { (this as IDicomServiceUser).OnReceiveAssociationAccept(Association); } break; } case 0x03: { var pdu = new AAssociateRJ(); pdu.Read(raw); Logger.Info("{0} <- Association reject [result: {1}; source: {2}; reason: {3}]", LogID, pdu.Result, pdu.Source, pdu.Reason); if (this is IDicomServiceUser) { (this as IDicomServiceUser).OnReceiveAssociationReject(pdu.Result, pdu.Source, pdu.Reason); } break; } case 0x04: { var pdu = new PDataTF(); pdu.Read(raw); if (Options.LogDataPDUs) { Logger.Info("{0} <- {1}", LogID, pdu); } _processQueue.Queue(ProcessPDataTF, pdu); break; } case 0x05: { var pdu = new AReleaseRQ(); pdu.Read(raw); Logger.Info("{0} <- Association release request", LogID); if (this is IDicomServiceProvider) { (this as IDicomServiceProvider).OnReceiveAssociationReleaseRequest(); } break; } case 0x06: { var pdu = new AReleaseRP(); pdu.Read(raw); Logger.Info("{0} <- Association release response", LogID); if (this is IDicomServiceUser) { (this as IDicomServiceUser).OnReceiveAssociationReleaseResponse(); } CloseConnection(0); break; } case 0x07: { var pdu = new AAbort(); pdu.Read(raw); Logger.Info("{0} <- Abort: {1} - {2}", LogID, pdu.Source, pdu.Reason); if (this is IDicomServiceProvider) { (this as IDicomServiceProvider).OnReceiveAbort(pdu.Source, pdu.Reason); } else if (this is IDicomServiceUser) { (this as IDicomServiceUser).OnReceiveAbort(pdu.Source, pdu.Reason); } CloseConnection(0); break; } case 0xFF: { break; } default: throw new DicomNetworkException("Unknown PDU type"); } BeginReadPDUHeader(); } catch (IOException e) { int error = 0; if (e.InnerException is SocketException) { error = (e.InnerException as SocketException).ErrorCode; Logger.Error("Socket error while reading PDU: {0} [{1}]", (e.InnerException as SocketException).SocketErrorCode, (e.InnerException as SocketException).ErrorCode); } else if (!(e.InnerException is ObjectDisposedException)) { Logger.Error("IO exception while reading PDU: {0}", e.ToString()); } CloseConnection(error); } catch (NullReferenceException) { // connection already closed; silently ignore CloseConnection(0); } catch (Exception e) { Logger.Error("Exception processing PDU: {0}", e.ToString()); CloseConnection(0); } }
private void WritePDU(bool last) { if (_pdu.PDVs.Count == 0 || ((CurrentPduSize() + 6) < _max && GetBufferLength() > 0)) { CreatePDV(); } if (_pdu.PDVs.Count > 0) { if (last) { _pdu.PDVs[_pdu.PDVs.Count - 1].IsLastFragment = true; } RawPDU raw = _pdu.Write(); raw.WritePDU(_network); if (OnPduSent != null) OnPduSent(); _pdu = new PDataTF(); } }
private void EndReadPDU(IAsyncResult result) { try { byte[] buffer = (byte[])result.AsyncState; int count = _network.EndRead(result); if (count == 0) { // disconnected CloseConnection(0); return; } _readLength -= count; if (_readLength > 0) { _network.BeginRead(buffer, buffer.Length - _readLength, _readLength, EndReadPDU, buffer); return; } var raw = new RawPDU(buffer); switch (raw.Type) { case 0x01: { Association = new DicomAssociation(); var pdu = new AAssociateRQ(Association); pdu.Read(raw); LogID = Association.CallingAE; Logger.Log(LogLevel.Info, "{0} <- Association request:\n{1}", LogID, Association.ToString()); if (this is IDicomServiceProvider) (this as IDicomServiceProvider).OnReceiveAssociationRequest(Association); break; } case 0x02: { var pdu = new AAssociateAC(Association); pdu.Read(raw); LogID = Association.CalledAE; Logger.Log(LogLevel.Info, "{0} <- Association accept:\n{1}", LogID, Association.ToString()); if (this is IDicomServiceUser) (this as IDicomServiceUser).OnReceiveAssociationAccept(Association); break; } case 0x03: { var pdu = new AAssociateRJ(); pdu.Read(raw); Logger.Log(LogLevel.Info, "{0} <- Association reject [result: {1}; source: {2}; reason: {3}]", LogID, pdu.Result, pdu.Source, pdu.Reason); if (this is IDicomServiceUser) (this as IDicomServiceUser).OnReceiveAssociationReject(pdu.Result, pdu.Source, pdu.Reason); break; } case 0x04: { var pdu = new PDataTF(); pdu.Read(raw); if (Options.LogDataPDUs) Logger.Info("{0} <- {1}", LogID, pdu); _processQueue.Queue(ProcessPDataTF, pdu); break; } case 0x05: { var pdu = new AReleaseRQ(); pdu.Read(raw); Logger.Log(LogLevel.Info, "{0} <- Association release request", LogID); if (this is IDicomServiceProvider) (this as IDicomServiceProvider).OnReceiveAssociationReleaseRequest(); break; } case 0x06: { var pdu = new AReleaseRP(); pdu.Read(raw); Logger.Log(LogLevel.Info, "{0} <- Association release response", LogID); if (this is IDicomServiceUser) (this as IDicomServiceUser).OnReceiveAssociationReleaseResponse(); CloseConnection(0); break; } case 0x07: { var pdu = new AAbort(); pdu.Read(raw); Logger.Log(LogLevel.Info, "{0} <- Abort: {1} - {2}", LogID, pdu.Source, pdu.Reason); if (this is IDicomServiceProvider) (this as IDicomServiceProvider).OnReceiveAbort(pdu.Source, pdu.Reason); else if (this is IDicomServiceUser) (this as IDicomServiceUser).OnReceiveAbort(pdu.Source, pdu.Reason); CloseConnection(0); break; } case 0xFF: { break; } default: throw new DicomNetworkException("Unknown PDU type"); } BeginReadPDUHeader(); } catch (IOException e) { int error = 0; if (e.InnerException is SocketException) { error = (e.InnerException as SocketException).ErrorCode; Logger.Error("Socket error while reading PDU: {0} [{1}]", (e.InnerException as SocketException).SocketErrorCode, (e.InnerException as SocketException).ErrorCode); } else if (!(e.InnerException is ObjectDisposedException)) Logger.Error("IO exception while reading PDU: {0}", e.ToString()); CloseConnection(error); } catch (Exception e) { Logger.Log(LogLevel.Error, "Exception processing PDU: {0}", e.ToString()); CloseConnection(0); } }
private void ProcessPDataTF(PDataTF pdu) { try { foreach (var pdv in pdu.PDVs) { if (_dimse == null) { // create stream for receiving command if (_dimseStream == null) { _dimseStream = new MemoryStream(); } } else { // create stream for receiving dataset if (_dimseStream == null) { if (_dimse.Type == DicomCommandField.CStoreRequest) { var pc = Association.PresentationContexts.FirstOrDefault(x => x.ID == pdv.PCID); var file = new DicomFile(); file.FileMetaInfo.MediaStorageSOPClassUID = pc.AbstractSyntax; file.FileMetaInfo.MediaStorageSOPInstanceUID = _dimse.Command.Get <DicomUID>(DicomTag.AffectedSOPInstanceUID); file.FileMetaInfo.TransferSyntax = pc.AcceptedTransferSyntax; file.FileMetaInfo.ImplementationClassUID = Association.RemoteImplemetationClassUID; file.FileMetaInfo.ImplementationVersionName = Association.RemoteImplementationVersion; file.FileMetaInfo.SourceApplicationEntityTitle = Association.CallingAE; string fileName; if (this is IDicomCStoreProvider) { fileName = (this as IDicomCStoreProvider).GetTempFileName(file.FileMetaInfo.MediaStorageSOPInstanceUID); } else { throw new DicomNetworkException("C-Store SCP not implemented"); } file.Save(fileName); _dimseStream = File.OpenWrite(fileName); _dimseStream.Seek(0, SeekOrigin.End); } else { _dimseStream = new MemoryStream(); } } } _dimseStream.Write(pdv.Value, 0, pdv.Value.Length); if (pdv.IsLastFragment) { if (pdv.IsCommand) { _dimseStream.Seek(0, SeekOrigin.Begin); var command = new DicomDataset(); var reader = new DicomReader(); reader.IsExplicitVR = false; reader.Read(new StreamByteSource(_dimseStream), new DicomDatasetReaderObserver(command)); _dimseStream = null; var type = command.Get <DicomCommandField>(DicomTag.CommandField); switch (type) { case DicomCommandField.CStoreRequest: _dimse = new DicomCStoreRequest(command); break; case DicomCommandField.CStoreResponse: _dimse = new DicomCStoreResponse(command); break; case DicomCommandField.CFindRequest: _dimse = new DicomCFindRequest(command); break; case DicomCommandField.CFindResponse: _dimse = new DicomCFindResponse(command); break; case DicomCommandField.CMoveRequest: _dimse = new DicomCMoveRequest(command); break; case DicomCommandField.CMoveResponse: _dimse = new DicomCMoveResponse(command); break; case DicomCommandField.CEchoRequest: _dimse = new DicomCEchoRequest(command); break; case DicomCommandField.CEchoResponse: _dimse = new DicomCEchoResponse(command); break; default: _dimse = new DicomMessage(command); break; } if (!_dimse.HasDataset) { ThreadPool.QueueUserWorkItem(PerformDimseCallback, _dimse); _dimse = null; return; } } else { if (_dimse.Type != DicomCommandField.CStoreRequest) { _dimseStream.Seek(0, SeekOrigin.Begin); _dimse.Dataset = new DicomDataset(); _dimse.Dataset.InternalTransferSyntax = _dimse.Command.InternalTransferSyntax; var source = new StreamByteSource(_dimseStream); source.Endian = _dimse.Command.InternalTransferSyntax.Endian; var reader = new DicomReader(); reader.IsExplicitVR = _dimse.Command.InternalTransferSyntax.IsExplicitVR; reader.Read(source, new DicomDatasetReaderObserver(_dimse.Dataset)); _dimseStream = null; } else { var fileName = (_dimseStream as FileStream).Name; _dimseStream.Close(); _dimseStream = null; var request = _dimse as DicomCStoreRequest; request.File = DicomFile.Open(fileName); request.File.File.IsTempFile = true; request.Dataset = request.File.Dataset; } ThreadPool.QueueUserWorkItem(PerformDimseCallback, _dimse); _dimse = null; } } } } catch (Exception e) { SendAbort(DicomAbortSource.ServiceUser, DicomAbortReason.NotSpecified); Logger.Log(LogLevel.Error, e.ToString()); } finally { SendNextMessage(); } }
private void EndReadPDU(IAsyncResult result) { try { byte[] buffer = (byte[])result.AsyncState; int count = _network.EndRead(result); if (count == 0) { // disconnected _network.Close(); _isConnected = false; return; } _readLength -= count; if (_readLength > 0) { _network.BeginRead(buffer, buffer.Length - _readLength, _readLength, EndReadPDU, buffer); return; } var raw = new RawPDU(buffer); switch (raw.Type) { case 0x01: { Association = new DicomAssociation(); var pdu = new AAssociateRQ(Association); pdu.Read(raw); LogID = Association.CallingAE; Logger.Log(LogLevel.Info, "{0} <- Association request:\n{1}", LogID, Association.ToString()); if (this is IDicomServiceProvider) { (this as IDicomServiceProvider).OnReceiveAssociationRequest(Association); } break; } case 0x02: { var pdu = new AAssociateAC(Association); pdu.Read(raw); LogID = Association.CalledAE; Logger.Log(LogLevel.Info, "{0} <- Association accept:\n{1}", LogID, Association.ToString()); if (this is IDicomServiceUser) { (this as IDicomServiceUser).OnReceiveAssociationAccept(Association); } break; } case 0x03: { var pdu = new AAssociateRJ(); pdu.Read(raw); Logger.Log(LogLevel.Info, "{0} <- Association reject [result: {1}; source: {2}; reason: {3}]", LogID, pdu.Result, pdu.Source, pdu.Reason); if (this is IDicomServiceUser) { (this as IDicomServiceUser).OnReceiveAssociationReject(pdu.Result, pdu.Source, pdu.Reason); } break; } case 0x04: { var pdu = new PDataTF(); pdu.Read(raw); ProcessPDataTF(pdu); break; } case 0x05: { var pdu = new AReleaseRQ(); pdu.Read(raw); Logger.Log(LogLevel.Info, "{0} <- Association release request", LogID); if (this is IDicomServiceProvider) { (this as IDicomServiceProvider).OnReceiveAssociationReleaseRequest(); } break; } case 0x06: { var pdu = new AReleaseRP(); pdu.Read(raw); Logger.Log(LogLevel.Info, "{0} <- Association release response", LogID); if (this is IDicomServiceUser) { (this as IDicomServiceUser).OnReceiveAssociationReleaseResponse(); } _network.Close(); _isConnected = false; break; } case 0x07: { var pdu = new AAbort(); pdu.Read(raw); Logger.Log(LogLevel.Info, "{0} <- Abort: {1} - {2}", LogID, pdu.Source, pdu.Reason); if (this is IDicomServiceProvider) { (this as IDicomServiceProvider).OnReceiveAbort(pdu.Source, pdu.Reason); } else if (this is IDicomServiceUser) { (this as IDicomServiceUser).OnReceiveAbort(pdu.Source, pdu.Reason); } _network.Close(); _isConnected = false; break; } case 0xFF: { break; } default: throw new DicomNetworkException("Unknown PDU type"); } BeginReadPDUHeader(); } catch (Exception e) { Logger.Log(LogLevel.Error, "Exception processing PDU: {0}", e.ToString()); _network.Close(); _isConnected = false; } }
private void WritePDU(bool last) { if (_length > 0) CreatePDV(last); if (_pdu.PDVs.Count > 0) { if (last) _pdu.PDVs[_pdu.PDVs.Count - 1].IsLastFragment = true; _service.SendPDU(_pdu); _pdu = new PDataTF(); } }
private void EndReadPDU(IAsyncResult result) { try { byte[] buffer = (byte[])result.AsyncState; int count = _network.EndRead(result); if (count == 0) { // disconnected CloseConnection(null); return; } _readLength -= count; if (_readLength > 0) { _network.BeginRead(buffer, buffer.Length - _readLength, _readLength, EndReadPDU, buffer); return; } var raw = new RawPDU(buffer); switch (raw.Type) { case 0x01: { Association = new DicomAssociation(); var pdu = new AAssociateRQ(Association); pdu.Read(raw); LogID = Association.CallingAE; if (Options.UseRemoteAEForLogName) Logger = LogManager.Default.GetLogger(LogID); Logger.Info("{callingAE} <- Association request:\n{association}", LogID, Association.ToString()); if (this is IDicomServiceProvider) (this as IDicomServiceProvider).OnReceiveAssociationRequest(Association); break; } case 0x02: { var pdu = new AAssociateAC(Association); pdu.Read(raw); LogID = Association.CalledAE; Logger.Info("{calledAE} <- Association accept:\n{assocation}", LogID, Association.ToString()); if (this is IDicomServiceUser) (this as IDicomServiceUser).OnReceiveAssociationAccept(Association); break; } case 0x03: { var pdu = new AAssociateRJ(); pdu.Read(raw); Logger.Info("{logId} <- Association reject [result: {pduResult}; source: {pduSource}; reason: {pduReason}]", LogID, pdu.Result, pdu.Source, pdu.Reason); if (this is IDicomServiceUser) (this as IDicomServiceUser).OnReceiveAssociationReject(pdu.Result, pdu.Source, pdu.Reason); break; } case 0x04: { var pdu = new PDataTF(); pdu.Read(raw); if (Options.LogDataPDUs) Logger.Info("{logId} <- {@pdu}", LogID, pdu); _processQueue.Queue(ProcessPDataTF, pdu); break; } case 0x05: { var pdu = new AReleaseRQ(); pdu.Read(raw); Logger.Info("{logId} <- Association release request", LogID); if (this is IDicomServiceProvider) (this as IDicomServiceProvider).OnReceiveAssociationReleaseRequest(); break; } case 0x06: { var pdu = new AReleaseRP(); pdu.Read(raw); Logger.Info("{logId} <- Association release response", LogID); if (this is IDicomServiceUser) (this as IDicomServiceUser).OnReceiveAssociationReleaseResponse(); CloseConnection(null); break; } case 0x07: { var pdu = new AAbort(); pdu.Read(raw); Logger.Info("{logId} <- Abort: {pduSource} - {pduReason}", LogID, pdu.Source, pdu.Reason); if (this is IDicomServiceProvider) (this as IDicomServiceProvider).OnReceiveAbort(pdu.Source, pdu.Reason); else if (this is IDicomServiceUser) (this as IDicomServiceUser).OnReceiveAbort(pdu.Source, pdu.Reason); CloseConnection(null); break; } case 0xFF: { break; } default: throw new DicomNetworkException("Unknown PDU type"); } BeginReadPDUHeader(); } catch (IOException e) { if (e.InnerException is SocketException) { Logger.Error("Socket error while reading PDU: {socketErrorCode} [{errorCode}]", (e.InnerException as SocketException).SocketErrorCode, (e.InnerException as SocketException).ErrorCode); } else if (!(e.InnerException is ObjectDisposedException)) Logger.Error("IO exception while reading PDU: {@error}", e); CloseConnection(e); } catch (NullReferenceException) { // connection already closed; silently ignore CloseConnection(null); } catch (Exception e) { Logger.Error("Exception processing PDU: {@error}", e); CloseConnection(e); } }