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); }
public void OnReceiveAssociationRequest(DicomAssociation association) { foreach (var pc in association.PresentationContexts) { pc.AcceptTransferSyntaxes(AcceptedImageTransferSyntaxes); } SendAssociationAccept(association); }
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); }
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); }
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); }
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); }
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)); }
//下面这部分是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); }
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); }
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(); } }
/// <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(); } } } }
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; }
/// <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(); }
/// <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; } }
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(); } }
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)); }
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); } }
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)); }
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); } }
/// <summary> /// Initializes new A-ASSOCIATE-AC /// </summary> /// <param name="assoc">Association parameters</param> public AAssociateAC(DicomAssociation assoc) { _assoc = assoc; }
/// <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); }
public void OnReceiveAssociationAccept(DicomAssociation association) { _client._assoc.Set(); _client._assoc = null; foreach (var request in _client._requests) SendRequest(request); _client._requests.Clear(); }
/// <summary> /// Initializes an instance of the <see cref="AssociationAcceptedEventArgs"/> class. /// </summary> /// <param name="association">Accepted association.</param> public AssociationAcceptedEventArgs(DicomAssociation association) { Association = association; }
private async void ReadAndProcessPDUs() { try { while (this.IsConnected) { // Read PDU header _readLength = 6; var buffer = new byte[6]; var count = await this._network.ReadAsync(buffer, 0, 6).ConfigureAwait(false); do { if (count == 0) { // disconnected this.CloseConnection(null); return; } this._readLength -= count; if (this._readLength > 0) { count = await this._network.ReadAsync(buffer, 6 - this._readLength, this._readLength) .ConfigureAwait(false); } } while (this._readLength > 0); var length = BitConverter.ToInt32(buffer, 2); length = Endian.Swap(length); this._readLength = length; Array.Resize(ref buffer, length + 6); count = await this._network.ReadAsync(buffer, 6, length).ConfigureAwait(false); // Read PDU do { if (count == 0) { // disconnected this.CloseConnection(null); return; } this._readLength -= count; if (this._readLength > 0) { count = await this._network.ReadAsync(buffer, buffer.Length - this._readLength, this._readLength) .ConfigureAwait(false); } } while (this._readLength > 0); var raw = new RawPDU(buffer); switch (raw.Type) { case 0x01: { Association = new DicomAssociation(); var pdu = new AAssociateRQ(Association); pdu.Read(raw); LogID = Association.CallingAE; if (Options.UseRemoteAEForLogName) Logger = LogManager.GetLogger(LogID); Logger.Info( "{callingAE} <- Association request:\n{association}", LogID, Association.ToString()); if (this is IDicomServiceProvider) (this as IDicomServiceProvider).OnReceiveAssociationRequest(Association); break; } case 0x02: { var pdu = new AAssociateAC(Association); pdu.Read(raw); LogID = Association.CalledAE; Logger.Info( "{calledAE} <- Association accept:\n{assocation}", LogID, Association.ToString()); if (this is IDicomServiceUser) (this as IDicomServiceUser).OnReceiveAssociationAccept(Association); break; } case 0x03: { var pdu = new AAssociateRJ(); pdu.Read(raw); Logger.Info( "{logId} <- Association reject [result: {pduResult}; source: {pduSource}; reason: {pduReason}]", LogID, pdu.Result, pdu.Source, pdu.Reason); if (this is IDicomServiceUser) (this as IDicomServiceUser).OnReceiveAssociationReject( pdu.Result, pdu.Source, pdu.Reason); break; } case 0x04: { var pdu = new PDataTF(); pdu.Read(raw); if (Options.LogDataPDUs) Logger.Info("{logId} <- {@pdu}", LogID, pdu); await this.ProcessPDataTFAsync(pdu).ConfigureAwait(false); break; } case 0x05: { var pdu = new AReleaseRQ(); pdu.Read(raw); Logger.Info("{logId} <- Association release request", LogID); if (this is IDicomServiceProvider) (this as IDicomServiceProvider).OnReceiveAssociationReleaseRequest(); break; } case 0x06: { var pdu = new AReleaseRP(); pdu.Read(raw); Logger.Info("{logId} <- Association release response", LogID); if (this is IDicomServiceUser) (this as IDicomServiceUser).OnReceiveAssociationReleaseResponse(); CloseConnection(null); return; } case 0x07: { var pdu = new AAbort(); pdu.Read(raw); Logger.Info( "{logId} <- Abort: {pduSource} - {pduReason}", LogID, pdu.Source, pdu.Reason); if (this is IDicomServiceProvider) (this as IDicomServiceProvider).OnReceiveAbort(pdu.Source, pdu.Reason); else if (this is IDicomServiceUser) (this as IDicomServiceUser).OnReceiveAbort(pdu.Source, pdu.Reason); CloseConnection(null); return; } case 0xFF: { break; } default: throw new DicomNetworkException("Unknown PDU type"); } } } catch (ObjectDisposedException) { // silently ignore CloseConnection(null); } catch (NullReferenceException) { // connection already closed; silently ignore CloseConnection(null); } catch (IOException e) { LogIOException(this.Logger, e, true); CloseConnection(e); } catch (Exception e) { Logger.Error("Exception processing PDU: {@error}", e); CloseConnection(e); } }
private 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); }
/// <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(); }
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); }
public DicomServiceUser(DicomClient client, Stream stream, DicomAssociation association, Logger log) : base(stream, log) { _client = client; if (_client.Options != null) Options = _client.Options; SendAssociationRequest(association); }
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)); }
public DicomServiceUser(DicomClient client, Stream stream, DicomAssociation association) : base(stream) { _client = client; SendAssociationRequest(association); }
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); } }