public void AssociateAC_WriteRead_ExpectedExtendedNegotiation(DicomUID sopClassUid, DicomServiceApplicationInfo applicationInfo, DicomUID commonServiceClass, DicomUID[] relatedSopClasses) { var inAssociation = new DicomAssociation("testCalling", "testCalled"); inAssociation.ExtendedNegotiations.Add(sopClassUid, applicationInfo, commonServiceClass, relatedSopClasses); var acceptedApplicationInfo = new DicomServiceApplicationInfo(applicationInfo.GetValues()); acceptedApplicationInfo.AddOrUpdate(1, 10); inAssociation.ExtendedNegotiations.AcceptApplicationInfo(sopClassUid, acceptedApplicationInfo); var ac = new AAssociateAC(inAssociation); var writePdu = ac.Write(); var readPdu = ConvertWriteToReadPdu(writePdu); var outAssociation = new DicomAssociation(); outAssociation.ExtendedNegotiations.Add(sopClassUid, applicationInfo); var ac2 = new AAssociateAC(outAssociation); ac2.Read(readPdu); Assert.Single(outAssociation.ExtendedNegotiations); var negotiation = outAssociation.ExtendedNegotiations.First(); Assert.Equal(sopClassUid, negotiation.SopClassUid); Assert.Equal(applicationInfo, negotiation.RequestedApplicationInfo); Assert.Equal(acceptedApplicationInfo, negotiation.AcceptedApplicationInfo); Assert.Null(negotiation.ServiceClassUid); Assert.Empty(negotiation.RelatedGeneralSopClasses); }
public void AssociateAC_Read_TransferSyntaxIdentifiedIfAccept(byte[] buffer, byte contextId, DicomPresentationContextResult result, DicomTransferSyntax syntax) { var association = new DicomAssociation(); association.PresentationContexts.Add( new DicomPresentationContext(contextId, DicomUID.Verification)); using (var raw = new RawPDU(buffer)) { var accept = new AAssociateAC(association); accept.Read(raw); var actual = association.PresentationContexts[contextId]; Assert.Equal(result, actual.Result); Assert.Equal(syntax, actual.AcceptedTransferSyntax); } }
/// <summary> /// The called AE shall accept or reject the association by sending an A-ASSOCIATE /// response primitive with an appropriate Result parameter. The Upper layer /// service-provider shall issue an A-ASSOCIATE confirmation primitive having the /// same Result parameter. The Result Source parameter shall be assigned the /// symbolic value of “UL service-user.” /// </summary> /// <param name="associate"></param> protected void SendAssociateAccept(DcmAssociate associate) { Log.Info("{0} -> Association accept:\n{1}", LogID, Associate.ToString()); AAssociateAC pdu = new AAssociateAC(_assoc); SendRawPDU(pdu.Write()); }
private bool ProcessNextPDU() { RawPDU raw = new RawPDU(_network); if (raw.Type == 0x04) { if (_dimse == null) { _dimse = new DcmDimseInfo(); } } try { raw.ReadPDU(); switch (raw.Type) { case 0x01: { _assoc = new DcmAssociate(); AAssociateRQ pdu = new AAssociateRQ(_assoc); pdu.Read(raw); Log.Info("{0} <- Association request:\n{1}", LogID, Associate.ToString()); OnReceiveAssociateRequest(_assoc); return true; } case 0x02: { AAssociateAC pdu = new AAssociateAC(_assoc); pdu.Read(raw); Log.Info("{0} <- Association accept:\n{1}", LogID, Associate.ToString()); OnReceiveAssociateAccept(_assoc); return true; } case 0x03: { AAssociateRJ pdu = new AAssociateRJ(); pdu.Read(raw); Log.Info("{0} <- Association reject [result: {1}; source: {2}; reason: {3}]", LogID, pdu.Result, pdu.Source, pdu.Reason); OnReceiveAssociateReject(pdu.Result, pdu.Source, pdu.Reason); return true; } case 0x04: { PDataTF pdu = new PDataTF(); pdu.Read(raw); //Log.Debug("{0} <- P-Data-TF", LogID); return ProcessPDataTF(pdu); } case 0x05: { AReleaseRQ pdu = new AReleaseRQ(); pdu.Read(raw); Log.Info("{0} <- Association release request", LogID); OnReceiveReleaseRequest(); return true; } case 0x06: { AReleaseRP pdu = new AReleaseRP(); pdu.Read(raw); Log.Info("{0} <- Association release response", LogID); OnReceiveReleaseResponse(); return true; } case 0x07: { AAbort pdu = new AAbort(); pdu.Read(raw); Log.Info("{0} <- Association abort: {1} - {2}", LogID, pdu.Source, pdu.Reason); OnReceiveAbort(pdu.Source, pdu.Reason); return true; } case 0xFF: { return false; } default: throw new DicomNetworkException("Unknown PDU type"); } } catch (SocketException) { throw; } catch (Exception e) { #if DEBUG Log.Error("{0} -> Error reading PDU [type: 0x{1:x2}]: {2}", LogID, raw.Type, e.ToString()); #else Log.Error("{0} -> Error reading PDU [type: 0x{1:x2}]: {2}", LogID, raw.Type, e.Message); #endif OnNetworkError(e); //String file = String.Format(@"{0}\Errors\{1}.pdu", // Dicom.Debug.GetStartDirectory(), DateTime.Now.Ticks); //Directory.CreateDirectory(Dicom.Debug.GetStartDirectory() + @"\Errors"); //raw.Save(file); return false; } }
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 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); } }
private void EndReadPDU(IAsyncResult result) { try { byte[] buffer = (byte[])result.AsyncState; int count = _network.EndRead(result); if (count == 0) { // disconnected _network.Close(); _isConnected = false; return; } _readLength -= count; if (_readLength > 0) { _network.BeginRead(buffer, buffer.Length - _readLength, _readLength, EndReadPDU, buffer); return; } var raw = new RawPDU(buffer); switch (raw.Type) { case 0x01: { Association = new DicomAssociation(); var pdu = new AAssociateRQ(Association); pdu.Read(raw); LogID = Association.CallingAE; Logger.Log(LogLevel.Info, "{0} <- Association request:\n{1}", LogID, Association.ToString()); if (this is IDicomServiceProvider) { (this as IDicomServiceProvider).OnReceiveAssociationRequest(Association); } break; } case 0x02: { var pdu = new AAssociateAC(Association); pdu.Read(raw); LogID = Association.CalledAE; Logger.Log(LogLevel.Info, "{0} <- Association accept:\n{1}", LogID, Association.ToString()); if (this is IDicomServiceUser) { (this as IDicomServiceUser).OnReceiveAssociationAccept(Association); } break; } case 0x03: { var pdu = new AAssociateRJ(); pdu.Read(raw); Logger.Log(LogLevel.Info, "{0} <- Association reject [result: {1}; source: {2}; reason: {3}]", LogID, pdu.Result, pdu.Source, pdu.Reason); if (this is IDicomServiceUser) { (this as IDicomServiceUser).OnReceiveAssociationReject(pdu.Result, pdu.Source, pdu.Reason); } break; } case 0x04: { var pdu = new PDataTF(); pdu.Read(raw); ProcessPDataTF(pdu); break; } case 0x05: { var pdu = new AReleaseRQ(); pdu.Read(raw); Logger.Log(LogLevel.Info, "{0} <- Association release request", LogID); if (this is IDicomServiceProvider) { (this as IDicomServiceProvider).OnReceiveAssociationReleaseRequest(); } break; } case 0x06: { var pdu = new AReleaseRP(); pdu.Read(raw); Logger.Log(LogLevel.Info, "{0} <- Association release response", LogID); if (this is IDicomServiceUser) { (this as IDicomServiceUser).OnReceiveAssociationReleaseResponse(); } _network.Close(); _isConnected = false; break; } case 0x07: { var pdu = new AAbort(); pdu.Read(raw); Logger.Log(LogLevel.Info, "{0} <- Abort: {1} - {2}", LogID, pdu.Source, pdu.Reason); if (this is IDicomServiceProvider) { (this as IDicomServiceProvider).OnReceiveAbort(pdu.Source, pdu.Reason); } else if (this is IDicomServiceUser) { (this as IDicomServiceUser).OnReceiveAbort(pdu.Source, pdu.Reason); } _network.Close(); _isConnected = false; break; } case 0xFF: { break; } default: throw new DicomNetworkException("Unknown PDU type"); } BeginReadPDUHeader(); } catch (Exception e) { Logger.Log(LogLevel.Error, "Exception processing PDU: {0}", e.ToString()); _network.Close(); _isConnected = false; } }
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); } }
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); } }