P-DATA-TF
상속: PDU
예제 #1
0
		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);
		}
예제 #2
0
 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);
 }
예제 #3
0
 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);
 }
예제 #4
0
            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];
            }
예제 #5
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;
                    }

                    _service.SendPDU(_pdu);

                    _pdu = new PDataTF();
                }
            }
예제 #6
0
            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();
                }
            }
예제 #7
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();
     }
 }
예제 #8
0
        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;
            }
        }
예제 #9
0
        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;
            }
        }
예제 #10
0
        /// <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();
            }
        }
예제 #11
0
        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);
            }
        }
예제 #12
0
            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();
                }
            }
예제 #13
0
            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];
            }
예제 #14
0
        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);
            }
        }
예제 #15
0
파일: PDataTFStream.cs 프로젝트: GMZ/mdcm
 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();
     }
 }
예제 #16
0
        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);
            }
        }
예제 #17
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();
            }
        }
예제 #18
0
        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;
            }
        }
예제 #19
0
			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();
				}
			}
예제 #20
0
		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);
			}
		}