private void OnEndSendCommand(IAsyncResult result) { var dimse = result.AsyncState as Dimse; try { dimse.Walker.EndWalk(result); dimse.Stream.IsCommand = false; var writer = new DicomWriter(dimse.PresentationContext.AcceptedTransferSyntax, DicomWriteOptions.Default, new StreamByteTarget(dimse.Stream)); dimse.Walker = new DicomDatasetWalker(dimse.Message.Dataset); dimse.Walker.BeginWalk(writer, OnEndSendMessage, dimse); } catch (Exception e) { Logger.Error("Exception sending DIMSE: {0}", e.ToString()); } finally { if (!dimse.Message.HasDataset) { lock (_lock) _sending = false; SendNextMessage(); } } }
private void SendNextMessage() { DicomMessage msg; lock (_lock) { if (_msgQueue.Count == 0) { if (_pending.Count == 0) { OnSendQueueEmpty(); } return; } if (_sending) { return; } if (Association.MaxAsyncOpsInvoked > 0 && _pending.Count >= Association.MaxAsyncOpsInvoked) { return; } _sending = true; msg = _msgQueue.Dequeue(); } if (msg is DicomRequest) { _pending.Add(msg as DicomRequest); } DicomPresentationContext pc = null; if (msg is DicomCStoreRequest) { pc = Association.PresentationContexts.FirstOrDefault(x => x.Result == DicomPresentationContextResult.Accept && x.AbstractSyntax == msg.SOPClassUID && x.AcceptedTransferSyntax == (msg as DicomCStoreRequest).TransferSyntax); if (pc == null) { pc = Association.PresentationContexts.FirstOrDefault(x => x.Result == DicomPresentationContextResult.Accept && x.AbstractSyntax == msg.SOPClassUID); } } else { pc = Association.PresentationContexts.FirstOrDefault(x => x.Result == DicomPresentationContextResult.Accept && x.AbstractSyntax == msg.SOPClassUID); } if (pc == null) { pc = msg.PresentationContext; } if (pc == null) { _pending.Remove(msg as DicomRequest); try { if (msg is DicomCStoreRequest) { (msg as DicomCStoreRequest).PostResponse(this, new DicomCStoreResponse(msg as DicomCStoreRequest, DicomStatus.SOPClassNotSupported)); } else if (msg is DicomCEchoRequest) { (msg as DicomCEchoRequest).PostResponse(this, new DicomCEchoResponse(msg as DicomCEchoRequest, DicomStatus.SOPClassNotSupported)); } else if (msg is DicomCFindRequest) { (msg as DicomCFindRequest).PostResponse(this, new DicomCFindResponse(msg as DicomCFindRequest, DicomStatus.SOPClassNotSupported)); } else if (msg is DicomCMoveRequest) { (msg as DicomCMoveRequest).PostResponse(this, new DicomCMoveResponse(msg as DicomCMoveRequest, DicomStatus.SOPClassNotSupported)); } //TODO: add N services } catch { } Logger.Error("No accepted presentation context found for abstract syntax: {0}", msg.SOPClassUID); lock (_lock) _sending = false; SendNextMessage(); return; } var dimse = new Dimse(); dimse.Message = msg; dimse.PresentationContext = pc; // force calculation of command group length as required by standard msg.Command.RecalculateGroupLengths(); if (msg.HasDataset) { // remove group lengths as recommended in PS 3.5 7.2 // // 2. It is recommended that Group Length elements be removed during storage or transfer // in order to avoid the risk of inconsistencies arising during coercion of data // element values and changes in transfer syntax. msg.Dataset.RemoveGroupLengths(); if (msg.Dataset.InternalTransferSyntax != dimse.PresentationContext.AcceptedTransferSyntax) { msg.Dataset = msg.Dataset.ChangeTransferSyntax(dimse.PresentationContext.AcceptedTransferSyntax); } } Logger.Info("{0} -> {1}", LogID, msg.ToString(Options.LogDimseDatasets)); dimse.Stream = new PDataTFStream(this, pc.ID, Association.MaximumPDULength); var writer = new DicomWriter(DicomTransferSyntax.ImplicitVRLittleEndian, DicomWriteOptions.Default, new StreamByteTarget(dimse.Stream)); dimse.Walker = new DicomDatasetWalker(msg.Command); if (dimse.Message.HasDataset) { dimse.Walker.BeginWalk(writer, OnEndSendCommand, dimse); } else { dimse.Walker.BeginWalk(writer, OnEndSendMessage, dimse); } }
private void SendNextMessage() { DicomMessage msg; lock (_lock) { if (_msgQueue.Count == 0) { if (_pending.Count == 0) { OnSendQueueEmpty(); } return; } if (_sending) { return; } if (Association.MaxAsyncOpsInvoked > 0 && _pending.Count >= Association.MaxAsyncOpsInvoked) { return; } _sending = true; msg = _msgQueue.Dequeue(); } Logger.Log(LogLevel.Info, "{0} -> {1}", LogID, msg); if (msg is DicomRequest) { _pending.Add(msg as DicomRequest); } DicomPresentationContext pc = null; if (msg is DicomCStoreRequest) { pc = Association.PresentationContexts.FirstOrDefault(x => x.Result == DicomPresentationContextResult.Accept && x.AbstractSyntax == msg.AffectedSOPClassUID && x.AcceptedTransferSyntax == (msg as DicomCStoreRequest).TransferSyntax); if (pc == null) { pc = Association.PresentationContexts.FirstOrDefault(x => x.Result == DicomPresentationContextResult.Accept && x.AbstractSyntax == msg.AffectedSOPClassUID); } } else { pc = Association.PresentationContexts.FirstOrDefault(x => x.Result == DicomPresentationContextResult.Accept && x.AbstractSyntax == msg.AffectedSOPClassUID); } if (pc == null) { throw new DicomNetworkException("No accepted presentation context found for abstract syntax: {0}", msg.AffectedSOPClassUID); } var dimse = new Dimse(); dimse.Message = msg; dimse.PresentationContext = pc; dimse.Stream = new PDataTFStream(this, pc.ID, (int)Association.MaximumPDULength); var writer = new DicomWriter(DicomTransferSyntax.ImplicitVRLittleEndian, DicomWriteOptions.Default, new StreamByteTarget(dimse.Stream)); dimse.Walker = new DicomDatasetWalker(msg.Command); dimse.Walker.BeginWalk(writer, OnEndSendCommand, dimse); }