예제 #1
0
        /// <summary>
        /// Parse commands
        /// </summary>
        protected override void conn_CommandReceived(DICOMConnection conn, PDATACommands command, DICOMData cmdDICOM, DICOMData dataDICOM)
        {
            switch (command)
            {
            case PDATACommands.CMOVERSP:
                logger.Log(LogLevel.Info, "Received C-MOVE-RSP");

                CommandStatus status    = (CommandStatus)(ushort)cmdDICOM[DICOMTags.Status].Data;
                ushort        remaining = (ushort)cmdDICOM[DICOMTags.NumberOfRemainingSubOps].Data;
                ushort        completed = (ushort)cmdDICOM[DICOMTags.NumberOfCompletedSubOps].Data;
                ushort        failed    = (ushort)cmdDICOM[DICOMTags.NumberOfFailedSubOps].Data;
                ushort        warning   = (ushort)cmdDICOM[DICOMTags.NumberOfWarningSubOps].Data;

                if (MoveUpdate != null)
                {
                    MoveUpdate(this, remaining, completed, failed, warning);
                }

                if (remaining == 0)
                {
                    conn.SendReleaseRQ();
                }

                break;

            default:
                logger.Log(LogLevel.Warning, "Unhandled P-DATA Command Type: " + command + "...");
                break;
            }
        }
예제 #2
0
 public DicomServerFactory(
     DICOMConnection connection,
     ILogger logger)
 {
     Connection = connection;
     _logger    = logger;
 }
예제 #3
0
        /// <summary>
        /// Parse commands
        /// </summary>
        protected override void conn_CommandReceived(DICOMConnection conn, PDATACommands command, DICOMData cmdDICOM, DICOMData dataDICOM)
        {
            switch (command)
            {
            case PDATACommands.CFINDRSP:
                logger.Log(LogLevel.Info, "Received C-FIND-RSP");

                CommandStatus status = (CommandStatus)(ushort)cmdDICOM[DICOMTags.Status].Data;
                if (status == CommandStatus.Pending_AllOptionalKeysReturned || status == CommandStatus.Pending_SomeOptionalKeysNotReturned)
                {
                    findResponse.AddResponseRow(dataDICOM);
                }
                else if (status == CommandStatus.Success)
                {
                    if (FindResponse != null)
                    {
                        FindResponse(this, findResponse);
                    }

                    conn.SendReleaseRQ();
                }
                else
                {
                    logger.Log(LogLevel.Error, "Unhandled C-FIND-RSP Status Type: " + status + "...");
                }

                break;

            default:
                logger.Log(LogLevel.Warning, "Unhandled P-DATA Command Type: " + command + "...");
                break;
            }
        }
예제 #4
0
 private void conn_ConnectionClosed(DICOMConnection conn)
 {
     if (SCUFinished != null)
     {
         SCUFinished(this, wasSuccessful && conn.Released);
     }
 }
예제 #5
0
        private void listener_AssociationRequest(DICOMConnection conn)
        {
            //make sure we have the calling AE in our list...
            ApplicationEntity entity = this._db.GetEntity(conn.CallingAE);

            if (this._settings.PromiscuousMode)
            {
                conn.SendAssociateAC();
            }
            else if (entity != null)
            {
                if (conn.CalledAE.Trim() != this._settings.AETitle.Trim())
                {
                    this._logger.Log(LogLevel.Error, "Rejecting Association: Called AE (" + conn.CalledAE + ") doesn't match our AE (" + this._settings.AETitle + ")");
                    conn.SendAssociateRJ(AssociateRJResults.RejectedPermanent, AssociateRJSources.DICOMULServiceProviderPresentation, AssociateRJReasons.CalledAENotRecognized);
                }
                else if (conn.RemoteEndPoint.Address.ToString() != entity.Address)
                {
                    this._logger.Log(LogLevel.Error, "Rejecting Association: Remote Address (" + conn.RemoteEndPoint.Address.ToString() + ") doesn't match AE (" + conn.CallingAE + ")'s Address (" + entity.Address + ")");
                    conn.SendAssociateRJ(AssociateRJResults.RejectedPermanent, AssociateRJSources.DICOMULServiceProviderPresentation, AssociateRJReasons.CallingAENotRecognized);
                }
                else
                {
                    conn.SendAssociateAC();
                }
            }
            else
            {
                this._logger.Log(LogLevel.Error, "Rejecting Association: Couldn't find entity in list with AE title (" + conn.CallingAE + ")");
                conn.SendAssociateRJ(AssociateRJResults.RejectedPermanent, AssociateRJSources.DICOMULServiceProviderPresentation, AssociateRJReasons.CallingAENotRecognized);
            }
        }
예제 #6
0
        /// <summary>
        /// Process commands
        /// </summary>
        protected override void conn_CommandReceived(DICOMConnection conn, PDATACommands command, DICOMData cmdDICOM, DICOMData dataDICOM)
        {
            switch (command)
            {
            case PDATACommands.CSTORERSP:
                logger.Log(LogLevel.Info, "Received C-STORE-RSP");

                CommandStatus status = (CommandStatus)(ushort)cmdDICOM[DICOMTags.Status].Data;
                if (status == CommandStatus.Success)
                {
                    completed++;
                }
                else if (status == CommandStatus.Warning_DuplicateInvocation || status == CommandStatus.Warning_DuplicateSOPInstance)
                {
                    warned++;
                }
                else
                {
                    failed++;
                }

                if (SendUpdate != null)
                {
                    SendUpdate(this, (ushort)sendQueue.Count, completed, warned, failed);
                }

                SendNextImage();

                break;

            default:
                logger.Log(LogLevel.Warning, "Unhandled P-DATA Command Type: " + command + "...");
                break;
            }
        }
예제 #7
0
        /// <summary>
        /// Push a file to DICOM.
        /// </summary>
        /// <param name="routedItem"></param>
        /// <param name="taskID"></param>
        /// <param name="connection"></param>
        public void CStore(RoutedItem routedItem, long taskID, DICOMConnection connection)
        {
            Connection = connection;
            var taskInfo = $"task: {taskID} connection: {Connection.name}";

            try
            {
                try
                {
                    if (File.Exists(routedItem.sourceFileName))
                    {
                        var cStoreRequest = new DicomCStoreRequest(routedItem.sourceFileName);
                        routedItem.MessageId    = cStoreRequest.MessageID;
                        cStoreRequest.UserState = routedItem;
                        _logger.Log(LogLevel.Debug, $"{taskInfo} Request id: {routedItem.id} {cStoreRequest.MessageID}, {routedItem.sourceFileName} {routedItem.fileIndex}/{routedItem.fileCount} attempt: {routedItem.attempts}");

                        cStoreRequest.OnResponseReceived = (DicomCStoreRequest request, DicomCStoreResponse response) =>
                        {
                            var ri = (RoutedItem)request.UserState;
                            _logger.Log(LogLevel.Information, $"{taskInfo} Request id: {ri.id} {response.RequestMessageID} status: {response.Status.Code} description: {response.Status.Description} comment: {response.Status.ErrorComment} state: {response.Status.State}");

                            _routedItemManager.Init(ri);
                            //2018-08-01 shb BOUR-559 handle and log failure conditions
                            if (response.Status == DicomStatus.Success)
                            {
                                _routedItemManager.Dequeue(Connection, Connection.toDicom, nameof(Connection.toDicom), error: false);
                            }
                            else
                            {
                                _routedItemManager.Dequeue(Connection, Connection.toDicom, nameof(Connection.toDicom), error: true);
                            }

                            OnCStoreRequestComplete(request, response);
                        };

                        dicomClient.AddRequest(cStoreRequest);
                    }
                    else
                    {
                        _logger.Log(LogLevel.Information, $"{taskInfo} File does not exist: {routedItem.sourceFileName}");
                        _routedItemManager.Init(routedItem);
                        _routedItemManager.Dequeue(Connection, Connection.toDicom, nameof(Connection.toDicom), error: true);
                    }
                }
                catch (DicomDataException e)
                {
                    _logger.Log(LogLevel.Warning, $"{taskInfo} {routedItem.sourceFileName} {e.Message} {e.StackTrace} ");

                    // !e.GetType().IsAssignableFrom(typeof(DicomFileException)))

                    _routedItemManager.Init(routedItem);
                    _routedItemManager.Dequeue(Connection, Connection.toDicom, nameof(Connection.toDicom), error: true);
                }
            }
            catch (Exception e)
            {
                _logger.LogFullException(e, taskInfo);
            }
        }
예제 #8
0
        void conn_ConnectionClosed(DICOMConnection conn)
        {
            if (ConnectionClosed != null)
            {
                ConnectionClosed(conn);
            }

            this._connections.Remove(conn);
        }
예제 #9
0
        public DicomSendRequestService(
            DicomClient dicomClient,
            DICOMConnection connection,
            ILogger logger)
        {
            _dicomClient = dicomClient;
            _logger      = logger;

            Connection = connection;
        }
        public async Task SendToDicom(int taskID, DICOMConnection connection, DicomClient dicomClient, SemaphoreSlim toDicomSignal)
        {
            Connection = connection;
            var taskInfo  = $"task: {taskID} connection: {Connection.name}";
            var stopWatch = new Stopwatch();

            stopWatch.Start();

            try
            {
                do
                {
                    if (Connection.TestConnection)
                    {
                        await CEcho(taskID, dicomClient);
                    }

                    bool success = await toDicomSignal.WaitAsync(_profileStorage.Current.KickOffInterval, _taskManager.cts.Token).ConfigureAwait(false);

                    while (Connection.toDicom.ToList().FindAll(e => e.lastAttempt < DateTime.Now.AddMinutes(-Connection.retryDelayMinutes)).Count > 0)
                    {
                        // batch up items along maxRequestsPerAssociation and if the attempt > 1 break out and send it.
                        List <List <RoutedItem> > batches = GetBatches(taskInfo);

                        _logger.Log(LogLevel.Debug, $"{taskInfo} batches to send: {batches.Count}");

                        //queue up the requests for each association
                        foreach (var association in batches)
                        {
                            await ProcessBatches(association, dicomClient, taskID, taskInfo, stopWatch);
                        }
                        await Task.Delay(+_profileStorage.Current.backlogInterval).ConfigureAwait(false);

                        stopWatch.Restart();
                    }

                    // toDicomSignal.Dispose();
                    // toDicomSignal = new SemaphoreSlim(0, 1);
                } while (Connection.responsive);
            }
            catch (DicomAssociationRejectedException e)
            {
                _logger.LogFullException(e, $"{taskInfo} Dicom Association Failed");
            }
            catch (Exception e)
            {
                _logger.LogFullException(e, taskInfo);
            }
            finally
            {
                _taskManager.Stop($"{Connection.name}.SendToDicom");
            }
        }
예제 #11
0
        /// <summary>
        /// Initializes a new SCU base type.
        /// </summary>
        /// <param name="logger">A logger to get logging callbacks about the exchange.  May not be null.</param>
        /// <param name="scuName">Name for the SCU for logging.</param>
        /// <param name="verbose">True for incredibly verbose logging to the logger.  False for simple logging.</param>
        internal DICOMSCU(ILogger logger, string scuName, bool verbose)
        {
            this.logger = logger;

            conn = new DICOMConnection(logger, scuName, verbose);

            conn.AssociationAccepted += new DICOMConnection.BasicConnectionHandler(conn_AssociationAccepted);
            conn.CommandReceived     += new DICOMConnection.CommandHandler(conn_CommandReceived);

            conn.AssociationRejected += new DICOMConnection.AssociationRejectedHandler(conn_AssociationRejected);
            conn.ConnectionClosed    += new DICOMConnection.BasicConnectionHandler(conn_ConnectionClosed);
        }
예제 #12
0
 private void conn_AssociationRequested(DICOMConnection conn)
 {
     if (AssociationRequest != null)
     {
         AssociationRequest(conn);
     }
     else
     {
         //No handler set up, so go promiscuous!
         conn.SendAssociateAC();
     }
 }
예제 #13
0
        private void listener_StoreRequest(DICOMConnection conn, DICOMData data)
        {
            try
            {
                if (!this._settings.StoreMetadataOnlyFiles && !data.Elements.ContainsKey(DICOMTags.PixelData))
                {
                    this._logger.Log(LogLevel.Info, "Data set has no image data (only metadata). Metadata storing is disabled, so image will not be persisted.");
                    conn.SendCSTORERSP(CommandStatus.Error_MissingAttribute);
                    return;
                }

                if (this._settings.AutoDecompress && data.TransferSyntax.Compression != DICOMSharp.Data.Compression.CompressionInfo.None)
                {
                    this._logger.Log(LogLevel.Info, "Image is compressed, decompressing before storage!");
                    if (!data.Uncompress())
                    {
                        this._logger.Log(LogLevel.Warning, "Image decompression failed! Storing compressed image.");
                    }
                }

                string postName = FileUtil.GenerateFilenameFromImage(data, this._logger);

                //form full file path
                string diskPath = _db.FixImagePath(this._settings.ImageStoragePath);
                if (!diskPath.EndsWith("\\"))
                {
                    diskPath += "\\";
                }
                diskPath += postName;

                data.WriteFile(diskPath, this._logger);

                // Db path can save a ~ path, so recalc without MapPath
                string dbPath = this._settings.ImageStoragePath;
                if (!dbPath.EndsWith("\\"))
                {
                    dbPath += "\\";
                }
                dbPath += postName;

                this._db.PersistImage(data, diskPath, dbPath);

                conn.SendCSTORERSP(CommandStatus.Success);
            }
            catch (Exception e)
            {
                this._logger.Log(LogLevel.Error, "Error in StoreRequest: " + e.ToString());
                conn.SendCSTORERSP(CommandStatus.Error_UnrecognizedOperation);
            }
        }
예제 #14
0
        /// <summary>
        /// Parses commands.
        /// </summary>
        protected override void conn_CommandReceived(DICOMConnection conn, PDATACommands command, DICOMData cmdDICOM, DICOMData dataDICOM)
        {
            switch (command)
            {
            case PDATACommands.CECHORSP:
                logger.Log(LogLevel.Info, "Received C-ECHO-RSP");
                conn.SendReleaseRQ();
                break;

            default:
                logger.Log(LogLevel.Warning, "Unhandled P-DATA Command Type: " + command + "...");
                break;
            }
        }
예제 #15
0
        private void ListenThread()
        {
            try
            {
                logger.Log(LogLevel.Info, "Listen Thread Started");
                while (true)
                {
                    Socket remoteSock = listenSocket.Accept();
                    if (remoteSock != null)
                    {
                        DICOMConnection conn = new DICOMConnection(logger, this._connectionCounter.ToString(), VerboseLogging);

                        conn.AssociationRequested += new DICOMConnection.BasicConnectionHandler(conn_AssociationRequested);
                        conn.CommandReceived      += new DICOMConnection.CommandHandler(conn_CommandReceived);
                        conn.ConnectionClosed     += new DICOMConnection.BasicConnectionHandler(conn_ConnectionClosed);

                        conn.SupportedAbstractSyntaxes.Add(AbstractSyntaxes.VerificationSOPClass);
                        foreach (AbstractSyntax syntax in AbstractSyntaxes.StorageSyntaxes)
                        {
                            conn.SupportedAbstractSyntaxes.Add(syntax);
                        }
                        foreach (AbstractSyntax syntax in AbstractSyntaxes.QueryRetrieveSyntaxes)
                        {
                            conn.SupportedAbstractSyntaxes.Add(syntax);
                        }

                        conn.HandleSocket(remoteSock);

                        this._connections.Add(conn);
                        this._connectionCounter++;
                    }
                }
            }
            catch (ThreadAbortException)
            {
                logger.Log(LogLevel.Info, "Listen Thread Stopped");
            }
            catch (SocketException)
            {
                logger.Log(LogLevel.Info, "Listen Thread Stopped");
            }
        }
예제 #16
0
        // Note: cGet is not working at this point
        public void CGet(RoutedItem routedItem, int taskID, DICOMConnection connection)
        {
            Connection = connection;
            //process any outstanding moves and return the results

            var taskInfo = $"task: {taskID} connection: {Connection.name}";

            List <string> movesToRemove = new List <string>();

            try
            {
                _logger.Log(LogLevel.Debug, $"{taskInfo} dicom.AddRequest: {routedItem.id} ");
                try
                {
                    var request = new DicomCGetRequest(routedItem.request)
                    {
                        UserState = routedItem
                    };

                    request.OnResponseReceived += CGetResponse;
                    // Fix if cGet is ever fixed                        dicomClient.AddRequest(request);
                }
                catch (TaskCanceledException)
                {
                    _logger.Log(LogLevel.Information, $"Task was canceled.");
                }
                catch (DicomDataException e)
                {
                    _logger.Log(LogLevel.Warning, $"{taskInfo} move: {routedItem.id} {e.Message} {e.StackTrace}");
                }
            }
            catch (Exception e)
            {
                _logger.LogFullException(e, taskInfo);
            }
        }
예제 #17
0
 /// <summary>
 /// This function must be overridden to provide handling of received P-DATA commands.
 /// </summary>
 /// <param name="conn">The DICOMConnection in question.</param>
 /// <param name="command">The P-DATA command ID.</param>
 /// <param name="cmdDICOM">The command DICOM set of the P-DATA command.</param>
 /// <param name="dataDICOM">The data DICOM set of the P-DATA command, if any.  Null if no data set contained in the command.</param>
 protected abstract void conn_CommandReceived(DICOMConnection conn, PDATACommands command, DICOMData cmdDICOM, DICOMData dataDICOM);
예제 #18
0
 /// <summary>
 /// This function must be overridden to provide actions when the connection is successfully associated.
 /// </summary>
 /// <param name="conn">The DICOMConnection in question.</param>
 protected abstract void conn_AssociationAccepted(DICOMConnection conn);
예제 #19
0
 static void listener_StoreRequest(DICOMConnection conn, DICOMData data)
 {
     //C-Store request with a dataset. cache it...
     storedData.Add(data);
 }
예제 #20
0
        static QRResponseData listener_FindRequest(DICOMConnection conn, QRRequestData request)
        {
            QRResponseData response = request.GenerateResponse();

            foreach (DICOMData data in storedData)
            {
                //check fields
                bool works = true;
                foreach (uint tag in request.SearchTerms.Keys)
                {
                    object search = request.SearchTerms[tag];
                    if (search.ToString() == "")
                    {
                        continue;
                    }

                    if (!data.Elements.ContainsKey(tag))
                    {
                        works = false;
                        break;
                    }

                    if (search.ToString().Contains("-"))
                    {
                        //range

                        string[] range = search.ToString().Split('-');
                        if (range[0] != "" && data[tag].Display.CompareTo(range[0]) < 0)
                        {
                            works = false;
                            break;
                        }
                        if (range[1] != "" && data[tag].Display.CompareTo(range[1]) > 0)
                        {
                            works = false;
                            break;
                        }
                    }
                    else if (search.ToString().Contains("*"))
                    {
                        if (!Regex.IsMatch(data[tag].Display, search.ToString()))
                        {
                            works = false;
                            break;
                        }
                    }
                    else if (data[tag].Display != search.ToString())
                    {
                        works = false;
                        break;
                    }
                }

                if (!works)
                {
                    continue;
                }

                DICOMData ndata = new DICOMData();
                foreach (uint tag in response.TagsToFill)
                {
                    if (data.Elements.ContainsKey(tag))
                    {
                        ndata[tag].Data = data[tag].Data;
                    }
                }
            }

            return(response);
        }
예제 #21
0
 /// <summary>
 /// Start the move request
 /// </summary>
 protected override void conn_AssociationAccepted(DICOMConnection conn)
 {
     //fire off the request...
     conn.SendCMOVERQ(CommandPriority.Medium, FindRequest.QueryLevel, SendToAE, FindRequest.CreateSearchData());
 }
예제 #22
0
 static void listener_AssociationRequest(DICOMConnection conn)
 {
     //accept anyone!
     conn.SendAssociateAC();
 }
        public async Task CEcho(DICOMConnection Connection, int taskID)
        {
            Throw.IfNull(Connection);

            var taskInfo  = $"task: {taskID} connection: {Connection.name}";
            var stopWatch = new Stopwatch();

            stopWatch.Start();

            //just c-echo the host to say hello

            dicomClient.AddRequest(new DicomCEchoRequest());

            DicomSendRequestService dicomSendRequestService = new DicomSendRequestService(dicomClient, Connection, _logger);

            try
            {
                await dicomSendRequestService.SendRequest(taskInfo, stopWatch);

                #region old code
                //await Task.Run(async () =>
                //{
                //    await dicomClient.SendAsync(Connection.remoteHostname, Connection.remotePort, Connection.useTLS, Connection.localAETitle, Connection.remoteAETitle);

                //    _logger.Log(LogLevel.Debug, $"{taskInfo} SendAsync complete elapsed: {stopWatch.Elapsed}");

                //    await Task.Delay(Connection.msToWaitAfterSendBeforeRelease).ConfigureAwait(false);

                //    _logger.Log(LogLevel.Debug, $"{taskInfo} Releasing: {stopWatch.Elapsed}");

                //    await dicomClient.ReleaseAsync();
                //});
                #endregion
            }
            catch (TaskCanceledException)
            {
                _logger.Log(LogLevel.Information, $"Task was canceled.");
            }
            catch (AggregateException e)
            {
                _logger.Log(LogLevel.Warning, $"{taskInfo} SendAsync: {e.Message} {e.StackTrace}");

                foreach (Exception exp in e.InnerExceptions)
                {
                    if (exp != null && exp.Message != null)
                    {
                        _logger.Log(LogLevel.Warning, $"{taskInfo} Inner Exception: {exp.Message} {exp.StackTrace}");
                    }
                }
            }
            catch (DicomAssociationRejectedException e)
            {
                foreach (var context in dicomClient.AdditionalPresentationContexts)
                {
                    if (!(context.Result == DicomPresentationContextResult.Accept))
                    {
                        _logger.Log(LogLevel.Warning, "Not Accepted: " + context.GetResultDescription());
                    }
                }

                _logger.Log(LogLevel.Warning, $"{taskInfo} SendAsync: {e.Message} {e.StackTrace}");
            }
            catch (Exception e)
            {
                _logger.LogFullException(e, $"{taskInfo} SendAsync:");
            }
        }
예제 #24
0
 private QRResponseData listener_MoveRequest(DICOMConnection conn, QRRequestData request)
 {
     return(this._db.GetQRResponse(request, true));
 }
예제 #25
0
 private QRResponseData listener_FindRequest(DICOMConnection conn, QRRequestData request)
 {
     return(this._db.GetQRResponse(request, false));
 }
예제 #26
0
        private void conn_CommandReceived(DICOMConnection conn, PDATACommands command, DICOMData cmdDICOM, DICOMData dataDICOM)
        {
            switch (command)
            {
            case PDATACommands.CECHORQ:
                conn.LogLine(LogLevel.Info, "Received C-ECHO-RQ");
                conn.SendCECHORSP();
                break;

            case PDATACommands.CSTORERQ:
                conn.LogLine(LogLevel.Info, "Received C-STORE-RQ");

                //Add source AE title to image
                dataDICOM[DICOMTags.SourceApplicationEntityTitle].Data = conn.CallingAE;

                if (StoreRequest != null)
                {
                    StoreRequest(conn, dataDICOM);
                }
                else
                {
                    conn.SendCSTORERSP(CommandStatus.Success);
                }
                break;

            case PDATACommands.CSTORERSP:
                conn.LogLine(LogLevel.Info, "Received C-STORE-RSP");

                break;

            case PDATACommands.CFINDRQ:
                conn.LogLine(LogLevel.Info, "Received C-FIND-RQ");
                if (FindRequest != null)
                {
                    QRResponseData response = FindRequest(conn, new QRRequestData(cmdDICOM, dataDICOM));
                    conn.SendCFINDRSP(response);
                }
                else
                {
                    conn.SendCFINDRSP(null, CommandStatus.Success);
                }
                break;

            case PDATACommands.CGETRQ:
                conn.LogLine(LogLevel.Info, "Received C-GET-RQ");
                if (GetRequest != null)
                {
                    QRResponseData response = GetRequest(conn, new QRRequestData(cmdDICOM, dataDICOM));
                    conn.StartGetResponse(response);
                }
                else
                {
                    conn.SendCGETRSP((ushort)cmdDICOM[DICOMTags.MessageID].Data, CommandStatus.Success, 0, 0, 0, 0);
                }
                break;

            case PDATACommands.CMOVERQ:
                conn.LogLine(LogLevel.Info, "Received C-MOVE-RQ");
                if (MoveRequest != null)
                {
                    string            newAE  = cmdDICOM[DICOMTags.MoveDestination].Display.Trim();
                    ApplicationEntity entity = null;
                    if (EntityLookup != null)
                    {
                        entity = EntityLookup(newAE);
                    }

                    if (entity != null)
                    {
                        QRResponseData response = MoveRequest(conn, new QRRequestData(cmdDICOM, dataDICOM));
                        conn.StartMoveResponse(entity, response);
                    }
                    else
                    {
                        conn.LogLine(LogLevel.Warning, "No entity found for the MOVE request: " + newAE);
                        conn.SendCMOVERSP(CommandStatus.Error_ProcessingFailure, 0, 0, 0, 0);
                    }
                }
                else
                {
                    conn.SendCMOVERSP(CommandStatus.Error_ProcessingFailure, 0, 0, 0, 0);
                }
                break;

            case PDATACommands.NGETRQ:
                conn.LogLine(LogLevel.Info, "Received N-GET-RQ");

                // No idea what we're supposed to do with these yet
                conn.SendNGETRSP(CommandStatus.Refused_SOPClassNotSupported, null);
                break;

            default:
                conn.LogLine(LogLevel.Warning, "Unhandled P-DATA Command Type: " + command + "...");
                break;
            }
        }
예제 #27
0
 private void conn_AssociationRejected(DICOMConnection conn, AssociateRJResults result, AssociateRJSources source, AssociateRJReasons reason)
 {
     wasSuccessful = false;
     logger.Log(LogLevel.Error, "Association Rejected! Result: " + result + ", Source: " + source + ", Reason: " + reason);
 }
예제 #28
0
 static void listener_StoreRequest(DICOMConnection conn, DICOMData data)
 {
     //Do something with the stored image
 }
        public void CMove(RoutedItem routedItem, long taskID, DICOMConnection connection)
        {
            Connection = connection;

            var taskInfo = $"task: {taskID} connection: {Connection.name}";

            try
            {
                try
                {
                    // 2018-01-22 shb changed from dicomServerName to localAETitle
                    var cmove = new DicomCMoveRequest(Connection.localAETitle, routedItem.request);
                    _logger.Log(LogLevel.Information, $"{taskInfo} cMove id: {routedItem.id} MessageID: {cmove.MessageID} attempt: {routedItem.attempts}");

                    cmove.UserState           = routedItem;
                    routedItem.MessageId      = cmove.MessageID;
                    routedItem.fromConnection = Connection.name;
                    routedItem.toConnections.Clear();
                    routedItem.status = RoutedItem.Status.PENDING;

                    _routedItemManager.Init(routedItem);
                    //var riToCache = (RoutedItem)routedItem.Clone();
                    var riToCache = _routedItemManager.Clone();
                    _routedItemManager.Init(riToCache);
                    _routedItemManager.Enqueue(Connection, Connection.toRules, nameof(Connection.toRules));

                    // Returns the status of the request, actual transfer happens in DicomListener
                    cmove.OnResponseReceived = (DicomCMoveRequest request, DicomCMoveResponse response) =>
                    {
                        RoutedItem ri = (RoutedItem)request.UserState;

                        _logger.Log(LogLevel.Information, $"{taskInfo} cmove.OnResponseReceived id: {ri.id} MessageId: {request.MessageID} {response.Status.Description}");

                        Dictionary <string, Dictionary <string, string> > results = new Dictionary <string, Dictionary <string, string> >();

                        Dictionary <string, string> returnTagData = new Dictionary <string, string>
                        {
                            { "StatusCode", response.Status.Code.ToString() },
                            { "StatusDescription", response.Status.Description },
                            { "StatusErrorComment", response.Status.ErrorComment },
                            { "StatusState", response.Status.State.ToString() }
                        };

                        if (response.Completed != 0 || response.Remaining != 0)
                        {
                            returnTagData.Add("Completed", response.Completed.ToString());
                            returnTagData.Add("Remaining", response.Remaining.ToString());
                        }
                        returnTagData.Add("SOPClassUID", response.SOPClassUID.ToString());

                        if (response.Command != null)
                        {
                            foreach (var dicomItem in response.Command)
                            {
                                _logger.Log(LogLevel.Debug, $"{taskInfo} cMove Response {ri.id} MessageId {request.MessageID}, {dicomItem.Tag} {response.Command.GetValueOrDefault<string>(dicomItem.Tag, 0, "")}");
                                returnTagData.Add(dicomItem.Tag.ToString(), response.Command.GetValueOrDefault <string>(dicomItem.Tag, 0, ""));
                            }
                            results.Add("response", returnTagData);
                        }

                        string jsonResults = JsonSerializer.Serialize(results);

                        ri.response.Add(jsonResults);

                        switch (response.Status.ToString())
                        {
                        case "Success":
                            ri.status      = RoutedItem.Status.COMPLETED;
                            ri.resultsTime = DateTime.Now;
                            _routedItemManager.Init(ri);
                            _routedItemManager.Dequeue(Connection, Connection.toDicom, nameof(Connection.toDicom), error: false);

                            //var toCache = (RoutedItem)ri.Clone();
                            var toCache = _routedItemManager.Clone();
                            toCache.fromConnection = Connection.name;
                            ri.toConnections.Clear();

                            _routedItemManager.Init(toCache);
                            _routedItemManager.Enqueue(Connection, Connection.toRules, nameof(Connection.toRules));
                            break;

                        case "Pending":
                            break;

                        default:
                            _routedItemManager.Init(ri);
                            _routedItemManager.Dequeue(Connection, Connection.toDicom, nameof(Connection.toDicom), error: true);
                            break;
                        }
                    };

                    dicomClient.AddRequest(cmove);
                }
                catch (Exception e)   // Needed for transfer syntax exceptions
                {
                    _logger.LogFullException(e, $"{taskInfo} move:");
                }
            }
            catch (Exception e)
            {
                _logger.LogFullException(e, taskInfo);
            }
        }
예제 #30
0
 /// <summary>
 /// Sends the echo request
 /// </summary>
 protected override void conn_AssociationAccepted(DICOMConnection conn)
 {
     conn.SendCECHORQ();
 }