[StructLayout(LayoutKind.Sequential)] public struct MSG { public IntPtr hwnd; public uint message; public IntPtr wParam; public IntPtr lParam; public uint time; public System.Drawing.Point p; } public enum WaitReturn { Complete, Timeout, } class Utils { [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] static extern bool PeekMessage(out MSG lpMsg, IntPtr hWnd, uint wMsgFilterMin, uint wMsgFilterMax, uint wRemoveMsg); [DllImport("user32.dll")] static extern bool TranslateMessage([In] ref MSG lpMsg); [DllImport("user32.dll")] static extern IntPtr DispatchMessage([In] ref MSG lpmsg); const uint PM_REMOVE = 1; public static WaitReturn WaitForComplete(double mill, WaitHandle wh) { TimeSpan goal = new TimeSpan(DateTime.Now.AddMilliseconds(mill).Ticks); do { MSG msg = new MSG(); if (PeekMessage(out msg, IntPtr.Zero, 0, 0, PM_REMOVE)) { TranslateMessage(ref msg); DispatchMessage(ref msg); } if (wh.WaitOne(new TimeSpan(0, 0, 0), false)) { return WaitReturn.Complete; } if (goal.CompareTo(new TimeSpan(DateTime.Now.Ticks)) < 0) { return WaitReturn.Timeout; } } while (true); } } class Client : DicomNet { DicomExceptionCode _LastError = DicomExceptionCode.Success; AutoResetEvent waitEvent = new AutoResetEvent(false); public Client() : base(null, DicomNetSecurityeMode.None) { } public DicomExceptionCode LastError { get { return _LastError; } } public bool Wait() { WaitReturn ret; _LastError = DicomExceptionCode.Success; ret = Utils.WaitForComplete((5 * 60) * 1000, waitEvent); return (ret == WaitReturn.Complete); } protected override void OnConnect(DicomExceptionCode error) { _LastError = error; waitEvent.Set(); } protected override void OnReceiveAssociateAccept(DicomAssociate association) { waitEvent.Set(); } protected override void OnReceiveData(byte presentationID, DicomDataSet cs, DicomDataSet ds) { DicomElement element; Debug.Assert(cs != null, "Command set should not be null"); Debug.Assert(ds != null, "Dataset should not be null"); element = ds.FindFirstElement(null, DicomTagType.PatientID, true); Debug.Assert(ds != null, "Element (PatientID) should not be null"); Debug.Assert(ds.GetStringValue(element, 0) == "ID", "PatientID should be ID"); waitEvent.Set(); } } class ServerConnection : DicomNet { public bool TestData = false; public ServerConnection() : base(null, DicomNetSecurityeMode.None) { } protected override void OnReceiveAssociateRequest(DicomAssociate association) { DicomAssociate retAssociation = new DicomAssociate(false); Debug.Assert(association.Called == "ServerTest", "Called AETitle should be ServerTest"); Debug.Assert(association.Calling == "ClientTest", "Calling AETitle should be ClientTest"); Debug.Assert(association.ImplementClass == "1.2.840.114257.1", "Implementation class should be 1.2.840.114257.1"); Debug.Assert(association.ImplementationVersionName == "1", "Implementation version should be 1"); Debug.Assert(association.MaxLength == 0x100000, "Max length should be 0x100000"); Debug.Assert(association.GetAbstract(1) == DicomUidType.VerificationClass, "Presentation index 1 should be " + DicomUidType.VerificationClass); Debug.Assert(association.GetTransfer(1, 0) == DicomUidType.ImplicitVRLittleEndian, "Abstract Syntax (1,0) should be " + DicomUidType.ImplicitVRLittleEndian); // // Build our Association Accept // retAssociation.Called = association.Called; retAssociation.Calling = association.Calling; retAssociation.ImplementClass = association.ImplementClass; retAssociation.ImplementationVersionName = association.ImplementationVersionName; for (int x = 0; x < association.PresentationContextCount; x++) { byte id = association.GetPresentationContextID(x); string abSyntax = association.GetAbstract(id); string trSyntax = DicomUidType.ImplicitVRLittleEndian; retAssociation.AddPresentationContext(id, 0, abSyntax); if (association.GetTransferCount(id) > 0) { trSyntax = association.GetTransfer(id, 0); } retAssociation.AddTransfer(id, trSyntax); } SendAssociateAccept(retAssociation); } protected override void OnReceiveData(byte presentationID, DicomDataSet cs, DicomDataSet ds) { DicomDataSet csResponse = new DicomDataSet(); DicomElement element; short[] v; if (!TestData) return; Debug.Assert(cs != null, "Command set should not be null"); Debug.Assert(ds != null, "Dataset should not be null"); // // Check command // element = cs.FindFirstElement(null, DicomTagType.MessageID, true); Debug.Assert(element != null, "Element (MessageID) should not be null"); v = cs.GetShortValue(element, 0, 1); Debug.Assert(v[0] == 1, "Command Field should be 1"); element = cs.FindFirstElement(null, DicomTagType.Priority, true); Debug.Assert(element != null, "Element (Priority) should not be null"); v = cs.GetShortValue(element, 0, 1); Debug.Assert(v[0] == (short)DicomCommandPriorityType.Medium, "Priority should be 0"); // // Check Dataset // element = ds.FindFirstElement(null, DicomTagType.PatientID, true); Debug.Assert(element != null, "Element (PatientID) should not be null"); Debug.Assert(ds.GetStringValue(element, 0) == "ID", "PatientID should be ID"); cs.InitializeCommandSet(DicomCommandType.CFind, false); SendData(presentationID, csResponse, ds); } } class Server : DicomNet { ServerConnection client; public Server() : base(null, DicomNetSecurityeMode.None) { } public bool TestData { get { if (client == null) return false; return client.TestData; } set { if (client != null) { client.TestData = value; } } } protected override void OnAccept(DicomExceptionCode error) { client = new ServerConnection(); Accept(client); } } public void SendDataSample() { DicomEngine.Startup(); DicomNet.Startup(); using (Server server = new Server()) { using (Client client = new Client()) { // // Connect to server // server.Listen("127.0.0.1", 104, 1); // start server client.Connect(null, 1000, "127.0.0.1", 104); // connect to server // Over here we can access the host (client or SCU) address by calling client.HostAddress // and its port by calling client.HostPort. We can also access the peer (server or SCP) // address by calling client.PeerAddress and its port by calling client.PeerPort if (!client.Wait()) // wait for connection to finish { Debug.Fail("Connection timed out"); } Debug.Assert(client.LastError == DicomExceptionCode.Success, "Connection failed"); Debug.Assert(client.IsConnected(), "Client not connected"); // // Send associate request // DicomAssociate associate = new DicomAssociate(true); long[] attributes = new long[4]; associate.Called = "ServerTest"; associate.Calling = "ClientTest"; associate.ImplementClass = "1.2.840.114257.1"; associate.ImplementationVersionName = "1"; associate.MaxLength = 0x100000; associate.AddPresentationContext(1, 0, DicomUidType.VerificationClass); associate.AddTransfer(1, DicomUidType.ImplicitVRLittleEndian); associate.AddPresentationContext(3, 0, DicomUidType.PatientRootQueryFind); associate.AddTransfer(3, DicomUidType.ImplicitVRLittleEndian); client.SendAssociateRequest(associate); if (!client.Wait()) // wait for connection to finish { Debug.Fail("SendAssociateRequest timed out"); } byte pid = client.Association.FindAbstract(DicomUidType.PatientRootQueryFind); DicomDataSet ds = new DicomDataSet(); DicomDataSet cs = new DicomDataSet(); DicomElement element; cs.InitializeCommandSet(DicomCommandType.Undefined, true); element = cs.FindFirstElement(null, DicomTagType.Priority, true); if (element == null) { element = cs.InsertElement(null, false, DicomTagType.Priority, DicomVRType.UN, false, 0); } cs.SetConvertValue(element, DicomCommandPriorityType.Medium.ToString(), 1); element = cs.FindFirstElement(null, DicomTagType.MessageID, true); if (element == null) { element = cs.InsertElement(null, false, DicomTagType.MessageID, DicomVRType.UN, false, 0); } cs.SetConvertValue(element, "1", 1); ds.Initialize(DicomClassType.PatientRootQueryPatient, DicomDataSetInitializeType.ImplicitVRLittleEndian); element = ds.FindFirstElement(null, DicomTagType.PatientID, true); if (element == null) { element = ds.InsertElement(null, false, DicomTagType.PatientID, DicomVRType.UN, false, 0); } ds.SetStringValue(element, "ID", DicomCharacterSetType.Default); server.TestData = true; client.SendData(pid, cs, ds); if (!client.Wait()) // wait for NActionRequest to finish { Debug.Fail("SendData timed out"); } server.TestData = false; client.CloseForced(true); } server.CloseForced(true); } DicomEngine.Shutdown(); DicomNet.Shutdown(); } |