示例#1
0
        private void SendNextMessage()
        {
            while (true)
            {
                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: {sopClassUid}",
                        msg.SOPClassUID);
                }
                else
                {
                    var dimse = new Dimse
                    {
                        Message = msg,
                        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("{logId} -> {dicomMessage}", LogID, msg.ToString(Options.LogDimseDatasets));

                    try
                    {
                        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);
                        dimse.Walker.Walk(writer);

                        if (dimse.Message.HasDataset)
                        {
                            dimse.Stream.IsCommand = false;

                            writer = new DicomWriter(
                                dimse.PresentationContext.AcceptedTransferSyntax,
                                DicomWriteOptions.Default,
                                new StreamByteTarget(dimse.Stream));

                            dimse.Walker = new DicomDatasetWalker(dimse.Message.Dataset);
                            dimse.Walker.Walk(writer);
                        }
                    }
                    catch (Exception e)
                    {
                        Logger.Error("Exception sending DIMSE: {@error}", e);
                    }
                    finally
                    {
                        dimse.Stream.Flush(true).Wait();
                        dimse.Stream.Dispose();
                    }
                }

                lock (_lock) _sending = false;
            }
        }
示例#2
0
        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);
            }
        }
示例#3
0
        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);
        }
示例#4
0
		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) {
				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);
		}
示例#5
0
 internal void FireReceived(Dimse dimse)
 {
     if (Logger.IsInfoEnabled) {
         Logger.Info("received " + dimse);
     }
     if (assocListener != null) {
         assocListener.Received(assoc, dimse);
     }
 }
示例#6
0
        private void SendNextMessage()
        {
            while (true)
            {
                DicomMessage msg;

                lock (_lock)
                {
                    if (_sending)
                    {
                        return;
                    }

                    if (_msgQueue.Count == 0)
                    {
                        if (_pending.Count == 0) OnSendQueueEmpty();
                        return;
                    }

                    if (!Options.IgnoreAsyncOps && Association.MaxAsyncOpsInvoked > 0
                        && _pending.Count >= Association.MaxAsyncOpsInvoked)
                    {
                        Logger.Debug("Cannot send messages since pending: {pending} would exceed max async ops invoked: {invoked}",
                            _pending.Count,
                            Association.MaxAsyncOpsInvoked);
                        return;
                        // Cannot easily recover from this unwanted state, so better to throw.
                        throw new DicomNetworkException(
                            "Cannot send messages since pending: {0} would exceed max async ops invoked: {1}",
                            _pending.Count,
                            Association.MaxAsyncOpsInvoked);
                    }

                    _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 if (msg is DicomResponse)
                {
                    //the presentation context should be set already from the request object
                    pc = msg.PresentationContext;

                    //fail safe if no presentation context is already assigned to the response (is this going to happen)
                    if (pc == null)
                    {
                        pc = this.Association.PresentationContexts.FirstOrDefault<DicomPresentationContext>(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)
                {
                    lock (_lock)
                    {
                        _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 DicomCGetRequest)
                            (msg as DicomCGetRequest).PostResponse(
                                this,
                                new DicomCGetResponse(
                                    msg as DicomCGetRequest,
                                    DicomStatus.SOPClassNotSupported));
                        else if (msg is DicomCMoveRequest)
                            (msg as DicomCMoveRequest).PostResponse(
                                this,
                                new DicomCMoveResponse(
                                    msg as DicomCMoveRequest,
                                    DicomStatus.SOPClassNotSupported));
                        else if (msg is DicomNActionRequest)
                            (msg as DicomNActionRequest).PostResponse(
                                this,
                                new DicomNActionResponse(
                                    msg as DicomNActionRequest,
                                    DicomStatus.SOPClassNotSupported));
                        else if (msg is DicomNCreateRequest)
                            (msg as DicomNCreateRequest).PostResponse(
                                this,
                                new DicomNCreateResponse(
                                    msg as DicomNCreateRequest,
                                    DicomStatus.SOPClassNotSupported));
                        else if (msg is DicomNDeleteRequest)
                            (msg as DicomNDeleteRequest).PostResponse(
                                this,
                                new DicomNDeleteResponse(
                                    msg as DicomNDeleteRequest,
                                    DicomStatus.SOPClassNotSupported));
                        else if (msg is DicomNEventReportRequest)
                            (msg as DicomNEventReportRequest).PostResponse(
                                this,
                                new DicomNEventReportResponse(
                                    msg as DicomNEventReportRequest,
                                    DicomStatus.SOPClassNotSupported));
                        else if (msg is DicomNGetRequest)
                            (msg as DicomNGetRequest).PostResponse(
                                this,
                                new DicomNGetResponse(
                                    msg as DicomNGetRequest,
                                    DicomStatus.SOPClassNotSupported));
                        else if (msg is DicomNSetRequest)
                            (msg as DicomNSetRequest).PostResponse(
                                this,
                                new DicomNSetResponse(
                                    msg as DicomNSetRequest,
                                    DicomStatus.SOPClassNotSupported));
                        else
                        {
                            Logger.Warn("Unknown message type: {type}", msg.Type);
                        }
                    }
                    catch
                    {
                    }

                    Logger.Error(
                        "No accepted presentation context found for abstract syntax: {sopClassUid}",
                        msg.SOPClassUID);
                }
                else
                {
                    var dimse = new Dimse
                    {
                        Message = msg,
                        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)
                        {
                            Logger.Debug("{logId} Changing Transfer Syntax from {0} to {1}", LogID, msg.Dataset.InternalTransferSyntax, dimse.PresentationContext.AcceptedTransferSyntax);
                            msg.Dataset =
                                msg.Dataset.Clone(dimse.PresentationContext.AcceptedTransferSyntax);
                        }
                    }

                    Logger.Info("{logId} -> {dicomMessage}", LogID, msg.ToString(Options.LogDimseDatasets));

                    try
                    {
                        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);
                        dimse.Walker.Walk(writer);

                        if (dimse.Message.HasDataset)
                        {
                            dimse.Stream.SetIsCommandAsync(false).Wait();

                            writer = new DicomWriter(
                                dimse.PresentationContext.AcceptedTransferSyntax,
                                DicomWriteOptions.Default,
                                new StreamByteTarget(dimse.Stream));

                            dimse.Walker = new DicomDatasetWalker(dimse.Message.Dataset);
                            dimse.Walker.Walk(writer);
                        }
                    }
                    catch (Exception e)
                    {
                        Logger.Error("Exception sending DIMSE: {@error}", e);
                    }
                    finally
                    {
                        dimse.Stream.FlushAsync(true).Wait();
                        dimse.Stream.Dispose();
                    }
                }

                lock (_lock) _sending = false;
            }
        }