Exemple #1
0
        public Task OnReceiveAssociationRequestAsync(FoDicomNetwork.DicomAssociation association)
        {
            _associationDataProvider = UserState as IApplicationEntityManager;

            if (_associationDataProvider is null)
            {
                throw new ArgumentNullException("userState must be an instance of IAssociationDataProvider");
            }

            _logger = _associationDataProvider.GetLogger <ScpServiceInternal>(Association.CalledAE);

            _associationId    = _associationDataProvider.NextAssociationNumber();
            _associationIdStr = $"#{_associationId} {association.RemoteHost}:{association.RemotePort}";

            _loggerScope = _logger?.BeginScope(new Dictionary <string, object> {
                { "Association", _associationIdStr }
            });
            _logger?.Log(LogLevel.Information, "Association received from {0}:{1}", association.RemoteHost, association.RemotePort);

            if (!IsValidSourceAe(association.CallingAE))
            {
                return(SendAssociationRejectAsync(
                           FoDicomNetwork.DicomRejectResult.Permanent,
                           FoDicomNetwork.DicomRejectSource.ServiceUser,
                           FoDicomNetwork.DicomRejectReason.CallingAENotRecognized));
            }

            if (!IsValidCalledAe(association.CalledAE))
            {
                return(SendAssociationRejectAsync(
                           FoDicomNetwork.DicomRejectResult.Permanent,
                           FoDicomNetwork.DicomRejectSource.ServiceUser,
                           FoDicomNetwork.DicomRejectReason.CalledAENotRecognized));
            }

            foreach (var pc in association.PresentationContexts)
            {
                if (pc.AbstractSyntax == FoDicom.DicomUID.Verification)
                {
                    if (!_associationDataProvider.Configuration.Value.Dicom.Scp.Verification.Enabled)
                    {
                        _logger?.Log(LogLevel.Warning, "Verification service is disabled: rejecting association");
                        return(SendAssociationRejectAsync(
                                   FoDicomNetwork.DicomRejectResult.Permanent,
                                   FoDicomNetwork.DicomRejectSource.ServiceUser,
                                   FoDicomNetwork.DicomRejectReason.ApplicationContextNotSupported
                                   ));
                    }
                    pc.AcceptTransferSyntaxes(_associationDataProvider.Configuration.Value.Dicom.Scp.Verification.TransferSyntaxes.ToDicomTransferSyntaxArray());
                }
                else if (pc.AbstractSyntax.StorageCategory != FoDicom.DicomStorageCategory.None)
                {
                    // Accept any proposed TS
                    pc.AcceptTransferSyntaxes(pc.GetTransferSyntaxes().ToArray());
                }
            }

            return(SendAssociationAcceptAsync(association));
        }
		public void OnReceiveAssociationRequest(DicomAssociation association) {
			foreach (var pc in association.PresentationContexts) {
				if (pc.AbstractSyntax == DicomUID.Verification)
					pc.SetResult(DicomPresentationContextResult.Accept);
				else
					pc.SetResult(DicomPresentationContextResult.RejectAbstractSyntaxNotSupported);
			}
			SendAssociationAccept(association);
		}
Exemple #3
0
            public void OnReceiveAssociationRequest(DicomAssociation association)
            {
                foreach (var pc in association.PresentationContexts)
                {
                    pc.AcceptTransferSyntaxes(AcceptedImageTransferSyntaxes);
                }

                SendAssociationAccept(association);
            }
Exemple #4
0
        public void OnReceiveAssociationRequest(DicomAssociation association)
        {


            foreach (var pc in association.PresentationContexts)
            {
                if (pc.AbstractSyntax == DicomUID.Verification)
                    pc.AcceptTransferSyntaxes(AcceptedTransferSyntaxes);
                else if (pc.AbstractSyntax.StorageCategory != DicomStorageCategory.None)
                    pc.AcceptTransferSyntaxes(AcceptedImageTransferSyntaxes);
            }

            SendAssociationAccept(association);
        }
Exemple #5
0
			public void OnReceiveAssociationRequest(DicomAssociation association) {
				if (association.CalledAE != "STORESCP") {
					SendAssociationReject(DicomRejectResult.Permanent, DicomRejectSource.ServiceUser, DicomRejectReason.CalledAENotRecognized);
					return;
				}

				foreach (var pc in association.PresentationContexts) {
					if (pc.AbstractSyntax == DicomUID.Verification)
						pc.AcceptTransferSyntaxes(AcceptedTransferSyntaxes);
					else if (pc.AbstractSyntax.StorageCategory != DicomStorageCategory.None)
						pc.AcceptTransferSyntaxes(AcceptedImageTransferSyntaxes);
				}

				SendAssociationAccept(association);
			}
Exemple #6
0
        public void OnReceiveAssociationRequest(DicomAssociation association)
        {
            if (association.CalledAE != "STORESCP")
            {
                SendAssociationReject(DicomRejectResult.Permanent, DicomRejectSource.ServiceUser, DicomRejectReason.CalledAENotRecognized);
                return;
            }

            foreach (var pc in association.PresentationContexts.Where(pc => pc.AbstractSyntax == DicomUID.VerificationSOPClass))
            {
                pc.AcceptTransferSyntaxes(new[] {
                                                    DicomTransferSyntax.ExplicitVRLittleEndian,
                                                    DicomTransferSyntax.ExplicitVRBigEndian,
                                                    DicomTransferSyntax.ImplicitVRLittleEndian
                                                });
            }

            SendAssociationAccept(association);
        }
Exemple #7
0
        public void OnReceiveAssociationRequest(DicomAssociation association)
        {
            this.Logger.Info("Received association request from AE: {0} with IP: {1} ", association.CallingAE, RemoteIP);

            if (Printer.PrinterAet != association.CalledAE)
            {
                this.Logger.Error("Association with {0} rejected since requested printer {1} not found",
                    association.CallingAE, association.CalledAE);
                SendAssociationReject(DicomRejectResult.Permanent, DicomRejectSource.ServiceUser, DicomRejectReason.CalledAENotRecognized);
                return;
            }

            CallingAE = association.CallingAE;
            CalledAE = Printer.PrinterAet;

            foreach (var pc in association.PresentationContexts)
            {
                if (pc.AbstractSyntax == DicomUID.Verification ||
                    pc.AbstractSyntax == DicomUID.BasicGrayscalePrintManagementMetaSOPClass ||
                    pc.AbstractSyntax == DicomUID.BasicColorPrintManagementMetaSOPClass ||
                    pc.AbstractSyntax == DicomUID.PrinterSOPClass ||
                    pc.AbstractSyntax == DicomUID.BasicFilmSessionSOPClass ||
                    pc.AbstractSyntax == DicomUID.BasicFilmBoxSOPClass ||
                    pc.AbstractSyntax == DicomUID.BasicGrayscaleImageBoxSOPClass ||
                    pc.AbstractSyntax == DicomUID.BasicColorImageBoxSOPClass)
                {
                    pc.AcceptTransferSyntaxes(AcceptedTransferSyntaxes);
                }
                else if (pc.AbstractSyntax == DicomUID.PrintJobSOPClass)
                {
                    pc.AcceptTransferSyntaxes(AcceptedTransferSyntaxes);
                    _sendEventReports = true;
                }
                else
                {
                    this.Logger.Warn("Requested abstract syntax {abstractSyntax} from {callingAE} not supported", pc.AbstractSyntax, association.CallingAE);
                    pc.SetResult(DicomPresentationContextResult.RejectAbstractSyntaxNotSupported);
                }
            }

            this.Logger.Info("Accepted association request from {callingAE}", association.CallingAE);
            SendAssociationAccept(association);
        }
Exemple #8
0
        public void WriteReadAAssociateRQExtendedNegotiation()
        {
            DicomAssociation association = new DicomAssociation("testCalling", "testCalled");
            association.ExtendedNegotiations.Add(
                new DicomExtendedNegotiation(
                    DicomUID.StudyRootQueryRetrieveInformationModelFIND,
                    new RootQueryRetrieveInfoFind(1, 1, 1, 1, null)));

            AAssociateRQ rq = new AAssociateRQ(association);

            RawPDU writePdu = rq.Write();

            RawPDU readPdu;
            using (MemoryStream stream = new MemoryStream())
            {
                writePdu.WritePDU(stream);

                int length = (int)stream.Length;
                byte[] buffer = new byte[length];
                stream.Seek(0, SeekOrigin.Begin);
                stream.Read(buffer, 0, length);
                readPdu = new RawPDU(buffer);
            }

            DicomAssociation testAssociation = new DicomAssociation();
            AAssociateRQ rq2 = new AAssociateRQ(testAssociation);
            rq2.Read(readPdu);

            Assert.True(testAssociation.ExtendedNegotiations.Count == 1);
            Assert.True(
                testAssociation.ExtendedNegotiations[0].SopClassUid
                == DicomUID.StudyRootQueryRetrieveInformationModelFIND);

            RootQueryRetrieveInfoFind info =
                testAssociation.ExtendedNegotiations[0].SubItem as RootQueryRetrieveInfoFind;
            Assert.True(null != info);
            Assert.True(
                (1 == info.DateTimeMatching) && (1 == info.FuzzySemanticMatching) && (1 == info.RelationalQueries)
                && (1 == info.TimezoneQueryAdjustment) && (false == info.EnhancedMultiFrameImageConversion.HasValue));
        }
Exemple #9
0
        //下面这部分是A-ASSOCIATE服务的相关实现,此处为了简单只实现了连接请求服务
        #region ACSE-Service

        //A-ASSOCIATE-RQ:
        public void OnReceiveAssociationRequest(DicomAssociation association)
        {


            foreach (var pc in association.PresentationContexts)
            {
                if (pc.AbstractSyntax == DicomUID.Verification)
                    pc.AcceptTransferSyntaxes(AcceptedTransferSyntaxes);
                else
                    if (pc.AbstractSyntax == DicomUID.StudyRootQueryRetrieveInformationModelFIND ||
                        pc.AbstractSyntax == DicomUID.StudyRootQueryRetrieveInformationModelMOVE ||
                        pc.AbstractSyntax == DicomUID.PatientRootQueryRetrieveInformationModelFIND ||
                        pc.AbstractSyntax == DicomUID.PatientRootQueryRetrieveInformationModelMOVE
                        )
                    {
                        //未添加Transfer Syntax限制
                        pc.SetResult(DicomPresentationContextResult.Accept);
                    }
                    else
                        if (pc.AbstractSyntax.StorageCategory != DicomStorageCategory.None)
                            pc.AcceptTransferSyntaxes(AcceptedImageTransferSyntaxes);
            }
            SendAssociationAccept(association);
        }
Exemple #10
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);
			}
		}
 public void OnReceiveAssociationRequest(DicomAssociation association)
 {
     Thread.Sleep(1000);
     this.SendAssociationAccept(association);
 }
Exemple #12
0
            public void OnReceiveAssociationAccept(DicomAssociation association)
            {
                foreach (var ctx in this.client.AdditionalPresentationContexts)
                {
                    foreach (
                        var item in
                            association.PresentationContexts.Where(pc => pc.AbstractSyntax == ctx.AbstractSyntax))
                    {
                        ctx.SetResult(item.Result, item.AcceptedTransferSyntax);
                    }
                }

                this.client.associateNotifier.TrySetResult(true);

                if (this.client.requests.Count > 0)
                {
                    foreach (var request in this.client.requests) this.SendRequest(request);
                    this.client.requests.Clear();
                }
                else
                {
                    this._SendAssociationReleaseRequest();
                }
            }
Exemple #13
0
            /// <summary>
            /// Callback for handling association accept scenarios.
            /// </summary>
            /// <param name="association">Accepted association.</param>
            public void OnReceiveAssociationAccept(DicomAssociation association)
            {
                foreach (var ctx in this.client.AdditionalPresentationContexts)
                {
                    foreach (var item in
                        association.PresentationContexts.Where(pc => pc.AbstractSyntax == ctx.AbstractSyntax))
                    {
                        ctx.SetResult(item.Result, item.AcceptedTransferSyntax);
                    }
                }

                this.client.associateNotifier.TrySetResult(true);

                List<DicomRequest> requests;
                lock (this.client.locker)
                {
                    requests = new List<DicomRequest>(this.client.requests);
                    this.client.requests.Clear();
                }

                if (requests.Count == 0)
                {
                    DoSendAssociationReleaseRequestAsync(ReleaseTimeout).Wait();
                }
                else
                {
                    while (requests.Count > 0)
                    {
                        foreach (var request in requests)
                        {
                            SendRequest(request);
                        }

                        // Have any new requests been added while sending previous requests?
                        lock (this.client.locker)
                        {
                            requests = new List<DicomRequest>(this.client.requests);
                            this.client.requests.Clear();
                        }
                    }
                }
            }
Exemple #14
0
        public IAsyncResult BeginSend(
            Stream stream,
            string callingAe,
            string calledAe,
            AsyncCallback callback,
            object state)
        {
            var assoc = new DicomAssociation(callingAe, calledAe);
            assoc.MaxAsyncOpsInvoked = _asyncInvoked;
            assoc.MaxAsyncOpsPerformed = _asyncPerformed;
            foreach (var request in _requests) assoc.PresentationContexts.AddFromRequest(request);
            foreach (var context in _contexts) assoc.PresentationContexts.Add(context.AbstractSyntax, context.GetTransferSyntaxes().ToArray());

            _service = new DicomServiceUser(this, stream, assoc, Logger);

            _assoc = new ManualResetEventSlim(false);

            _async = new EventAsyncResult(callback, state);
            return _async;
        }
Exemple #15
0
 /// <summary>
 /// Send association request.
 /// </summary>
 /// <param name="association">DICOM association.</param>
 protected void SendAssociationRequest(DicomAssociation association)
 {
     LogID = association.CalledAE;
     if (Options.UseRemoteAEForLogName) Logger = LogManager.GetLogger(LogID);
     Logger.Info("{calledAE} -> Association request:\n{association}", LogID, association.ToString());
     Association = association;
     this.SendPDUAsync(new AAssociateRQ(Association)).Wait();
 }
Exemple #16
0
        /// <summary>
        /// Synchronously send existing requests to DICOM service.
        /// </summary>
        /// <param name="stream">Established network stream.</param>
        /// <param name="callingAe">Calling Application Entity Title.</param>
        /// <param name="calledAe">Called Application Entity Title.</param>
        public void Send(INetworkStream stream, string callingAe, string calledAe)
        {
            if (!CanSend) return;

            var assoc = new DicomAssociation(callingAe, calledAe)
            {
                MaxAsyncOpsInvoked = this.asyncInvoked,
                MaxAsyncOpsPerformed = this.asyncPerformed,
                RemoteHost = stream.Host,
                RemotePort = stream.Port
            };

            try
            {
                DoSendAsync(stream, assoc).Wait();
            }
            catch (AggregateException e)
            {
                throw e.Flatten().InnerException;
            }
        }
Exemple #17
0
        private async Task DoSendAsync(INetworkStream stream, DicomAssociation association)
        {
            try
            {
                while (this.service != null)
                {
                    await Task.Delay(50).ConfigureAwait(false);
                }

                this.associateNotifier = new TaskCompletionSource<bool>();
                this.completeNotifier = new TaskCompletionSource<bool>();

                this.service = new DicomServiceUser(this, stream, association, Options, FallbackEncoding, Logger);

                await this.completeNotifier.Task.ConfigureAwait(false);
            }
            finally
            {
                Cleanup();
            }
        }
Exemple #18
0
 protected void SendAssociationRequest(DicomAssociation association)
 {
     LogID = association.CalledAE;
     Logger.Log(LogLevel.Info, "{0} -> Association request:\n{1}", LogID, association.ToString());
     Association = association;
     SendPDU(new AAssociateRQ(Association));
 }
Exemple #19
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);
            }
        }
Exemple #20
0
        protected void SendAssociationAccept(DicomAssociation association)
        {
            Association = association;

            // reject all presentation contexts that have not already been accepted or rejected
            foreach (var pc in Association.PresentationContexts) {
                if (pc.Result == DicomPresentationContextResult.Proposed)
                    pc.SetResult(DicomPresentationContextResult.RejectNoReason);
            }

            Logger.Log(LogLevel.Info, "{0} -> Association accept:\n{1}", LogID, association.ToString());
            SendPDU(new AAssociateAC(Association));
        }
Exemple #21
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);
            }
        }
Exemple #22
0
 /// <summary>
 /// Initializes new A-ASSOCIATE-AC
 /// </summary>
 /// <param name="assoc">Association parameters</param>
 public AAssociateAC(DicomAssociation assoc)
 {
     _assoc = assoc;
 }
Exemple #23
0
        /// <summary>
        /// Asynchronously send existing requests to DICOM service.
        /// </summary>
        /// <param name="stream">Established network stream.</param>
        /// <param name="callingAe">Calling Application Entity Title.</param>
        /// <param name="calledAe">Called Application Entity Title.</param>
        /// <returns>Awaitable task.</returns>
        public Task SendAsync(INetworkStream stream, string callingAe, string calledAe)
        {
            if (!CanSend) return Task.FromResult(false);   // TODO Replace with Task.CompletedTask when moving to .NET 4.6

            var assoc = new DicomAssociation(callingAe, calledAe)
            {
                MaxAsyncOpsInvoked = this.asyncInvoked,
                MaxAsyncOpsPerformed = this.asyncPerformed,
                RemoteHost = stream.Host,
                RemotePort = stream.Port
            };

            return DoSendAsync(stream, assoc);
        }
Exemple #24
0
            public void OnReceiveAssociationAccept(DicomAssociation association)
            {
                _client._assoc.Set();
                _client._assoc = null;

                foreach (var request in _client._requests) SendRequest(request);
                _client._requests.Clear();
            }
Exemple #25
0
		/// <summary>
		/// Initializes new A-ASSOCIATE-AC
		/// </summary>
		/// <param name="assoc">Association parameters</param>
		public AAssociateAC(DicomAssociation assoc) {
			_assoc = assoc;
		}
Exemple #26
0
 /// <summary>
 /// Initializes an instance of the <see cref="AssociationAcceptedEventArgs"/> class.
 /// </summary>
 /// <param name="association">Accepted association.</param>
 public AssociationAcceptedEventArgs(DicomAssociation association)
 {
     Association = association;
 }
Exemple #27
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);
            }
        }
Exemple #28
0
        private void InitializeSend(Stream stream, string callingAe, string calledAe)
        {
            var assoc = new DicomAssociation(callingAe, calledAe)
                            {
                                MaxAsyncOpsInvoked = this.asyncInvoked,
                                MaxAsyncOpsPerformed = this.asyncPerformed
                            };
            foreach (var request in this.requests)
            {
                assoc.PresentationContexts.AddFromRequest(request);
            }
            foreach (var context in this.AdditionalPresentationContexts)
            {
                assoc.PresentationContexts.Add(context.AbstractSyntax, context.GetTransferSyntaxes().ToArray());
            }

            this.associateNotifier = new TaskCompletionSource<bool>();
            this.completeNotifier = new TaskCompletionSource<bool>();

            this.service = new DicomServiceUser(this, stream, assoc, this.Options, this.Logger);
        }
Exemple #29
0
        /// <summary>
        /// Send association accept response.
        /// </summary>
        /// <param name="association">DICOM association.</param>
        protected void SendAssociationAccept(DicomAssociation association)
        {
            Association = association;

            // reject all presentation contexts that have not already been accepted or rejected
            foreach (var pc in Association.PresentationContexts)
            {
                if (pc.Result == DicomPresentationContextResult.Proposed) pc.SetResult(DicomPresentationContextResult.RejectNoReason);
            }

            Logger.Info("{logId} -> Association accept:\n{association}", LogID, association.ToString());
            this.SendPDUAsync(new AAssociateAC(Association)).Wait();
        }
Exemple #30
0
 internal DicomServiceUser(
     DicomClient client,
     Stream stream,
     DicomAssociation association,
     DicomServiceOptions options,
     Logger log)
     : base(stream, log)
 {
     this.client = client;
     this.isLingering = false;
     if (options != null) this.Options = options;
     this.SendAssociationRequest(association);
 }
Exemple #31
0
 public DicomServiceUser(DicomClient client, Stream stream, DicomAssociation association, Logger log)
     : base(stream, log)
 {
     _client = client;
     if (_client.Options != null) Options = _client.Options;
     SendAssociationRequest(association);
 }
Exemple #32
0
            internal DicomServiceUser(
                DicomClient client,
                INetworkStream stream,
                DicomAssociation association,
                DicomServiceOptions options,
                Encoding fallbackEncoding,
                Logger log)
                : base(stream, fallbackEncoding, log)
            {
                this.client = client;

                if (options != null)
                {
                    Options = options;
                }

                List<DicomRequest> requests;
                lock (this.client.locker)
                {
                    requests = new List<DicomRequest>(this.client.requests);
                }

                foreach (var request in requests)
                {
                    association.PresentationContexts.AddFromRequest(request);
                }

                foreach (var context in client.AdditionalPresentationContexts)
                {
                    association.PresentationContexts.Add(
                        context.AbstractSyntax,
                        context.UserRole,
                        context.ProviderRole,
                        context.GetTransferSyntaxes().ToArray());
                }

                SendAssociationRequest(association);
            }
		protected void SendAssociationRequest(DicomAssociation association) {
			LogID = association.CalledAE;
			if (Options.UseRemoteAEForLogName)
				Logger = LogManager.Default.GetLogger(LogID);
			Logger.Info("{0} -> Association request:\n{1}", LogID, association.ToString());
			Association = association;
			SendPDU(new AAssociateRQ(Association));
		}
Exemple #34
0
 public DicomServiceUser(DicomClient client, Stream stream, DicomAssociation association) : base(stream)
 {
     _client = client;
     SendAssociationRequest(association);
 }
Exemple #35
0
 public void OnReceiveAssociationRequest(DicomAssociation association)
 {
     if (association.CalledAE.Equals("ANY-SCP", StringComparison.OrdinalIgnoreCase))
     {
         Thread.Sleep(1000);
         DicomClientTest.remoteHost = association.RemoteHost;
         DicomClientTest.remotePort = association.RemotePort;
         this.SendAssociationAccept(association);
     }
     else
     {
         this.SendAssociationReject(
             DicomRejectResult.Permanent,
             DicomRejectSource.ServiceUser,
             DicomRejectReason.CalledAENotRecognized);
     }
 }
Exemple #36
0
 public void OnReceiveAssociationRequest(DicomAssociation association)
 {
     Thread.Sleep(1000);
     this.SendAssociationAccept(association);
 }