Exemplo n.º 1
0
        /// <summary>
        /// Method to send an association release request.  this method can only be used by clients.
        /// </summary>
        public void SendReleaseRequest()
        {
            if (State != DicomAssociationState.Sta6_AssociationEstablished)
            {
                Platform.Log(LogLevel.Error, "Unexpected attempt to send Release Request when in invalid state.");
                return;
            }

            var pdu = new AReleaseRQ();

            EnqueuePdu(pdu.Write());

            State = DicomAssociationState.Sta7_AwaitingAReleaseRP;

            // still waiting for remote AE to send release response
            if (AssociationReleasing != null)
                AssociationReleasing(_assoc);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Method to send an association release response.
        /// </summary>
        protected void SendReleaseResponse()
        {
            if (State != DicomAssociationState.Sta8_AwaitingAReleaseRPLocalUser)
            {
            }

            var pdu = new AReleaseRP();

            EnqueuePdu(pdu.Write());
            State = DicomAssociationState.Sta13_AwaitingTransportConnectionClose;

            if (AssociationReleased != null)
                AssociationReleased(_assoc);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Method to send an association accept.
        /// </summary>
        /// <param name="associate">The parameters to use for the association accept.</param>
        public void SendAssociateAccept(AssociationParameters associate)
        {
            if (State != DicomAssociationState.Sta3_AwaitingLocalAAssociationResponsePrimative)
            {
                Platform.Log(LogLevel.Error, "Error attempting to send association accept at invalid time in association.");
                SendAssociateAbort(DicomAbortSource.ServiceProvider, DicomAbortReason.NotSpecified);
                throw new DicomNetworkException(
                    "Attempting to send association accept at invalid time in association, aborting");
            }
            var pdu = new AAssociateAC(_assoc);

            EnqueuePdu(pdu.Write());

            State = DicomAssociationState.Sta6_AssociationEstablished;


            if (AssociationEstablished != null)
                AssociationEstablished(_assoc);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Method to send an association rejection.
        /// </summary>
        /// <param name="result">The </param>
        /// <param name="source"></param>
        /// <param name="reason"></param>
        public void SendAssociateReject(DicomRejectResult result, DicomRejectSource source, DicomRejectReason reason)
        {
            if (State != DicomAssociationState.Sta3_AwaitingLocalAAssociationResponsePrimative)
            {
                Platform.Log(LogLevel.Error, "Error attempting to send association reject at invalid time in association.");
                SendAssociateAbort(DicomAbortSource.ServiceProvider, DicomAbortReason.NotSpecified);
                throw new DicomNetworkException(
                    "Attempting to send association reject at invalid time in association, aborting");
            }
            var pdu = new AAssociateRJ(result, source, reason);

            EnqueuePdu(pdu.Write());

            State = DicomAssociationState.Sta13_AwaitingTransportConnectionClose;

            if (AssociationRejected != null)
                AssociationRejected(source, reason);
        }
Exemplo n.º 5
0
        /// <summary>
        /// Method to send an association abort PDU.
        /// </summary>
        /// <param name="source">The source of the abort.</param>
        /// <param name="reason">The reason for the abort.</param>
        public void SendAssociateAbort(DicomAbortSource source, DicomAbortReason reason)
        {
            if (State != DicomAssociationState.Sta13_AwaitingTransportConnectionClose)
            {
                var pdu = new AAbort(source, reason);

                EnqueuePdu(pdu.Write());
                State = DicomAssociationState.Sta13_AwaitingTransportConnectionClose;


                if (AssociationAborted != null)
                    AssociationAborted(_assoc, reason);
            }
            else
            {
                Platform.Log(LogLevel.Error, "Unexpected state for association abort, closing connection from {0} to {1}",
                                     _assoc.CallingAE, _assoc.CalledAE);

				OnNetworkError(null, true);

                if (NetworkClosed != null)
                    NetworkClosed("Unexpected state for association abort");
            }
        }
Exemplo n.º 6
0
        /// <summary>
        /// Method used to send an association request.
        /// </summary>
        /// <param name="associate">The parameters used in the association request.</param>
        public void SendAssociateRequest(AssociationParameters associate)
        {
            _assoc = associate;
            var pdu = new AAssociateRQ(_assoc);

        	State = DicomAssociationState.Sta5_AwaitingAAssociationACOrReject;

            EnqueuePdu(pdu.Write());

        }
Exemplo n.º 7
0
        private bool ProcessRawPDU(RawPDU raw)
        {
            try
            {
                switch (raw.Type)
                {
                    case 0x01:
                        {
                            _assoc = new ServerAssociationParameters();
                            var pdu = new AAssociateRQ(_assoc);
                            pdu.Read(raw);
                            State = DicomAssociationState.Sta3_AwaitingLocalAAssociationResponsePrimative;
                            OnReceiveAssociateRequest(_assoc as ServerAssociationParameters);

                            if (State != DicomAssociationState.Sta13_AwaitingTransportConnectionClose &&
                                State != DicomAssociationState.Sta6_AssociationEstablished)
                            {
                                Platform.Log(LogLevel.Error, "Association incorrectly not accepted or rejected, aborting.");
                                return false;
                            }

                            //if derived class call SendAssociateAccept, it has fired this event
                            //if (AssociationEstablished != null)
                            //    AssociationEstablished(_assoc);

                            return true;
                        }
                    case 0x02:
                        {
                            var pdu = new AAssociateAC(_assoc);
                            pdu.Read(raw);
                            State = DicomAssociationState.Sta6_AssociationEstablished;

                            OnReceiveAssociateAccept(_assoc);

                            if (AssociationEstablished != null)
                                AssociationEstablished(_assoc);

                            return true;
                        }
                    case 0x03:
                        {
                            var pdu = new AAssociateRJ();
                            pdu.Read(raw);
                            State = DicomAssociationState.Sta13_AwaitingTransportConnectionClose;

                            if (AssociationRejected != null)
                                AssociationRejected(pdu.Source, pdu.Reason);

                            OnReceiveAssociateReject(pdu.Result, pdu.Source, pdu.Reason);

                            return true;
                        }
                    case 0x04:
                        {
                            var pdu = new PDataTF();
                            pdu.Read(raw);
                            return ProcessPDataTF(pdu);
                        }
                    case 0x05:
                        {
                            var pdu = new AReleaseRQ();
                            pdu.Read(raw);
                            State = DicomAssociationState.Sta8_AwaitingAReleaseRPLocalUser;

                            OnReceiveReleaseRequest();

                            return true;
                        }
                    case 0x06:
                        {
                            var pdu = new AReleaseRP();
                            pdu.Read(raw);
                            State = DicomAssociationState.Sta13_AwaitingTransportConnectionClose;

                            if (AssociationReleased != null)
                                AssociationReleased(_assoc);


                            OnReceiveReleaseResponse();

                            return true;
                        }
                    case 0x07:
                        {
                            var pdu = new AAbort();
                            pdu.Read(raw);
                            State = DicomAssociationState.Sta1_Idle;

                            if (AssociationAborted != null)
                                AssociationAborted(_assoc, pdu.Reason);

                            OnReceiveAbort(pdu.Source, pdu.Reason);

                            return true;
                        }
                    case 0xFF:
                        {
                            Platform.Log(LogLevel.Error, "Unexpected PDU type: 0xFF.  Potential parsing error.");
                            return false;
                        }
                    default:
                        throw new DicomNetworkException("Unknown PDU type");
                }
            }
            catch (Exception e)
            {
                OnNetworkError(e, true);

                if (NetworkError != null)
                    NetworkError(e);

                Platform.Log(LogLevel.Error, e, "Unexpected exception when processing PDU.");
                return false;
            }
        }
Exemplo n.º 8
0
        /// <summary>
        /// Main processing routine for processing a network connection.
        /// </summary>
        private void RunRead()
        {
            try
            {
				ResetDimseTimeout();

				while (!_stop)
                {
                    if (NetworkHasData())
                    {
                        ResetDimseTimeout();

                        bool success = ProcessNextPDU();
                        if (!success)
                        {
                            // Start the Abort process, not much else we can do
                            Platform.Log(LogLevel.Error,
                                "Unexpected error processing PDU.  Aborting Association from {0} to {1}",
                                _assoc.CallingAE, _assoc.CalledAE);
                            SendAssociateAbort(DicomAbortSource.ServiceProvider, DicomAbortReason.InvalidPDUParameter);
                        }
                    }
                    else if (DateTime.Now > GetDimseTimeout())
                    {
                    	string errorMessage;
                    	switch (State)
                        {
                        	case DicomAssociationState.Sta6_AssociationEstablished:
                        		OnDimseTimeout();
								ResetDimseTimeout();
                        		break;
                        	case DicomAssociationState.Sta2_TransportConnectionOpen:
                        		errorMessage = "ARTIM timeout when waiting for AAssociate Request PDU, closing connection.";
                        		Platform.Log(LogLevel.Error, errorMessage);
                        		State = DicomAssociationState.Sta13_AwaitingTransportConnectionClose;
                        		OnNetworkError(new DicomNetworkException(errorMessage), true);
                        		if (NetworkClosed != null)
                        			NetworkClosed(errorMessage);
                        		break;
                        	case DicomAssociationState.Sta5_AwaitingAAssociationACOrReject:
                        		errorMessage = "ARTIM timeout when waiting for AAssociate AC or RJ PDU, closing connection.";
                        		Platform.Log(LogLevel.Error,errorMessage );
                        		State = DicomAssociationState.Sta13_AwaitingTransportConnectionClose;
								OnNetworkError(new DicomNetworkException(errorMessage), true);
                        		if (NetworkClosed != null)
                        			NetworkClosed(errorMessage);
                        		break;
                        	case DicomAssociationState.Sta13_AwaitingTransportConnectionClose:
                        		errorMessage = string.Format(
                        				"Timeout when waiting for transport connection to close from {0} to {1}.  Dropping Connection.",
                        				_assoc.CallingAE, _assoc.CalledAE);
                        		Platform.Log(LogLevel.Error, errorMessage);
								OnNetworkError(new DicomNetworkException(errorMessage), true);
                        		if (NetworkClosed != null)
                        			NetworkClosed(errorMessage);
                        		break;
                        	default:
                        		Platform.Log(LogLevel.Error, "DIMSE timeout in unexpected state: {0}", State.ToString());
                        		OnDimseTimeout();
								ResetDimseTimeout();
                        		break;
                        }
                    }
					//else
					//{
					//    Thread.Sleep(0);
					//}
                }
                _network.Close();
                _network.Dispose();
                _network = null;
            }
            catch (Exception e)
            {
                OnNetworkError(e, true);

                if (NetworkError != null)
                    NetworkError(e);
            }
        }
Exemplo n.º 9
0
        /// <summary>
        /// Main processing routine for processing a network connection.
        /// </summary>
        private void Process()
        {
            try
            {
            	DateTime timeout = _assoc != null
            	                   	? DateTime.Now.AddMilliseconds(_assoc.ReadTimeout)
            	                   	: DateTime.Now.AddSeconds(Timeout);

				while (!_stop)
                {
                    if (NetworkHasData())
                    {
                        timeout = _assoc != null 
							? DateTime.Now.AddMilliseconds(_assoc.ReadTimeout) 
							: DateTime.Now.AddSeconds(Timeout);

                        bool success = ProcessNextPDU();
                        if (!success)
                        {
                            // Start the Abort process, not much else we can do
                            Platform.Log(LogLevel.Error,
                                "Unexpected error processing PDU.  Aborting Association from {0} to {1}",
                                _assoc.CallingAE, _assoc.CalledAE);
                            SendAssociateAbort(DicomAbortSource.ServiceProvider, DicomAbortReason.InvalidPDUParameter);
                        }
                    }
                    else if (_pduQueue.Count > 0)
                    {
                        //SendRawPDU(DequeuePdu());
						// Note, if this is ever enabled, it would make sense to reset the timeout at this point.
						// So that the timeout is really based on the last data read or written to the network, instead of 
						// from the last time data was read from the network.
                    }
                    else if (DateTime.Now > timeout)
                    {
                    	string errorMessage;
                    	switch (State)
                        {
                        	case DicomAssociationState.Sta6_AssociationEstablished:
                        		OnDimseTimeout();
								timeout = DateTime.Now.AddMilliseconds(_assoc.ReadTimeout);
                        		break;
                        	case DicomAssociationState.Sta2_TransportConnectionOpen:
                        		errorMessage = "ARTIM timeout when waiting for AAssociate Request PDU, closing connection.";
                        		Platform.Log(LogLevel.Error, errorMessage);
                        		State = DicomAssociationState.Sta13_AwaitingTransportConnectionClose;
                        		OnNetworkError(new DicomNetworkException(errorMessage), true);
                        		if (NetworkClosed != null)
                        			NetworkClosed(errorMessage);
                        		break;
                        	case DicomAssociationState.Sta5_AwaitingAAssociationACOrReject:
                        		errorMessage = "ARTIM timeout when waiting for AAssociate AC or RJ PDU, closing connection.";
                        		Platform.Log(LogLevel.Error,errorMessage );
                        		State = DicomAssociationState.Sta13_AwaitingTransportConnectionClose;
								OnNetworkError(new DicomNetworkException(errorMessage), true);
                        		if (NetworkClosed != null)
                        			NetworkClosed(errorMessage);
                        		break;
                        	case DicomAssociationState.Sta13_AwaitingTransportConnectionClose:
                        		errorMessage = string.Format(
                        				"Timeout when waiting for transport connection to close from {0} to {1}.  Dropping Connection.",
                        				_assoc.CallingAE, _assoc.CalledAE);
                        		Platform.Log(LogLevel.Error, errorMessage);
								OnNetworkError(new DicomNetworkException(errorMessage), true);
                        		if (NetworkClosed != null)
                        			NetworkClosed(errorMessage);
                        		break;
                        	default:
                        		Platform.Log(LogLevel.Error, "DIMSE timeout in unexpected state: {0}", State.ToString());
                        		OnDimseTimeout();
								timeout = _assoc != null ? DateTime.Now.AddMilliseconds(_assoc.ReadTimeout) : DateTime.Now.AddSeconds(Timeout);
                        		break;
                        }
                    }
					//else
					//{
					//    Thread.Sleep(0);
					//}
                }
                _network.Close();
                _network.Dispose();
                _network = null;
            }
            catch (Exception e)
            {
                OnNetworkError(e, true);

                if (NetworkError != null)
                    NetworkError(e);
            }
        }