Inheritance: IDisposable
Example #1
0
        private void SaveDimseToFile(DcmDimseInfo dimse, byte pcid, string fileName)
        {
            string path = Path.GetFullPath(fileName);
            for (int i = 1; File.Exists(path); i++) {
                path = Path.GetFullPath(fileName);
                string ext = Path.GetExtension(path);
                path = path.Substring(0, path.Length - ext.Length);
                path += String.Format(" ({0})", i);
                path += ext;
            }

            if (String.IsNullOrEmpty(dimse.DatasetFile)) {
                DcmPresContext pres = Associate.GetPresentationContext(pcid);

                DicomFileFormat ff = new DicomFileFormat();
                ff.FileMetaInfo.FileMetaInformationVersion = DcmFileMetaInfo.Version;
                ff.FileMetaInfo.MediaStorageSOPClassUID = pres.AbstractSyntax;
                ff.FileMetaInfo.MediaStorageSOPInstanceUID = dimse.Command.AffectedSOPInstanceUID;
                ff.FileMetaInfo.TransferSyntax = pres.AcceptedTransferSyntax;
                ff.FileMetaInfo.ImplementationClassUID = Implementation.ClassUID;
                ff.FileMetaInfo.ImplementationVersionName = Implementation.Version;
                ff.FileMetaInfo.SourceApplicationEntityTitle = Associate.CalledAE;
                ff.Save(fileName, DicomWriteOptions.Default);
            }

            long pos = dimse.DatasetStream.Position;

            using (FileStream fs = File.OpenWrite(fileName)) {
                fs.Seek(0, SeekOrigin.End);
                dimse.DatasetStream.Seek(0, SeekOrigin.Begin);
                StreamUtility.Copy(dimse.DatasetStream, fs);
            }

            dimse.DatasetStream.Position = pos;
        }
Example #2
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;
            }
        }
Example #3
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;
            }
        }
Example #4
0
 private void Process()
 {
     try {
         OnConnected();
         _disableTimeout = false;
         DateTime timeout = DateTime.Now.AddSeconds(DimseTimeout);
         while (!_stop) {
             if (_socket.Poll(1000000, SelectMode.SelectRead)) {
                 if (_socket.Available == 0)
                     break;
                 ProcessNextPDU();
                 timeout = DateTime.Now.AddSeconds(DimseTimeout);
             }
             else if (_disableTimeout) {
                 timeout = DateTime.Now.AddSeconds(DimseTimeout);
             }
             else if (DimseTimeout != 0 && DateTime.Now > timeout) {
                 Log.Error("{0} -> DIMSE timeout after {1} seconds", LogID, DimseTimeout);
                 OnDimseTimeout();
                 _stop = true;
             }
             else if (!_socket.Connected)
                 break;
         }
         Log.Info("{0} -> Connection closed", LogID);
         OnConnectionClosed();
     }
     catch (SocketException e) {
         if (e.SocketErrorCode == SocketError.TimedOut)
             Log.Error("{0} -> Network timeout after {1} seconds", LogID, SocketTimeout);
         else
             Log.Error("{0} -> Network error: {1}", LogID, e.Message);
         OnNetworkError(e);
         OnConnectionClosed();
     }
     catch (Exception e) {
     #if DEBUG
         Log.Error("{0} -> Processing failure: {1}", LogID, e.ToString());
     #else
         Log.Error("{0} -> Processing failure: {1}", LogID, e.Message);
     #endif
         OnNetworkError(e);
         Log.Info("{0} -> Connection closed", LogID);
         OnConnectionClosed();
     }
     finally {
         try { _network.Close(); } catch { }
         _network = null;
         try { _socket.Close(); } catch { }
         _socket = null;
         _isRunning = false;
         _dimse = null;
     }
 }