Encapsulates PDU data for reading or writing
Example #1
0
        public void Write_AeWithNonAsciiCharacters_ShouldBeAsciified()
        {
            var notExpected = "GÖTEBORG";
            var request = new AAssociateRQ(new DicomAssociation("MALMÖ", notExpected));

            var writePdu = request.Write();

            RawPDU readPdu;
            using (var stream = new MemoryStream())
            {
                writePdu.WritePDU(stream);

                var length = (int)writePdu.Length;
                var buffer = new byte[length];
                stream.Seek(0, SeekOrigin.Begin);
                stream.Read(buffer, 0, length);
                readPdu = new RawPDU(buffer);
            }

            readPdu.Reset();
            readPdu.SkipBytes("Unknown", 10);
            var actual = readPdu.ReadString("Called AE", 16);

            Assert.NotEqual(notExpected, actual);
        }
Example #2
0
        /// <summary>
        /// Writes A-ABORT to PDU buffer
        /// </summary>
        /// <returns>PDU buffer</returns>
        public RawPDU Write()
        {
            RawPDU pdu = new RawPDU((byte)0x07);

            pdu.Write("Reserved", (byte)0x00);
            pdu.Write("Reserved", (byte)0x00);
            pdu.Write("Source", (byte)_s);
            pdu.Write("Reason", (byte)_r);
            return(pdu);
        }
Example #3
0
        /// <summary>
        /// Writes PDV to PDU buffer
        /// </summary>
        /// <param name="pdu">PDU buffer</param>
        public void Write(RawPDU pdu)
        {
            byte mch = (byte)((_last ? 2 : 0) + (_command ? 1 : 0));

            pdu.MarkLength32("PDV-Length");
            pdu.Write("Presentation Context ID", (byte)_pcid);
            pdu.Write("Message Control Header", (byte)mch);
            pdu.Write("PDV Value", _value);
            pdu.WriteLength32();
        }
Example #4
0
        /// <summary>
        /// Writes P-DATA-TF to PDU buffer
        /// </summary>
        /// <returns>PDU buffer</returns>
        public RawPDU Write()
        {
            RawPDU pdu = new RawPDU((byte)0x04);

            foreach (PDV pdv in _pdvs)
            {
                pdv.Write(pdu);
            }
            return(pdu);
        }
Example #5
0
        /// <summary>
        /// Writes P-DATA-TF to PDU buffer
        /// </summary>
        /// <returns>PDU buffer</returns>
        public RawPDU Write()
        {
            var pdu = new RawPDU(0x04);

            foreach (var pdv in _pdvs)
            {
                pdv.Write(pdu);
            }
            return(pdu);
        }
Example #6
0
        /// <summary>
        /// Writes A-ASSOCIATE-RJ to PDU buffer
        /// </summary>
        /// <returns>PDU buffer</returns>
        /// <remarks>When writing the rejection reason to the <see cref="RawPDU"/> object, the <see cref="DicomRejectSource"/>
        /// specification in the underlying value is masked out, to ensure that the reason code matches the codes specified
        /// in Table 9-21 of DICOM Standard PS 3.8.</remarks>
        public RawPDU Write()
        {
            var pdu = new RawPDU(0x03);

            pdu.Write("Reserved", 0x00);
            pdu.Write("Result", (byte)_rt);
            pdu.Write("Source", (byte)_so);
            pdu.Write("Reason", (byte)((byte)_rn & 0xf));
            return(pdu);
        }
Example #7
0
        /// <summary>
        /// Writes A-ASSOCIATE-RJ to PDU buffer
        /// </summary>
        /// <returns>PDU buffer</returns>
        public RawPDU Write()
        {
            RawPDU pdu = new RawPDU((byte)0x03);

            pdu.Write("Reserved", (byte)0x00);
            pdu.Write("Result", (byte)_rt);
            pdu.Write("Source", (byte)_so);
            pdu.Write("Reason", (byte)_rn);
            return(pdu);
        }
Example #8
0
        public void AssociateRJ_Read_ReasonGivenByContext(byte[] buffer, AAssociateRJ dummy, string expected)
        {
            using (var raw = new RawPDU(buffer))
            {
                var reject = new AAssociateRJ();
                reject.Read(raw);
                var actual = reject.Reason.ToString();

                Assert.Equal(expected, actual);
            }
        }
Example #9
0
        public void Save_ToNonExistingDirectory_Succeeds()
        {
            var path = @".\Test Data\PDU Test";
            var name = Path.Combine(path, "assoc.pdu");
            if (Directory.Exists(path)) Directory.Delete(path, true);

            var pdu = new RawPDU(0x01);
            pdu.Save(name);

            Assert.True(File.Exists(name));
        }
Example #10
0
        /// <summary>
        /// Reads PDV from PDU buffer
        /// </summary>
        /// <param name="raw">PDU buffer</param>
        public uint Read(RawPDU raw)
        {
            uint len = raw.ReadUInt32("PDV-Length");

            _pcid = raw.ReadByte("Presentation Context ID");
            byte mch = raw.ReadByte("Message Control Header");

            _value   = raw.ReadBytes("PDV Value", (int)len - 2);
            _command = (mch & 0x01) != 0;
            _last    = (mch & 0x02) != 0;
            return(len + 4);
        }
Example #11
0
        /// <summary>
        /// Reads P-DATA-TF from PDU buffer
        /// </summary>
        /// <param name="raw">PDU buffer</param>
        public void Read(RawPDU raw)
        {
            uint len  = raw.Length - 6;
            uint read = 0;

            while (read < len)
            {
                PDV pdv = new PDV();
                read += pdv.Read(raw);
                _pdvs.Add(pdv);
            }
        }
Example #12
0
        private RawPDU ConvertWriteToReadPdu(RawPDU writePdu)
        {
            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);
                return(new RawPDU(buffer));
            }
        }
Example #13
0
        public void Save_ToNonExistingDirectory_Succeeds()
        {
            var path = @".\Test Data\PDU Test";
            var name = Path.Combine(path, "assoc.pdu");

            if (Directory.Exists(path))
            {
                Directory.Delete(path, true);
            }

            var pdu = new RawPDU(0x01);

            pdu.Save(name);

            Assert.True(File.Exists(name));
        }
Example #14
0
        /// <summary>
        /// Write PDU.
        /// </summary>
        /// <param name="pdu">PDU to write.</param>
        public void Write(RawPDU pdu)
        {
            if (null != SubItem)
            {
                pdu.Write("Item-Type", (byte)0x56);
                pdu.Write("Reserved", (byte)0x00);

                pdu.MarkLength16("Item-Length");

                pdu.Write("SOP Class UID Length", (ushort)(SopClassUid.UID.Length));
                pdu.Write("SOP Class UID", SopClassUid.UID);

                SubItem.Write(pdu);

                pdu.WriteLength16();
            }
        }
        /// <summary>
        /// Write PDU.
        /// </summary>
        /// <param name="pdu">PDU to write.</param>
        public void Write(RawPDU pdu)
        {
            if (null != SubItem)
            {
                pdu.Write("Item-Type", (byte)0x56);
                pdu.Write("Reserved", (byte)0x00);

                pdu.MarkLength16("Item-Length");

                pdu.Write("SOP Class UID Length", (ushort)(SopClassUid.UID.Length));
                pdu.Write("SOP Class UID", SopClassUid.UID);

                SubItem.Write(pdu);

                pdu.WriteLength16();
            }
        }
Example #16
0
        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));
        }
Example #17
0
        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);
            }
        }
Example #18
0
 private void WritePDU(bool last)
 {
     if (_pdu.PDVs.Count == 0 || ((CurrentPduSize() + 6) < _max && GetBufferLength() > 0))
     {
         CreatePDV();
     }
     if (_pdu.PDVs.Count > 0)
     {
         if (last)
         {
             _pdu.PDVs[_pdu.PDVs.Count - 1].IsLastFragment = true;
         }
         RawPDU raw = _pdu.Write();
         raw.WritePDU(_network);
         if (OnPduSent != null)
         {
             OnPduSent();
         }
         _pdu = new PDataTF();
     }
 }
Example #19
0
        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));
        }
Example #20
0
        /// <summary>
        /// Factory method for creating <see cref="DicomExtendedNegotiation"/> instances.
        /// </summary>
        /// <param name="raw">Raw PDU.</param>
        /// <param name="length">Length.</param>
        /// <returns>A new <see cref="DicomExtendedNegotiation"/> instance.</returns>
        public static DicomExtendedNegotiation Create(RawPDU raw, ushort length)
        {
            var uidLen = raw.ReadUInt16("SOP Class UID Length");
            var uidStr = raw.ReadString("SOP Class UID", uidLen);

            var uid = DicomUID.Parse(uidStr);
            IExtendedNegotiationSubItem subItem = null;
            var subItemSize = 0;

            var remaining = length - uidLen - 2;

            if (subItemCreators.ContainsKey(uid))
            {
                subItem = subItemCreators[uid](raw, remaining, out subItemSize);
            }

            remaining -= subItemSize;
            if (remaining > 0)
            {
                raw.SkipBytes("Unread bytes", remaining);
            }

            return(new DicomExtendedNegotiation(uid, subItem));
        }
Example #21
0
		/// <summary>
		/// Writes A-ABORT to PDU buffer
		/// </summary>
		/// <returns>PDU buffer</returns>
		public RawPDU Write() {
			RawPDU pdu = new RawPDU((byte)0x07);
			pdu.Write("Reserved", (byte)0x00);
			pdu.Write("Reserved", (byte)0x00);
			pdu.Write("Source", (byte)_s);
			pdu.Write("Reason", (byte)_r);
			return pdu;
		}
Example #22
0
		/// <summary>
		/// Writes A-RELEASE-RP to PDU buffer
		/// </summary>
		/// <returns>PDU buffer</returns>
		public RawPDU Write() {
			RawPDU pdu = new RawPDU((byte)0x06);
			pdu.Write("Reserved", (uint)0x00000000);
			return pdu;
		}
Example #23
0
		/// <summary>
		/// Writes A-ASSOCIATE-RJ to PDU buffer
		/// </summary>
		/// <returns>PDU buffer</returns>
		public RawPDU Write() {
			RawPDU pdu = new RawPDU((byte)0x03);
			pdu.Write("Reserved", (byte)0x00);
			pdu.Write("Result", (byte)_rt);
			pdu.Write("Source", (byte)_so);
			pdu.Write("Reason", (byte)_rn);
			return pdu;
		}
Example #24
0
		/// <summary>
		/// Writes A-ASSOCIATE-AC to PDU buffer
		/// </summary>
		/// <returns>PDU buffer</returns>
		public RawPDU Write() {
			RawPDU pdu = new RawPDU((byte)0x02);

			pdu.Write("Version", (ushort)0x0001);
			pdu.Write("Reserved", 0x00, 2);
			pdu.Write("Called AE", _assoc.CalledAE, 16, ' ');
			pdu.Write("Calling AE", _assoc.CallingAE, 16, ' ');
			pdu.Write("Reserved", 0x00, 32);

			// Application Context
			pdu.Write("Item-Type", (byte)0x10);
			pdu.Write("Reserved", (byte)0x00);
			pdu.MarkLength16("Item-Length");
			pdu.Write("Application Context Name", DicomUID.DICOMApplicationContextName.UID);
			pdu.WriteLength16();

			foreach (var pc in _assoc.PresentationContexts) {
				// Presentation Context
				pdu.Write("Item-Type", (byte)0x21);
				pdu.Write("Reserved", (byte)0x00);
				pdu.MarkLength16("Item-Length");
				pdu.Write("Presentation Context ID", (byte)pc.ID);
				pdu.Write("Reserved", (byte)0x00);
				pdu.Write("Result", (byte)pc.Result);
				pdu.Write("Reserved", (byte)0x00);

				// Transfer Syntax
				pdu.Write("Item-Type", (byte)0x40);
				pdu.Write("Reserved", (byte)0x00);
				pdu.MarkLength16("Item-Length");
				pdu.Write("Transfer Syntax UID", pc.AcceptedTransferSyntax.UID.UID);
				pdu.WriteLength16();

				pdu.WriteLength16();
			}

			// User Data Fields
			pdu.Write("Item-Type", (byte)0x50);
			pdu.Write("Reserved", (byte)0x00);
			pdu.MarkLength16("Item-Length");

			// Maximum PDU
			pdu.Write("Item-Type", (byte)0x51);
			pdu.Write("Reserved", (byte)0x00);
			pdu.Write("Item-Length", (ushort)0x0004);
			pdu.Write("Max PDU Length", (uint)_assoc.MaximumPDULength);

			// Implementation Class UID
			pdu.Write("Item-Type", (byte)0x52);
			pdu.Write("Reserved", (byte)0x00);
			pdu.MarkLength16("Item-Length");
			pdu.Write("Implementation Class UID", DicomImplementation.ClassUID.UID);
			pdu.WriteLength16();

			// Asynchronous Operations Negotiation
			if (_assoc.MaxAsyncOpsInvoked != 1 || _assoc.MaxAsyncOpsPerformed != 1) {
				pdu.Write("Item-Type", (byte)0x53);
				pdu.Write("Reserved", (byte)0x00);
				pdu.Write("Item-Length", (ushort)0x0004);
				pdu.Write("Asynchronous Operations Invoked", (ushort)_assoc.MaxAsyncOpsInvoked);
				pdu.Write("Asynchronous Operations Performed", (ushort)_assoc.MaxAsyncOpsPerformed);
			}

			// Implementation Version
			pdu.Write("Item-Type", (byte)0x55);
			pdu.Write("Reserved", (byte)0x00);
			pdu.MarkLength16("Item-Length");
			pdu.Write("Implementation Version", DicomImplementation.Version);
			pdu.WriteLength16();

			pdu.WriteLength16();

			return pdu;
		}
Example #25
0
File: PDU.cs Project: hide1980/mdcm
        /// <summary>
        /// Reads A-ASSOCIATE-AC from PDU buffer
        /// </summary>
        /// <param name="raw">PDU buffer</param>
        public void Read(RawPDU raw)
        {
            uint l = raw.Length;
            ushort c = 0;

            raw.ReadUInt16("Version");
            raw.SkipBytes("Reserved", 2);
            raw.SkipBytes("Reserved", 16);
            raw.SkipBytes("Reserved", 16);
            raw.SkipBytes("Reserved", 32);
            l -= 68;

            while (l > 0) {
                byte type = raw.ReadByte("Item-Type");
                l -= 1;

                if (type == 0x10) {
                    // Application Context
                    raw.SkipBytes("Reserved", 1);
                    c = raw.ReadUInt16("Item-Length");
                    raw.SkipBytes("Value", (int)c);
                    l -= 3 + (uint)c;
                } else

                if (type == 0x21) {
                    // Presentation Context
                    raw.ReadByte("Reserved");
                    ushort pl = raw.ReadUInt16("Presentation Context Item-Length");
                    byte id = raw.ReadByte("Presentation Context ID");
                    raw.ReadByte("Reserved");
                    byte res = raw.ReadByte("Presentation Context Result/Reason");
                    raw.ReadByte("Reserved");
                    l -= (uint)pl + 3;
                    pl -= 4;

                    // Presentation Context Transfer Syntax
                    raw.ReadByte("Presentation Context Item-Type (0x40)");
                    raw.ReadByte("Reserved");
                    ushort tl = raw.ReadUInt16("Presentation Context Item-Length");
                    string tx = raw.ReadString("Presentation Context Syntax UID", tl);
                    pl -= (ushort)(tl + 4);

                    _assoc.SetPresentationContextResult(id, (DcmPresContextResult)res);
                    _assoc.SetAcceptedTransferSyntax(id, DicomTransferSyntax.Lookup(tx));
                } else

                if (type == 0x50) {
                    // User Information
                    raw.ReadByte("Reserved");
                    ushort il = raw.ReadUInt16("User Information Item-Length");
                    l -= (uint)(il + 3);
                    while (il > 0) {
                        byte ut = raw.ReadByte("User Item-Type");
                        raw.ReadByte("Reserved");
                        ushort ul = raw.ReadUInt16("User Item-Length");
                        il -= (ushort)(ul + 4);
                        if (ut == 0x51) {
                            _assoc.MaximumPduLength = raw.ReadUInt32("Max PDU Length");
                        } else if (ut == 0x52) {
                            _assoc.ImplementationClass = DicomUID.Lookup(raw.ReadString("Implementation Class UID", ul));
                        } else if (ut == 0x53) {
                            _assoc.AsyncOpsInvoked = raw.ReadUInt16("Asynchronous Operations Invoked");
                            _assoc.AsyncOpsPerformed = raw.ReadUInt16("Asynchronous Operations Performed");
                        } else if (ut == 0x55) {
                            _assoc.ImplementationVersion = raw.ReadString("Implementation Version", ul);
                        } else {
                            raw.SkipBytes("User Item Value", (int)ul);
                        }
                    }
                }

                else {
                    raw.SkipBytes("Reserved", 1);
                    ushort il = raw.ReadUInt16("User Item-Length");
                    raw.SkipBytes("Unknown User Item", il);
                    l -= (uint)(il + 3);
                }
            }
        }
Example #26
0
        /// <summary>
        /// Reads A-ASSOCIATE-RQ from PDU buffer
        /// </summary>
        /// <param name="raw">PDU buffer</param>
        public void Read(RawPDU raw)
        {
            uint l = raw.Length - 6;

            raw.ReadUInt16("Version");
            raw.SkipBytes("Reserved", 2);
            _assoc.CalledAE = raw.ReadString("Called AE", 16);
            _assoc.CallingAE = raw.ReadString("Calling AE", 16);
            raw.SkipBytes("Reserved", 32);
            l -= 2 + 2 + 16 + 16 + 32;

            while (l > 0)
            {
                byte type = raw.ReadByte("Item-Type");
                raw.SkipBytes("Reserved", 1);
                ushort il = raw.ReadUInt16("Item-Length");

                l -= 4 + (uint)il;

                if (type == 0x10)
                {
                    // Application Context
                    raw.SkipBytes("Application Context", il);
                }
                else if (type == 0x20)
                {
                    // Presentation Context
                    byte id = raw.ReadByte("Presentation Context ID");
                    raw.SkipBytes("Reserved", 3);
                    il -= 4;

                    while (il > 0)
                    {
                        byte pt = raw.ReadByte("Presentation Context Item-Type");
                        raw.SkipBytes("Reserved", 1);
                        ushort pl = raw.ReadUInt16("Presentation Context Item-Length");
                        string sx = raw.ReadString("Presentation Context Syntax UID", pl);
                        if (pt == 0x30)
                        {
                            var pc = new DicomPresentationContext(id, DicomUID.Parse(sx));
                            _assoc.PresentationContexts.Add(pc);
                        }
                        else if (pt == 0x40)
                        {
                            var pc = _assoc.PresentationContexts[id];
                            pc.AddTransferSyntax(DicomTransferSyntax.Parse(sx));
                        }
                        il -= (ushort)(4 + pl);
                    }
                }
                else if (type == 0x50)
                {
                    // User Information
                    while (il > 0)
                    {
                        byte ut = raw.ReadByte("User Information Item-Type");
                        raw.SkipBytes("Reserved", 1);
                        ushort ul = raw.ReadUInt16("User Information Item-Length");
                        il -= (ushort)(4 + ul);
                        if (ut == 0x51)
                        {
                            _assoc.MaximumPDULength = raw.ReadUInt32("Max PDU Length");
                        }
                        else if (ut == 0x52)
                        {
                            _assoc.RemoteImplementationClassUID =
                                new DicomUID(
                                    raw.ReadString("Implementation Class UID", ul),
                                    "Implementation Class UID",
                                    DicomUidType.Unknown);
                        }
                        else if (ut == 0x55)
                        {
                            _assoc.RemoteImplementationVersion = raw.ReadString("Implementation Version", ul);
                        }
                        else if (ut == 0x53)
                        {
                            _assoc.MaxAsyncOpsInvoked = raw.ReadUInt16("Asynchronous Operations Invoked");
                            _assoc.MaxAsyncOpsPerformed = raw.ReadUInt16("Asynchronous Operations Performed");
                        }
                        else if (ut == 0x54)
                        {
                            var asul = raw.ReadUInt16("Abstract Syntax Item-Length");
                            var syntax = raw.ReadString("Abstract Syntax UID", asul);
                            var userRole = raw.ReadByte("SCU role");
                            var providerRole = raw.ReadByte("SCP role");
                            var pc =
                                _assoc.PresentationContexts.FirstOrDefault(
                                    context => context.AbstractSyntax.UID.Equals(syntax));
                            if (pc != null)
                            {
                                pc.UserRole = userRole == 0x01;
                                pc.ProviderRole = providerRole == 0x01;
                            }
                        }
                        else if (ut == 0x56)
                        {
                            _assoc.ExtendedNegotiations.Add(DicomExtendedNegotiation.Create(raw, ul));
                        }
                        else
                        {
                            raw.SkipBytes("Unhandled User Item", ul);
                        }
                    }
                }
            }
        }
Example #27
0
File: PDU.cs Project: sczx888/mDCM
        /// <summary>
        /// 扩展,向RawPDU中写入UserIdentity身份信息
        /// </summary>
        /// <param name="userIdentity"></param>
        /// <returns></returns>
        public RawPDU WriteAddingUserIdentity(UserIdentity userIdentity)
        {
            RawPDU pdu = new RawPDU((byte)0x01);

            pdu.Write("Version", (ushort)0x0001);
            pdu.Write("Reserved", 0x00, 2);
            pdu.Write("Called AE", _assoc.CalledAE, 16, ' ');
            pdu.Write("Calling AE", _assoc.CallingAE, 16, ' ');
            pdu.Write("Reserved", 0x00, 32);

            // Application Context
            pdu.Write("Item-Type", (byte)0x10);
            pdu.Write("Reserved", (byte)0x00);
            pdu.MarkLength16("Item-Length");
            pdu.Write("Application Context Name", DicomUID.DICOMApplicationContextName.UID);
            pdu.WriteLength16();

            foreach (DcmPresContext pc in _assoc.GetPresentationContexts())
            {
                // Presentation Context
                pdu.Write("Item-Type", (byte)0x20);
                pdu.Write("Reserved", (byte)0x00);
                pdu.MarkLength16("Item-Length");
                pdu.Write("Presentation Context ID", (byte)pc.ID);
                pdu.Write("Reserved", (byte)0x00, 3);

                // Abstract Syntax
                pdu.Write("Item-Type", (byte)0x30);
                pdu.Write("Reserved", (byte)0x00);
                pdu.MarkLength16("Item-Length");
                pdu.Write("Abstract Syntax UID", pc.AbstractSyntax.UID);
                pdu.WriteLength16();

                // Transfer Syntax
                foreach (DicomTransferSyntax ts in pc.GetTransfers())
                {
                    pdu.Write("Item-Type", (byte)0x40);
                    pdu.Write("Reserved", (byte)0x00);
                    pdu.MarkLength16("Item-Length");
                    pdu.Write("Transfer Syntax UID", ts.UID.UID);
                    pdu.WriteLength16();
                }

                pdu.WriteLength16();
            }

            // User Data Fields
            pdu.Write("Item-Type", (byte)0x50);
            pdu.Write("Reserved", (byte)0x00);
            pdu.MarkLength16("Item-Length");

            // Maximum PDU
            pdu.Write("Item-Type", (byte)0x51);
            pdu.Write("Reserved", (byte)0x00);
            pdu.Write("Item-Length", (ushort)0x0004);
            pdu.Write("Max PDU Length", (uint)_assoc.MaximumPduLength);

            // Implementation Class UID
            pdu.Write("Item-Type", (byte)0x52);
            pdu.Write("Reserved", (byte)0x00);
            pdu.MarkLength16("Item-Length");
            pdu.Write("Implementation Class UID", Implementation.ClassUID.UID);
            pdu.WriteLength16();

            // Asynchronous Operations Negotiation
            if (_assoc.NegotiateAsyncOps)
            {
                pdu.Write("Item-Type", (byte)0x53);
                pdu.Write("Reserved", (byte)0x00);
                pdu.Write("Item-Length", (ushort)0x0004);
                pdu.Write("Asynchronous Operations Invoked", (ushort)_assoc.AsyncOpsInvoked);
                pdu.Write("Asynchronous Operations Performed", (ushort)_assoc.AsyncOpsPerformed);
            }

            // Implementation Version
            pdu.Write("Item-Type", (byte)0x55);
            pdu.Write("Reserved", (byte)0x00);
            pdu.MarkLength16("Item-Length");
            pdu.Write("Implementation Version", Implementation.Version);
            pdu.WriteLength16();

            //User Indentity
            //http://medical.nema.org/medical/dicom/current/output/html/part07.html#sect_D.3.3.7
            pdu.Write("Item-Type", (byte)0x58);
            pdu.Write("Reserved", (byte)0x00);
            pdu.MarkLength16("Item-Length");
            pdu.Write("User Identity Type", (byte)userIdentity.UserIdentityType);
            pdu.Write("Positive Response Requested", (userIdentity.bPositiveResponseRequested?(byte)0x01:(byte)0x00));
            pdu.Write("Primary Field Length", (ushort)userIdentity.UserName.Length);
            pdu.Write("Primary Field", userIdentity.UserName);
            pdu.Write("Secondary Field Length", (ushort)userIdentity.PassCode.Length);
            pdu.Write("Secondary Field", userIdentity.PassCode);
            pdu.WriteLength16();
            //zssure:end.


            pdu.WriteLength16();

            return(pdu);
        }
Example #28
0
        /// <summary>
        /// Writes A-ASSOCIATE-RQ to PDU buffer
        /// </summary>
        /// <returns>PDU buffer</returns>
        public RawPDU Write()
        {
            RawPDU pdu = new RawPDU((byte)0x01);

            pdu.Write("Version", (ushort)0x0001);
            pdu.Write("Reserved", 0x00, 2);
            pdu.Write("Called AE", _assoc.CalledAE, 16, ' ');
            pdu.Write("Calling AE", _assoc.CallingAE, 16, ' ');
            pdu.Write("Reserved", 0x00, 32);

            // Application Context
            pdu.Write("Item-Type", (byte)0x10);
            pdu.Write("Reserved", (byte)0x00);
            pdu.MarkLength16("Item-Length");
            pdu.Write("Application Context Name", DicomUID.DICOMApplicationContextName.UID);
            pdu.WriteLength16();

            foreach (var pc in _assoc.PresentationContexts)
            {
                // Presentation Context
                pdu.Write("Item-Type", (byte)0x20);
                pdu.Write("Reserved", (byte)0x00);
                pdu.MarkLength16("Item-Length");
                pdu.Write("Presentation Context ID", (byte)pc.ID);
                pdu.Write("Reserved", (byte)0x00, 3);

                // Abstract Syntax
                pdu.Write("Item-Type", (byte)0x30);
                pdu.Write("Reserved", (byte)0x00);
                pdu.MarkLength16("Item-Length");
                pdu.Write("Abstract Syntax UID", pc.AbstractSyntax.UID);
                pdu.WriteLength16();

                // Transfer Syntax
                foreach (DicomTransferSyntax ts in pc.GetTransferSyntaxes())
                {
                    pdu.Write("Item-Type", (byte)0x40);
                    pdu.Write("Reserved", (byte)0x00);
                    pdu.MarkLength16("Item-Length");
                    pdu.Write("Transfer Syntax UID", ts.UID.UID);
                    pdu.WriteLength16();
                }

                pdu.WriteLength16();
            }

            // User Data Fields
            pdu.Write("Item-Type", (byte)0x50);
            pdu.Write("Reserved", (byte)0x00);
            pdu.MarkLength16("Item-Length");

            // Maximum PDU
            pdu.Write("Item-Type", (byte)0x51);
            pdu.Write("Reserved", (byte)0x00);
            pdu.Write("Item-Length", (ushort)0x0004);
            pdu.Write("Max PDU Length", (uint)_assoc.MaximumPDULength);

            // Implementation Class UID
            pdu.Write("Item-Type", (byte)0x52);
            pdu.Write("Reserved", (byte)0x00);
            pdu.MarkLength16("Item-Length");
            pdu.Write("Implementation Class UID", DicomImplementation.ClassUID.UID);
            pdu.WriteLength16();

            // Asynchronous Operations Negotiation
            if (_assoc.MaxAsyncOpsInvoked != 1 || _assoc.MaxAsyncOpsPerformed != 1)
            {
                pdu.Write("Item-Type", (byte)0x53);
                pdu.Write("Reserved", (byte)0x00);
                pdu.Write("Item-Length", (ushort)0x0004);
                pdu.Write("Asynchronous Operations Invoked", (ushort)_assoc.MaxAsyncOpsInvoked);
                pdu.Write("Asynchronous Operations Performed", (ushort)_assoc.MaxAsyncOpsPerformed);
            }

            foreach (var pc in _assoc.PresentationContexts)
            {
                if (pc.UserRole.HasValue || pc.ProviderRole.HasValue)
                {
                    pdu.Write("Item-Type", (byte)0x54);
                    pdu.Write("Reserved", (byte)0x00);
                    pdu.MarkLength16("Item-Length");
                    pdu.MarkLength16("UID-Length");
                    pdu.Write("Abstract Syntax UID", pc.AbstractSyntax.UID);
                    pdu.WriteLength16();
                    pdu.Write("SCU Role", pc.UserRole.GetValueOrDefault() ? (byte)1 : (byte)0);
                    pdu.Write("SCP Role", pc.ProviderRole.GetValueOrDefault() ? (byte)1 : (byte)0);
                    pdu.WriteLength16();
                }
            }

            // Implementation Version
            pdu.Write("Item-Type", (byte)0x55);
            pdu.Write("Reserved", (byte)0x00);
            pdu.MarkLength16("Item-Length");
            pdu.Write("Implementation Version", DicomImplementation.Version);
            pdu.WriteLength16();

            foreach (DicomExtendedNegotiation exNeg in _assoc.ExtendedNegotiations)
            {
                exNeg.Write(pdu);
            }

            pdu.WriteLength16();

            return pdu;
        }
Example #29
0
		/// <summary>
		/// Reads P-DATA-TF from PDU buffer
		/// </summary>
		/// <param name="raw">PDU buffer</param>
		public void Read(RawPDU raw) {
			uint len = raw.Length - 6;
			uint read = 0;
			while (read < len) {
				PDV pdv = new PDV();
				read += pdv.Read(raw);
				_pdvs.Add(pdv);
			}
		}
Example #30
0
		/// <summary>
		/// Writes P-DATA-TF to PDU buffer
		/// </summary>
		/// <returns>PDU buffer</returns>
		public RawPDU Write() {
			RawPDU pdu = new RawPDU((byte)0x04);
			foreach (PDV pdv in _pdvs) {
				pdv.Write(pdu);
			}
			return pdu;
		}
Example #31
0
		/// <summary>
		/// Reads PDV from PDU buffer
		/// </summary>
		/// <param name="raw">PDU buffer</param>
		public uint Read(RawPDU raw) {
			uint len = raw.ReadUInt32("PDV-Length");
			_pcid = raw.ReadByte("Presentation Context ID");
			byte mch = raw.ReadByte("Message Control Header");
			_value = raw.ReadBytes("PDV Value", (int)len - 2);
			_command = (mch & 0x01) != 0;
			_last = (mch & 0x02) != 0;
			return len + 4;
		}
Example #32
0
		/// <summary>
		/// Writes PDV to PDU buffer
		/// </summary>
		/// <param name="pdu">PDU buffer</param>
		public void Write(RawPDU pdu) {
			byte mch = (byte)((_last ? 2 : 0) + (_command ? 1 : 0));
			pdu.MarkLength32("PDV-Length");
			pdu.Write("Presentation Context ID", (byte)_pcid);
			pdu.Write("Message Control Header", (byte)mch);
			pdu.Write("PDV Value", _value);
			pdu.WriteLength32();
		}
Example #33
0
        /// <summary>
        /// Writes A-ASSOCIATE-RQ to PDU buffer
        /// </summary>
        /// <returns>PDU buffer</returns>
        public RawPDU Write()
        {
            RawPDU pdu = new RawPDU((byte)0x01);

            pdu.Write("Version", (ushort)0x0001);
            pdu.Write("Reserved", 0x00, 2);
            pdu.Write("Called AE", _assoc.CalledAE, 16, ' ');
            pdu.Write("Calling AE", _assoc.CallingAE, 16, ' ');
            pdu.Write("Reserved", 0x00, 32);

            // Application Context
            pdu.Write("Item-Type", (byte)0x10);
            pdu.Write("Reserved", (byte)0x00);
            pdu.MarkLength16("Item-Length");
            pdu.Write("Application Context Name", DicomUID.DICOMApplicationContextName.UID);
            pdu.WriteLength16();

            foreach (DcmPresContext pc in _assoc.GetPresentationContexts())
            {
                // Presentation Context
                pdu.Write("Item-Type", (byte)0x20);
                pdu.Write("Reserved", (byte)0x00);
                pdu.MarkLength16("Item-Length");
                pdu.Write("Presentation Context ID", (byte)pc.ID);
                pdu.Write("Reserved", (byte)0x00, 3);

                // Abstract Syntax
                pdu.Write("Item-Type", (byte)0x30);
                pdu.Write("Reserved", (byte)0x00);
                pdu.MarkLength16("Item-Length");
                pdu.Write("Abstract Syntax UID", pc.AbstractSyntax.UID);
                pdu.WriteLength16();

                // Transfer Syntax
                foreach (DicomTransferSyntax ts in pc.GetTransfers())
                {
                    pdu.Write("Item-Type", (byte)0x40);
                    pdu.Write("Reserved", (byte)0x00);
                    pdu.MarkLength16("Item-Length");
                    pdu.Write("Transfer Syntax UID", ts.UID.UID);
                    pdu.WriteLength16();
                }

                pdu.WriteLength16();
            }

            // User Data Fields
            pdu.Write("Item-Type", (byte)0x50);
            pdu.Write("Reserved", (byte)0x00);
            pdu.MarkLength16("Item-Length");

            // Maximum PDU
            pdu.Write("Item-Type", (byte)0x51);
            pdu.Write("Reserved", (byte)0x00);
            pdu.Write("Item-Length", (ushort)0x0004);
            pdu.Write("Max PDU Length", (uint)_assoc.MaximumPduLength);

            // Implementation Class UID
            pdu.Write("Item-Type", (byte)0x52);
            pdu.Write("Reserved", (byte)0x00);
            pdu.MarkLength16("Item-Length");
            pdu.Write("Implementation Class UID", Implementation.ClassUID.UID);
            pdu.WriteLength16();

            // Asynchronous Operations Negotiation
            if (_assoc.NegotiateAsyncOps)
            {
                pdu.Write("Item-Type", (byte)0x53);
                pdu.Write("Reserved", (byte)0x00);
                pdu.Write("Item-Length", (ushort)0x0004);
                pdu.Write("Asynchronous Operations Invoked", (ushort)_assoc.AsyncOpsInvoked);
                pdu.Write("Asynchronous Operations Performed", (ushort)_assoc.AsyncOpsPerformed);
            }

            // Implementation Version
            pdu.Write("Item-Type", (byte)0x55);
            pdu.Write("Reserved", (byte)0x00);
            pdu.MarkLength16("Item-Length");
            pdu.Write("Implementation Version", Implementation.Version);
            pdu.WriteLength16();

            pdu.WriteLength16();

            return(pdu);
        }
Example #34
0
		/// <summary>
		/// Reads A-ASSOCIATE-RQ from PDU buffer
		/// </summary>
		/// <param name="raw">PDU buffer</param>
		public void Read(RawPDU raw) {
			uint l = raw.Length - 6;

			raw.ReadUInt16("Version");
			raw.SkipBytes("Reserved", 2);
			_assoc.CalledAE = raw.ReadString("Called AE", 16);
			_assoc.CallingAE = raw.ReadString("Calling AE", 16);
			raw.SkipBytes("Reserved", 32);
			l -= 2 + 2 + 16 + 16 + 32;

			while (l > 0) {
				byte type = raw.ReadByte("Item-Type");
				raw.SkipBytes("Reserved", 1);
				ushort il = raw.ReadUInt16("Item-Length");

				l -= 4 + (uint)il;

				if (type == 0x10) {
					// Application Context
					raw.SkipBytes("Application Context", il);
				} else

					if (type == 0x20) {
						// Presentation Context
						byte id = raw.ReadByte("Presentation Context ID");
						raw.SkipBytes("Reserved", 3);
						il -= 4;

						while (il > 0) {
							byte pt = raw.ReadByte("Presentation Context Item-Type");
							raw.SkipBytes("Reserved", 1);
							ushort pl = raw.ReadUInt16("Presentation Context Item-Length");
							string sx = raw.ReadString("Presentation Context Syntax UID", pl);
							if (pt == 0x30) {
								var pc = new DicomPresentationContext(id, DicomUID.Parse(sx));
								_assoc.PresentationContexts.Add(pc);
							} else if (pt == 0x40) {
								var pc = _assoc.PresentationContexts[id];
								pc.AddTransferSyntax(DicomTransferSyntax.Parse(sx));
							}
							il -= (ushort)(4 + pl);
						}
					} else

						if (type == 0x50) {
							// User Information
							while (il > 0) {
								byte ut = raw.ReadByte("User Information Item-Type");
								raw.SkipBytes("Reserved", 1);
								ushort ul = raw.ReadUInt16("User Information Item-Length");
								il -= (ushort)(4 + ul);
								if (ut == 0x51) {
									_assoc.MaximumPDULength = raw.ReadUInt32("Max PDU Length");
								} else if (ut == 0x52) {
									_assoc.RemoteImplemetationClassUID = new DicomUID(raw.ReadString("Implementation Class UID", ul), "Implementation Class UID", DicomUidType.Unknown);
								} else if (ut == 0x55) {
									_assoc.RemoteImplementationVersion = raw.ReadString("Implementation Version", ul);
								} else if (ut == 0x53) {
									_assoc.MaxAsyncOpsInvoked = raw.ReadUInt16("Asynchronous Operations Invoked");
									_assoc.MaxAsyncOpsPerformed = raw.ReadUInt16("Asynchronous Operations Performed");
								} else if (ut == 0x54) {
									raw.SkipBytes("SCU/SCP Role Selection", ul);
									/*
									ushort rsul = raw.ReadUInt16();
									if ((rsul + 4) != ul) {
										throw new DicomNetworkException("SCU/SCP role selection length (" + ul + " bytes) does not match uid length (" + rsul + " + 4 bytes)");
									}
									raw.ReadChars(rsul);	// Abstract Syntax
									raw.ReadByte();		// SCU role
									raw.ReadByte();		// SCP role
									*/
								} else {
									//Debug.Log.Error("Unhandled user item: 0x{0:x2} ({1} + 4 bytes)", ut, ul);
									raw.SkipBytes("Unhandled User Item", ul);
								}
							}
						}
			}
		}
Example #35
0
        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);
            }
        }
Example #36
0
		/// <summary>
		/// Reads A-ASSOCIATE-AC from PDU buffer
		/// </summary>
		/// <param name="raw">PDU buffer</param>
		public void Read(RawPDU raw) {
			// reset async ops in case remote end does not negotiate
			_assoc.MaxAsyncOpsInvoked = 1;
			_assoc.MaxAsyncOpsPerformed = 1;

			uint l = raw.Length - 6;
			ushort c = 0;

			raw.ReadUInt16("Version");
			raw.SkipBytes("Reserved", 2);
			raw.SkipBytes("Reserved", 16);
			raw.SkipBytes("Reserved", 16);
			raw.SkipBytes("Reserved", 32);
			l -= 68;

			while (l > 0) {
				byte type = raw.ReadByte("Item-Type");
				l -= 1;

				if (type == 0x10) {
					// Application Context
					raw.SkipBytes("Reserved", 1);
					c = raw.ReadUInt16("Item-Length");
					raw.SkipBytes("Value", (int)c);
					l -= 3 + (uint)c;
				} else

					if (type == 0x21) {
						// Presentation Context
						raw.ReadByte("Reserved");
						ushort pl = raw.ReadUInt16("Presentation Context Item-Length");
						byte id = raw.ReadByte("Presentation Context ID");
						raw.ReadByte("Reserved");
						byte res = raw.ReadByte("Presentation Context Result/Reason");
						raw.ReadByte("Reserved");
						l -= (uint)pl + 3;
						pl -= 4;

						// Presentation Context Transfer Syntax
						raw.ReadByte("Presentation Context Item-Type (0x40)");
						raw.ReadByte("Reserved");
						ushort tl = raw.ReadUInt16("Presentation Context Item-Length");
						string tx = raw.ReadString("Presentation Context Syntax UID", tl);
						pl -= (ushort)(tl + 4);

						_assoc.PresentationContexts[id].SetResult((DicomPresentationContextResult)res, DicomTransferSyntax.Parse(tx));
					} else if (type == 0x50) {
						// User Information
						raw.ReadByte("Reserved");
						ushort il = raw.ReadUInt16("User Information Item-Length");
						l -= (uint)(il + 3);
						while (il > 0) {
							byte ut = raw.ReadByte("User Item-Type");
							raw.ReadByte("Reserved");
							ushort ul = raw.ReadUInt16("User Item-Length");
							il -= (ushort)(ul + 4);
							if (ut == 0x51) {
								_assoc.MaximumPDULength = raw.ReadUInt32("Max PDU Length");
							} else if (ut == 0x52) {
								_assoc.RemoteImplemetationClassUID = DicomUID.Parse(raw.ReadString("Implementation Class UID", ul));
							} else if (ut == 0x53) {
								_assoc.MaxAsyncOpsInvoked = raw.ReadUInt16("Asynchronous Operations Invoked");
								_assoc.MaxAsyncOpsPerformed = raw.ReadUInt16("Asynchronous Operations Performed");
							} else if (ut == 0x55) {
								_assoc.RemoteImplementationVersion = raw.ReadString("Implementation Version", ul);
							} else {
								raw.SkipBytes("User Item Value", (int)ul);
							}
						}
					} else {
						raw.SkipBytes("Reserved", 1);
						ushort il = raw.ReadUInt16("User Item-Length");
						raw.SkipBytes("Unknown User Item", il);
						l -= (uint)(il + 3);
					}
			}
		}
Example #37
0
        /// <summary>
        /// Reads A-ASSOCIATE-RQ from PDU buffer
        /// </summary>
        /// <param name="raw">PDU buffer</param>
        public void Read(RawPDU raw)
        {
            uint l = raw.Length - 6;

            raw.ReadUInt16("Version");
            raw.SkipBytes("Reserved", 2);
            _assoc.CalledAE  = raw.ReadString("Called AE", 16);
            _assoc.CallingAE = raw.ReadString("Calling AE", 16);
            raw.SkipBytes("Reserved", 32);
            l -= 2 + 2 + 16 + 16 + 32;

            while (l > 0)
            {
                byte type = raw.ReadByte("Item-Type");
                raw.SkipBytes("Reserved", 1);
                ushort il = raw.ReadUInt16("Item-Length");

                l -= 4 + (uint)il;

                if (type == 0x10)
                {
                    // Application Context
                    raw.SkipBytes("Application Context", il);
                }
                else

                if (type == 0x20)
                {
                    // Presentation Context
                    byte id = raw.ReadByte("Presentation Context ID");
                    raw.SkipBytes("Reserved", 3);
                    il -= 4;

                    while (il > 0)
                    {
                        byte pt = raw.ReadByte("Presentation Context Item-Type");
                        raw.SkipBytes("Reserved", 1);
                        ushort pl = raw.ReadUInt16("Presentation Context Item-Length");
                        string sx = raw.ReadString("Presentation Context Syntax UID", pl);
                        if (pt == 0x30)
                        {
                            var pc = new DicomPresentationContext(id, DicomUID.Parse(sx));
                            _assoc.PresentationContexts.Add(pc);
                        }
                        else if (pt == 0x40)
                        {
                            var pc = _assoc.PresentationContexts[id];
                            pc.AddTransferSyntax(DicomTransferSyntax.Parse(sx));
                        }
                        il -= (ushort)(4 + pl);
                    }
                }
                else

                if (type == 0x50)
                {
                    // User Information
                    while (il > 0)
                    {
                        byte ut = raw.ReadByte("User Information Item-Type");
                        raw.SkipBytes("Reserved", 1);
                        ushort ul = raw.ReadUInt16("User Information Item-Length");
                        il -= (ushort)(4 + ul);
                        if (ut == 0x51)
                        {
                            _assoc.MaximumPDULength = raw.ReadUInt32("Max PDU Length");
                        }
                        else if (ut == 0x52)
                        {
                            _assoc.RemoteImplemetationClassUID = new DicomUID(raw.ReadString("Implementation Class UID", ul), "Implementation Class UID", DicomUidType.Unknown);
                        }
                        else if (ut == 0x55)
                        {
                            _assoc.RemoteImplementationVersion = raw.ReadString("Implementation Version", ul);
                        }
                        else if (ut == 0x53)
                        {
                            _assoc.MaxAsyncOpsInvoked   = raw.ReadUInt16("Asynchronous Operations Invoked");
                            _assoc.MaxAsyncOpsPerformed = raw.ReadUInt16("Asynchronous Operations Performed");
                        }
                        else if (ut == 0x54)
                        {
                            raw.SkipBytes("SCU/SCP Role Selection", ul);

                            /*
                             * ushort rsul = raw.ReadUInt16();
                             * if ((rsul + 4) != ul) {
                             *      throw new DicomNetworkException("SCU/SCP role selection length (" + ul + " bytes) does not match uid length (" + rsul + " + 4 bytes)");
                             * }
                             * raw.ReadChars(rsul);	// Abstract Syntax
                             * raw.ReadByte();		// SCU role
                             * raw.ReadByte();		// SCP role
                             */
                        }
                        else
                        {
                            //Debug.Log.Error("Unhandled user item: 0x{0:x2} ({1} + 4 bytes)", ut, ul);
                            raw.SkipBytes("Unhandled User Item", ul);
                        }
                    }
                }
            }
        }
Example #38
0
		/// <summary>
		/// Reads A-ASSOCIATE-RJ from PDU buffer
		/// </summary>
		/// <param name="raw">PDU buffer</param>
		public void Read(RawPDU raw) {
			raw.ReadByte("Reserved");
			_rt = (DicomRejectResult)raw.ReadByte("Result");
			_so = (DicomRejectSource)raw.ReadByte("Source");
			_rn = (DicomRejectReason)raw.ReadByte("Reason");
		}
Example #39
0
        /// <summary>
        /// Reads A-ASSOCIATE-AC from PDU buffer
        /// </summary>
        /// <param name="raw">PDU buffer</param>
        public void Read(RawPDU raw)
        {
            // reset async ops in case remote end does not negotiate
            _assoc.MaxAsyncOpsInvoked   = 1;
            _assoc.MaxAsyncOpsPerformed = 1;

            uint   l = raw.Length - 6;
            ushort c = 0;

            raw.ReadUInt16("Version");
            raw.SkipBytes("Reserved", 2);
            raw.SkipBytes("Reserved", 16);
            raw.SkipBytes("Reserved", 16);
            raw.SkipBytes("Reserved", 32);
            l -= 68;

            while (l > 0)
            {
                byte type = raw.ReadByte("Item-Type");
                l -= 1;

                if (type == 0x10)
                {
                    // Application Context
                    raw.SkipBytes("Reserved", 1);
                    c = raw.ReadUInt16("Item-Length");
                    raw.SkipBytes("Value", (int)c);
                    l -= 3 + (uint)c;
                }
                else

                if (type == 0x21)
                {
                    // Presentation Context
                    raw.ReadByte("Reserved");
                    ushort pl = raw.ReadUInt16("Presentation Context Item-Length");
                    byte   id = raw.ReadByte("Presentation Context ID");
                    raw.ReadByte("Reserved");
                    byte res = raw.ReadByte("Presentation Context Result/Reason");
                    raw.ReadByte("Reserved");
                    l  -= (uint)pl + 3;
                    pl -= 4;

                    // Presentation Context Transfer Syntax
                    raw.ReadByte("Presentation Context Item-Type (0x40)");
                    raw.ReadByte("Reserved");
                    ushort tl = raw.ReadUInt16("Presentation Context Item-Length");
                    string tx = raw.ReadString("Presentation Context Syntax UID", tl);
                    pl -= (ushort)(tl + 4);

                    _assoc.PresentationContexts[id].SetResult((DicomPresentationContextResult)res, DicomTransferSyntax.Parse(tx));
                }
                else if (type == 0x50)
                {
                    // User Information
                    raw.ReadByte("Reserved");
                    ushort il = raw.ReadUInt16("User Information Item-Length");
                    l -= (uint)(il + 3);
                    while (il > 0)
                    {
                        byte ut = raw.ReadByte("User Item-Type");
                        raw.ReadByte("Reserved");
                        ushort ul = raw.ReadUInt16("User Item-Length");
                        il -= (ushort)(ul + 4);
                        if (ut == 0x51)
                        {
                            _assoc.MaximumPDULength = raw.ReadUInt32("Max PDU Length");
                        }
                        else if (ut == 0x52)
                        {
                            _assoc.RemoteImplemetationClassUID = DicomUID.Parse(raw.ReadString("Implementation Class UID", ul));
                        }
                        else if (ut == 0x53)
                        {
                            _assoc.MaxAsyncOpsInvoked   = raw.ReadUInt16("Asynchronous Operations Invoked");
                            _assoc.MaxAsyncOpsPerformed = raw.ReadUInt16("Asynchronous Operations Performed");
                        }
                        else if (ut == 0x55)
                        {
                            _assoc.RemoteImplementationVersion = raw.ReadString("Implementation Version", ul);
                        }
                        else
                        {
                            raw.SkipBytes("User Item Value", (int)ul);
                        }
                    }
                }
                else
                {
                    raw.SkipBytes("Reserved", 1);
                    ushort il = raw.ReadUInt16("User Item-Length");
                    raw.SkipBytes("Unknown User Item", il);
                    l -= (uint)(il + 3);
                }
            }
        }
Example #40
0
		/// <summary>
		/// Reads A-RELEASE-RP from PDU buffer
		/// </summary>
		/// <param name="raw">PDU buffer</param>
		public void Read(RawPDU raw) {
			raw.ReadUInt32("Reserved");
		}
Example #41
0
        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;
            }
        }
Example #42
0
		/// <summary>
		/// Reads A-ABORT from PDU buffer
		/// </summary>
		/// <param name="raw">PDU buffer</param>
		public void Read(RawPDU raw) {
			raw.ReadByte("Reserved");
			raw.ReadByte("Reserved");
			_s = (DicomAbortSource)raw.ReadByte("Source");
			_r = (DicomAbortReason)raw.ReadByte("Reason");
		}
Example #43
0
File: PDU.cs Project: hide1980/mdcm
        /// <summary>
        /// Writes A-ASSOCIATE-RQ to PDU buffer
        /// </summary>
        /// <returns>PDU buffer</returns>
        public RawPDU Write()
        {
            RawPDU pdu = new RawPDU((byte)0x01);

            pdu.Write("Version", (ushort)0x0001);
            pdu.Write("Reserved", 0x00, 2);
            pdu.Write("Called AE", _assoc.CalledAE, 16, ' ');
            pdu.Write("Calling AE", _assoc.CallingAE, 16, ' ');
            pdu.Write("Reserved", 0x00, 32);

            // Application Context
            pdu.Write("Item-Type", (byte)0x10);
            pdu.Write("Reserved", (byte)0x00);
            pdu.MarkLength16("Item-Length");
            pdu.Write("Application Context Name", DicomUID.DICOMApplicationContextName.UID);
            pdu.WriteLength16();

            foreach (DcmPresContext pc in _assoc.GetPresentationContexts()) {
                // Presentation Context
                pdu.Write("Item-Type", (byte)0x20);
                pdu.Write("Reserved", (byte)0x00);
                pdu.MarkLength16("Item-Length");
                pdu.Write("Presentation Context ID", (byte)pc.ID);
                pdu.Write("Reserved", (byte)0x00, 3);

                // Abstract Syntax
                pdu.Write("Item-Type", (byte)0x30);
                pdu.Write("Reserved", (byte)0x00);
                pdu.MarkLength16("Item-Length");
                pdu.Write("Abstract Syntax UID", pc.AbstractSyntax.UID);
                pdu.WriteLength16();

                // Transfer Syntax
                foreach (DicomTransferSyntax ts in pc.GetTransfers()) {
                    pdu.Write("Item-Type", (byte)0x40);
                    pdu.Write("Reserved", (byte)0x00);
                    pdu.MarkLength16("Item-Length");
                    pdu.Write("Transfer Syntax UID", ts.UID.UID);
                    pdu.WriteLength16();
                }

                pdu.WriteLength16();
            }

            // User Data Fields
            pdu.Write("Item-Type", (byte)0x50);
            pdu.Write("Reserved", (byte)0x00);
            pdu.MarkLength16("Item-Length");

            // Maximum PDU
            pdu.Write("Item-Type", (byte)0x51);
            pdu.Write("Reserved", (byte)0x00);
            pdu.Write("Item-Length", (ushort)0x0004);
            pdu.Write("Max PDU Length", (uint)_assoc.MaximumPduLength);

            // Implementation Class UID
            pdu.Write("Item-Type", (byte)0x52);
            pdu.Write("Reserved", (byte)0x00);
            pdu.MarkLength16("Item-Length");
            pdu.Write("Implementation Class UID", Implementation.ClassUID.UID);
            pdu.WriteLength16();

            // Asynchronous Operations Negotiation
            if (_assoc.NegotiateAsyncOps) {
                pdu.Write("Item-Type", (byte)0x53);
                pdu.Write("Reserved", (byte)0x00);
                pdu.Write("Item-Length", (ushort)0x0004);
                pdu.Write("Asynchronous Operations Invoked", (ushort)_assoc.AsyncOpsInvoked);
                pdu.Write("Asynchronous Operations Performed", (ushort)_assoc.AsyncOpsPerformed);
            }

            // Implementation Version
            pdu.Write("Item-Type", (byte)0x55);
            pdu.Write("Reserved", (byte)0x00);
            pdu.MarkLength16("Item-Length");
            pdu.Write("Implementation Version", Implementation.Version);
            pdu.WriteLength16();

            pdu.WriteLength16();

            return pdu;
        }
Example #44
0
        /// <summary>
        /// Reads A-ASSOCIATE-AC from PDU buffer
        /// </summary>
        /// <param name="raw">PDU buffer</param>
        public void Read(RawPDU raw)
        {
            uint   l = raw.Length;
            ushort c = 0;

            raw.ReadUInt16("Version");
            raw.SkipBytes("Reserved", 2);
            raw.SkipBytes("Reserved", 16);
            raw.SkipBytes("Reserved", 16);
            raw.SkipBytes("Reserved", 32);
            l -= 68;

            while (l > 0)
            {
                byte type = raw.ReadByte("Item-Type");
                l -= 1;

                if (type == 0x10)
                {
                    // Application Context
                    raw.SkipBytes("Reserved", 1);
                    c = raw.ReadUInt16("Item-Length");
                    raw.SkipBytes("Value", (int)c);
                    l -= 3 + (uint)c;
                }
                else

                if (type == 0x21)
                {
                    // Presentation Context
                    raw.ReadByte("Reserved");
                    ushort pl = raw.ReadUInt16("Presentation Context Item-Length");
                    byte   id = raw.ReadByte("Presentation Context ID");
                    raw.ReadByte("Reserved");
                    byte res = raw.ReadByte("Presentation Context Result/Reason");
                    raw.ReadByte("Reserved");
                    l  -= (uint)pl + 3;
                    pl -= 4;

                    // Presentation Context Transfer Syntax
                    raw.ReadByte("Presentation Context Item-Type (0x40)");
                    raw.ReadByte("Reserved");
                    ushort tl = raw.ReadUInt16("Presentation Context Item-Length");
                    string tx = raw.ReadString("Presentation Context Syntax UID", tl);
                    pl -= (ushort)(tl + 4);

                    _assoc.SetPresentationContextResult(id, (DcmPresContextResult)res);
                    _assoc.SetAcceptedTransferSyntax(id, DicomTransferSyntax.Lookup(tx));
                }
                else

                if (type == 0x50)
                {
                    // User Information
                    raw.ReadByte("Reserved");
                    ushort il = raw.ReadUInt16("User Information Item-Length");
                    l -= (uint)(il + 3);
                    while (il > 0)
                    {
                        byte ut = raw.ReadByte("User Item-Type");
                        raw.ReadByte("Reserved");
                        ushort ul = raw.ReadUInt16("User Item-Length");
                        il -= (ushort)(ul + 4);
                        if (ut == 0x51)
                        {
                            _assoc.MaximumPduLength = raw.ReadUInt32("Max PDU Length");
                        }
                        else if (ut == 0x52)
                        {
                            _assoc.ImplementationClass = DicomUID.Lookup(raw.ReadString("Implementation Class UID", ul));
                        }
                        else if (ut == 0x53)
                        {
                            _assoc.AsyncOpsInvoked   = raw.ReadUInt16("Asynchronous Operations Invoked");
                            _assoc.AsyncOpsPerformed = raw.ReadUInt16("Asynchronous Operations Performed");
                        }
                        else if (ut == 0x55)
                        {
                            _assoc.ImplementationVersion = raw.ReadString("Implementation Version", ul);
                        }
                        else
                        {
                            raw.SkipBytes("User Item Value", (int)ul);
                        }
                    }
                }

                else
                {
                    raw.SkipBytes("Reserved", 1);
                    ushort il = raw.ReadUInt16("User Item-Length");
                    raw.SkipBytes("Unknown User Item", il);
                    l -= (uint)(il + 3);
                }
            }
        }
Example #45
0
        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);
            }
        }
Example #46
0
        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);
            }
        }
Example #47
0
        /// <summary>
        /// Reads A-ASSOCIATE-RQ from PDU buffer
        /// </summary>
        /// <param name="raw">PDU buffer</param>
        public void Read(RawPDU raw)
        {
            var l = raw.Length - 6;

            raw.ReadUInt16("Version");
            raw.SkipBytes("Reserved", 2);
            _assoc.CalledAE  = raw.ReadString("Called AE", 16);
            _assoc.CallingAE = raw.ReadString("Calling AE", 16);
            raw.SkipBytes("Reserved", 32);
            l -= 2 + 2 + 16 + 16 + 32;

            while (l > 0)
            {
                var type = raw.ReadByte("Item-Type");
                raw.SkipBytes("Reserved", 1);
                var il = raw.ReadUInt16("Item-Length");

                l -= 4 + (uint)il;

                if (type == 0x10)
                {
                    // Application Context
                    raw.SkipBytes("Application Context", il);
                }
                else if (type == 0x20)
                {
                    // Presentation Context
                    var id = raw.ReadByte("Presentation Context ID");
                    raw.SkipBytes("Reserved", 3);
                    il -= 4;

                    while (il > 0)
                    {
                        var pt = raw.ReadByte("Presentation Context Item-Type");
                        raw.SkipBytes("Reserved", 1);
                        var pl = raw.ReadUInt16("Presentation Context Item-Length");
                        var sx = raw.ReadString("Presentation Context Syntax UID", pl);
                        if (pt == 0x30)
                        {
                            var pc = new DicomPresentationContext(id, DicomUID.Parse(sx));
                            _assoc.PresentationContexts.Add(pc);
                        }
                        else if (pt == 0x40)
                        {
                            var pc = _assoc.PresentationContexts[id];
                            pc.AddTransferSyntax(DicomTransferSyntax.Parse(sx));
                        }
                        il -= (ushort)(4 + pl);
                    }
                }
                else if (type == 0x50)
                {
                    // User Information
                    while (il > 0)
                    {
                        var ut = raw.ReadByte("User Information Item-Type");
                        raw.SkipBytes("Reserved", 1);
                        var ul = raw.ReadUInt16("User Information Item-Length");
                        il -= (ushort)(4 + ul);
                        if (ut == 0x51)
                        {
                            _assoc.MaximumPDULength = raw.ReadUInt32("Max PDU Length");
                        }
                        else if (ut == 0x52)
                        {
                            _assoc.RemoteImplementationClassUID =
                                new DicomUID(
                                    raw.ReadString("Implementation Class UID", ul),
                                    "Implementation Class UID",
                                    DicomUidType.Unknown);
                        }
                        else if (ut == 0x55)
                        {
                            _assoc.RemoteImplementationVersion = raw.ReadString("Implementation Version", ul);
                        }
                        else if (ut == 0x53)
                        {
                            _assoc.MaxAsyncOpsInvoked   = raw.ReadUInt16("Asynchronous Operations Invoked");
                            _assoc.MaxAsyncOpsPerformed = raw.ReadUInt16("Asynchronous Operations Performed");
                        }
                        else if (ut == 0x54)
                        {
                            var asul         = raw.ReadUInt16("Abstract Syntax Item-Length");
                            var syntax       = raw.ReadString("Abstract Syntax UID", asul);
                            var userRole     = raw.ReadByte("SCU role");
                            var providerRole = raw.ReadByte("SCP role");
                            var pc           =
                                _assoc.PresentationContexts.FirstOrDefault(
                                    context => context.AbstractSyntax.UID.Equals(syntax));
                            if (pc != null)
                            {
                                pc.UserRole     = userRole == 0x01;
                                pc.ProviderRole = providerRole == 0x01;
                            }
                        }
                        else if (ut == 0x56)
                        {
                            _assoc.ExtendedNegotiations.Add(DicomExtendedNegotiation.Create(raw, ul));
                        }
                        else
                        {
#if !NET35
                            if (HandlePDUBytes != null)
                            {
                                HandlePDUBytes(raw.ReadBytes("Unhandled User Item", ul));
                            }
                            else
                            {
                                raw.SkipBytes("Unhandled User Item", ul);
                            }
#else
                            raw.SkipBytes("Unhandled User Item", ul);
#endif
                        }
                    }
                }
            }
        }
Example #48
0
        /// <summary>
        /// Writes A-ASSOCIATE-AC to PDU buffer
        /// </summary>
        /// <returns>PDU buffer</returns>
        public RawPDU Write()
        {
            var pdu = new RawPDU(0x02);

            pdu.Write("Version", (ushort)0x0001);
            pdu.Write("Reserved", 0x00, 2);
            pdu.Write("Called AE", _assoc.CalledAE, 16, ' ');
            pdu.Write("Calling AE", _assoc.CallingAE, 16, ' ');
            pdu.Write("Reserved", 0x00, 32);

            // Application Context
            pdu.Write("Item-Type", 0x10);
            pdu.Write("Reserved", 0x00);
            pdu.MarkLength16("Item-Length");
            pdu.Write("Application Context Name", DicomUID.DICOMApplicationContextName.UID);
            pdu.WriteLength16();

            foreach (var pc in _assoc.PresentationContexts)
            {
                // Presentation Context
                pdu.Write("Item-Type", 0x21);
                pdu.Write("Reserved", 0x00);
                pdu.MarkLength16("Item-Length");
                pdu.Write("Presentation Context ID", pc.ID);
                pdu.Write("Reserved", 0x00);
                pdu.Write("Result", (byte)pc.Result);
                pdu.Write("Reserved", 0x00);

                // Transfer Syntax (set to Implicit VR Little Endian if no accepted transfer syntax is defined)
                pdu.Write("Item-Type", 0x40);
                pdu.Write("Reserved", 0x00);
                pdu.MarkLength16("Item-Length");
                pdu.Write("Transfer Syntax UID",
                          pc.AcceptedTransferSyntax?.UID.UID ?? DicomUID.ImplicitVRLittleEndian.UID);
                pdu.WriteLength16();

                pdu.WriteLength16();
            }

            // User Data Fields
            pdu.Write("Item-Type", 0x50);
            pdu.Write("Reserved", 0x00);
            pdu.MarkLength16("Item-Length");

            // Maximum PDU
            pdu.Write("Item-Type", 0x51);
            pdu.Write("Reserved", 0x00);
            pdu.Write("Item-Length", (ushort)0x0004);
            pdu.Write("Max PDU Length", _assoc.MaximumPDULength);

            // Implementation Class UID
            pdu.Write("Item-Type", 0x52);
            pdu.Write("Reserved", 0x00);
            pdu.MarkLength16("Item-Length");
            pdu.Write("Implementation Class UID", DicomImplementation.ClassUID.UID);
            pdu.WriteLength16();

            // Asynchronous Operations Negotiation
            if (_assoc.MaxAsyncOpsInvoked != 1 || _assoc.MaxAsyncOpsPerformed != 1)
            {
                pdu.Write("Item-Type", 0x53);
                pdu.Write("Reserved", 0x00);
                pdu.Write("Item-Length", (ushort)0x0004);
                pdu.Write("Asynchronous Operations Invoked", (ushort)_assoc.MaxAsyncOpsInvoked);
                pdu.Write("Asynchronous Operations Performed", (ushort)_assoc.MaxAsyncOpsPerformed);
            }

            foreach (var pc in _assoc.PresentationContexts)
            {
                if (pc.UserRole.HasValue || pc.ProviderRole.HasValue)
                {
                    pdu.Write("Item-Type", 0x54);
                    pdu.Write("Reserved", 0x00);
                    pdu.MarkLength16("Item-Length");
                    pdu.MarkLength16("UID-Length");
                    pdu.Write("Abstract Syntax UID", pc.AbstractSyntax.UID);
                    pdu.WriteLength16();
                    pdu.Write("SCU Role", pc.UserRole.GetValueOrDefault() ? (byte)1 : (byte)0);
                    pdu.Write("SCP Role", pc.ProviderRole.GetValueOrDefault() ? (byte)1 : (byte)0);
                    pdu.WriteLength16();
                }
            }

            // Implementation Version
            pdu.Write("Item-Type", 0x55);
            pdu.Write("Reserved", 0x00);
            pdu.MarkLength16("Item-Length");
            pdu.Write("Implementation Version", DicomImplementation.Version);
            pdu.WriteLength16();

            foreach (var exNeg in _assoc.ExtendedNegotiations)
            {
                exNeg.Write(pdu);
            }

            pdu.WriteLength16();

            return(pdu);
        }
Example #49
0
        /// <summary>
        /// Reads A-ASSOCIATE-AC from PDU buffer
        /// </summary>
        /// <param name="raw">PDU buffer</param>
        public void Read(RawPDU raw)
        {
            // reset async ops in case remote end does not negotiate
            _assoc.MaxAsyncOpsInvoked   = 1;
            _assoc.MaxAsyncOpsPerformed = 1;

            var l = raw.Length - 6;

            raw.ReadUInt16("Version");
            raw.SkipBytes("Reserved", 2);
            raw.SkipBytes("Reserved", 16);
            raw.SkipBytes("Reserved", 16);
            raw.SkipBytes("Reserved", 32);
            l -= 68;

            while (l > 0)
            {
                var type = raw.ReadByte("Item-Type");
                l -= 1;

                if (type == 0x10)
                {
                    // Application Context
                    raw.SkipBytes("Reserved", 1);
                    var c = raw.ReadUInt16("Item-Length");
                    raw.SkipBytes("Value", c);
                    l -= 3 + (uint)c;
                }
                else if (type == 0x21)
                {
                    // Presentation Context
                    raw.ReadByte("Reserved");
                    var pl = raw.ReadUInt16("Presentation Context Item-Length");
                    var id = raw.ReadByte("Presentation Context ID");
                    raw.ReadByte("Reserved");
                    var res = raw.ReadByte("Presentation Context Result/Reason");
                    raw.ReadByte("Reserved");
                    l  -= (uint)pl + 3;
                    pl -= 4;

                    if ((DicomPresentationContextResult)res == DicomPresentationContextResult.Accept)
                    {
                        // Presentation Context Transfer Syntax
                        raw.ReadByte("Presentation Context Item-Type (0x40)");
                        raw.ReadByte("Reserved");
                        var tl = raw.ReadUInt16("Presentation Context Item-Length");
                        var tx = raw.ReadString("Presentation Context Syntax UID", tl);
                        pl -= (ushort)(tl + 4);

                        _assoc.PresentationContexts[id].SetResult(
                            (DicomPresentationContextResult)res,
                            DicomTransferSyntax.Parse(tx));
                    }
                    else
                    {
                        raw.SkipBytes("Rejected Presentation Context", pl);
                        _assoc.PresentationContexts[id].SetResult((DicomPresentationContextResult)res);
                    }
                }
                else if (type == 0x50)
                {
                    // User Information
                    raw.ReadByte("Reserved");
                    var il = raw.ReadUInt16("User Information Item-Length");
                    l -= (uint)(il + 3);
                    while (il > 0)
                    {
                        var ut = raw.ReadByte("User Item-Type");
                        raw.ReadByte("Reserved");
                        var ul = raw.ReadUInt16("User Item-Length");
                        il -= (ushort)(ul + 4);
                        if (ut == 0x51)
                        {
                            _assoc.MaximumPDULength = raw.ReadUInt32("Max PDU Length");
                        }
                        else if (ut == 0x52)
                        {
                            _assoc.RemoteImplementationClassUID =
                                DicomUID.Parse(raw.ReadString("Implementation Class UID", ul));
                        }
                        else if (ut == 0x53)
                        {
                            _assoc.MaxAsyncOpsInvoked   = raw.ReadUInt16("Asynchronous Operations Invoked");
                            _assoc.MaxAsyncOpsPerformed = raw.ReadUInt16("Asynchronous Operations Performed");
                        }
                        else if (ut == 0x54)
                        {
                            var asul         = raw.ReadUInt16("Abstract Syntax Item-Length");
                            var syntax       = raw.ReadString("Abstract Syntax UID", asul);
                            var userRole     = raw.ReadByte("SCU role");
                            var providerRole = raw.ReadByte("SCP role");
                            var pc           =
                                _assoc.PresentationContexts.FirstOrDefault(
                                    context => context.AbstractSyntax.UID.Equals(syntax));
                            if (pc != null)
                            {
                                pc.UserRole     = userRole == 0x01;
                                pc.ProviderRole = providerRole == 0x01;
                            }
                        }
                        else if (ut == 0x55)
                        {
                            _assoc.RemoteImplementationVersion = raw.ReadString("Implementation Version", ul);
                        }
                        else if (ut == 0x56)
                        {
                            _assoc.ExtendedNegotiations.Add(DicomExtendedNegotiation.Create(raw, ul));
                        }
                        else
                        {
                            raw.SkipBytes("User Item Value", ul);
                        }
                    }
                }
                else
                {
                    raw.SkipBytes("Reserved", 1);
                    var il = raw.ReadUInt16("User Item-Length");
                    raw.SkipBytes("Unknown User Item", il);
                    l -= (uint)(il + 3);
                }
            }
        }
Example #50
0
        /// <summary>
        /// Writes A-ASSOCIATE-AC to PDU buffer
        /// </summary>
        /// <returns>PDU buffer</returns>
        public RawPDU Write()
        {
            RawPDU pdu = new RawPDU((byte)0x02);

            pdu.Write("Version", (ushort)0x0001);
            pdu.Write("Reserved", 0x00, 2);
            pdu.Write("Called AE", _assoc.CalledAE, 16, ' ');
            pdu.Write("Calling AE", _assoc.CallingAE, 16, ' ');
            pdu.Write("Reserved", 0x00, 32);

            // Application Context
            pdu.Write("Item-Type", (byte)0x10);
            pdu.Write("Reserved", (byte)0x00);
            pdu.MarkLength16("Item-Length");
            pdu.Write("Application Context Name", DicomUID.DICOMApplicationContextName.UID);
            pdu.WriteLength16();

            foreach (var pc in _assoc.PresentationContexts)
            {
                // Presentation Context
                pdu.Write("Item-Type", (byte)0x21);
                pdu.Write("Reserved", (byte)0x00);
                pdu.MarkLength16("Item-Length");
                pdu.Write("Presentation Context ID", (byte)pc.ID);
                pdu.Write("Reserved", (byte)0x00);
                pdu.Write("Result", (byte)pc.Result);
                pdu.Write("Reserved", (byte)0x00);

                // Transfer Syntax
                pdu.Write("Item-Type", (byte)0x40);
                pdu.Write("Reserved", (byte)0x00);
                pdu.MarkLength16("Item-Length");
                pdu.Write("Transfer Syntax UID", pc.AcceptedTransferSyntax.UID.UID);
                pdu.WriteLength16();

                pdu.WriteLength16();
            }

            // User Data Fields
            pdu.Write("Item-Type", (byte)0x50);
            pdu.Write("Reserved", (byte)0x00);
            pdu.MarkLength16("Item-Length");

            // Maximum PDU
            pdu.Write("Item-Type", (byte)0x51);
            pdu.Write("Reserved", (byte)0x00);
            pdu.Write("Item-Length", (ushort)0x0004);
            pdu.Write("Max PDU Length", (uint)_assoc.MaximumPDULength);

            // Implementation Class UID
            pdu.Write("Item-Type", (byte)0x52);
            pdu.Write("Reserved", (byte)0x00);
            pdu.MarkLength16("Item-Length");
            pdu.Write("Implementation Class UID", DicomImplementation.ClassUID.UID);
            pdu.WriteLength16();

            // Asynchronous Operations Negotiation
            if (_assoc.MaxAsyncOpsInvoked != 1 || _assoc.MaxAsyncOpsPerformed != 1)
            {
                pdu.Write("Item-Type", (byte)0x53);
                pdu.Write("Reserved", (byte)0x00);
                pdu.Write("Item-Length", (ushort)0x0004);
                pdu.Write("Asynchronous Operations Invoked", (ushort)_assoc.MaxAsyncOpsInvoked);
                pdu.Write("Asynchronous Operations Performed", (ushort)_assoc.MaxAsyncOpsPerformed);
            }

            // Implementation Version
            pdu.Write("Item-Type", (byte)0x55);
            pdu.Write("Reserved", (byte)0x00);
            pdu.MarkLength16("Item-Length");
            pdu.Write("Implementation Version", DicomImplementation.Version);
            pdu.WriteLength16();

            pdu.WriteLength16();

            return(pdu);
        }
Example #51
0
		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);
			}
		}
Example #52
0
 /// <summary>
 /// Reads A-RELEASE-RP from PDU buffer
 /// </summary>
 /// <param name="raw">PDU buffer</param>
 public void Read(RawPDU raw)
 {
     raw.ReadUInt32("Reserved");
 }
Example #53
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;
            }
        }
Example #54
0
 private void SendRawPDU(RawPDU pdu)
 {
     try {
         lock (_socket) {
             _disableTimeout = true;
             pdu.WritePDU(_network);
             _disableTimeout = false;
         }
     }
     catch (Exception e) {
     #if DEBUG
         Log.Error("{0} -> Error sending PDU [type: 0x{1:x2}]: {2}", LogID, pdu.Type, e.ToString());
     #else
         Log.Error("{0} -> Error sending PDU [type: 0x{1:x2}]: {2}", LogID, pdu.Type, e.Message);
     #endif
         OnNetworkError(e);
     }
 }
        /// <summary>
        /// Factory method for creating <see cref="DicomExtendedNegotiation"/> instances.
        /// </summary>
        /// <param name="raw">Raw PDU.</param>
        /// <param name="length">Length.</param>
        /// <returns>A new <see cref="DicomExtendedNegotiation"/> instance.</returns>
        public static DicomExtendedNegotiation Create(RawPDU raw, ushort length)
        {
            var uidLen = raw.ReadUInt16("SOP Class UID Length");
            var uidStr = raw.ReadString("SOP Class UID", uidLen);

            var uid = DicomUID.Parse(uidStr);
            IExtendedNegotiationSubItem subItem = null;
            var subItemSize = 0;

            var remaining = length - uidLen - 2;
            if (subItemCreators.ContainsKey(uid))
            {
                subItem = subItemCreators[uid](raw, remaining, out subItemSize);
            }

            remaining -= subItemSize;
            if (remaining > 0)
            {
                raw.SkipBytes("Unread bytes", remaining);
            }

            return new DicomExtendedNegotiation(uid, subItem);
        }