/// <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); } } }
/// <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 } } } } }