LDicomNet::SendAbort

Summary

Sends an Abort message to a connection. This function is available in the PACS Imaging Toolkit.

Syntax

#include "ltdic.h"

L_INT LDicomNet::SendAbort(nSource, nReason)

Parameters

L_UCHAR nSource

The source of the abort. Possible values are:

Value Meaning
PDU_ABORT_SOURCE_USER [0] Service user. (SCU)
PDU_ABORT_SOURCE_PROVIDER [2] Service provider. (SCP)

L_UCHAR nReason

The reason for the abort. If the source of the abort is PDU_ABORT_SOURCE_USER, the reasons for the abort are not significant. If the source of the abort is PDU_ABORT_SOURCE_PROVIDER, the possible values are:

Value Meaning
PDU_ABORT_REASON_UNKNOWN [0] Unknown
PDU_ABORT_REASON_UNRECOGNIZED [1] Unrecognized PDU
PDU_ABORT_REASON_UNEXPECTED [2] Unexpected PDU
PDU_ABORT_REASON_UNRECOGNIZED_PARAM [4] Unrecognized PDU parameter
PDU_ABORT_REASON_UNEXPECTED_PARAM [5] Unexpected PDU parameter
PDU_ABORT_REASON_INVALID_PARAM [6] Invalid PDU parameter value

Returns

Value Meaning
0 SUCCESS
>0 An error occurred. Refer to Return Codes.

Comments

Calling LDicomNet::SendAbort generates a call to LDicomNet::OnReceiveAbort. At this time the DICOM Association is closed.

NOTE: It is preferable to close a DICOM Association using the LDicomNet::SendReleaseRequest and LDicomNet::SendReleaseResponse. For more information on closing a DICOM Association, refer to Closing a DICOM Associate Connection.

Required DLLs and Libraries

Platforms

Win32, x64

See Also

Functions

Topics

Example

This is a basic, but complete example that shows a DICOM client sending an abort to a server.

namespace LDicomNet_SendAbort_Namespace 
{ 
   // Logs a message 
   // This implementation logs to the console, and the debug window 
   L_VOID LogMessage(TCHAR *szMsg) 
   { 
      wprintf(TEXT("\n")); 
      wprintf(szMsg); 
 
      OutputDebugStringW(TEXT("\n")); 
      OutputDebugStringW(szMsg); 
   } 
 
 
   // ******************************************************************************************* 
   // Client Class  
   // 
   // Class that is used to connect to the server  
   // ******************************************************************************************* 
   class CMyClient : public LDicomNet 
   { 
   public: 
      CMyClient(L_INT32 nMode): LDicomNet(NULL, nMode) 
      { 
         m_waitEvent = CreateEvent( NULL, TRUE, TRUE, TEXT("ClientEvent")); 
         ResetEvent(m_waitEvent); 
      } 
 
      ~CMyClient(void) 
      { 
         CloseHandle(m_waitEvent); 
      } 
 
      // Client 
      L_VOID OnConnect                    (L_INT nError); 
      L_VOID OnReceiveAssociateAccept     (LDicomAssociate *pPDU); 
      L_VOID OnReceiveReleaseResponse     (); 
 
      L_BOOL Wait(DWORD timeout = 5000); 
 
   private: 
      HANDLE m_waitEvent; 
   }; 
 
   // Continues dispatching messages until hEvent is signalled, our timeout 
   // Returns TRUE if hEvent is signalled 
   // Returns FALSE if timeout 
   L_BOOL MessageLoop ( 
      HANDLE hEvent, // handles that need to be waited on 
      DWORD timeout  // timeout in milliseconds 
      ) 
   { 
      DWORD dwStart = GetTickCount(); 
      MSG msg = {0}; 
 
      volatile L_BOOL bRunForever = TRUE; 
      while (bRunForever) 
      { 
         if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))  
         { 
            TranslateMessage(&msg); 
            DispatchMessage(&msg); 
         } 
 
         if (WaitForSingleObject(hEvent, 0) == WAIT_OBJECT_0) 
         { 
            ResetEvent(hEvent); 
            return TRUE; 
         } 
 
         DWORD dwCurrent = GetTickCount(); 
         if ((dwCurrent - dwStart) > timeout) 
         { 
            return FALSE; 
         } 
      } 
      return TRUE; 
   } 
 
   L_VOID CMyClient::OnConnect(L_INT nError) 
   { 
      L_TCHAR szMsg[200] = {0}; 
 
      wsprintf(szMsg, TEXT("CMyClient::OnConnect: nError[%d]"), nError);  
      LogMessage(szMsg); 
   } 
 
   L_VOID CMyClient::OnReceiveAssociateAccept  (LDicomAssociate *pPDU) 
   { 
      UNREFERENCED_PARAMETER(pPDU); 
      SetEvent(m_waitEvent); 
      LogMessage(TEXT("CMyClient::OnReceiveAssociateAccept")); 
   } 
 
   L_VOID CMyClient::OnReceiveReleaseResponse() 
   { 
      SetEvent(m_waitEvent); 
      LogMessage(TEXT("CMyClient::OnReceiveReleaseResponse")); 
   } 
 
   L_BOOL CMyClient::Wait(DWORD timeout) 
   { 
      L_BOOL bRet = MessageLoop(m_waitEvent,  timeout);   
      return bRet; 
   } 
 
   // ******************************************************************************************* 
   // Server Connection Class  
   // 
   // When a client connects, CMyServer creates a new instance of the CMyServerConnection class  
   // and accepts the connection.   
   // ******************************************************************************************* 
   class CMyServerConnection : public LDicomNet 
   { 
   public: 
      CMyServerConnection(L_INT32 nMode): LDicomNet(NULL, nMode) 
      { 
      } 
      ~CMyServerConnection(void) 
      { 
      } 
 
      // Server 
      L_VOID OnReceiveAssociateRequest(LDicomAssociate *pPDU); 
      L_VOID OnReceiveAbort(L_UCHAR nSource, L_UCHAR nReason); 
      L_VOID OnReceiveReleaseRequest(); 
   }; 
 
   #define SIZEINWORD(p) sizeof(p)/sizeof(L_TCHAR) 
   L_VOID CMyServerConnection::OnReceiveAssociateRequest(LDicomAssociate *pPDU) 
   { 
      LogMessage(TEXT("\tCMyServerConnection::OnReceiveAssociateRequest")); 
 
            
         LDicomAssociate DicomAssociate(FALSE); 
 
         //Copy presentation objects from received 
         //Reply that we only support the first Transfer Syntax from the received hPDU 
         L_TCHAR szTransfer[PDU_MAX_UID_SIZE+1] = {0}; 
         L_TCHAR szAbstract[PDU_MAX_UID_SIZE+1] = {0}; 
         L_INT iPresentationCount = pPDU->GetPresentationCount(); 
         for (L_UCHAR i = 0; i<iPresentationCount; i++) 
         { 
            L_UCHAR nId = pPDU->GetPresentation(i); 
            pPDU->GetTransfer(nId, 0, szTransfer, PDU_MAX_UID_SIZE+1); 
            L_UCHAR nResult = PDU_ACCEPT_RESULT_SUCCESS; 
            pPDU->GetAbstract(nId, szAbstract, PDU_MAX_UID_SIZE+1); 
            DicomAssociate.AddPresentation( nId, nResult, szAbstract); 
            DicomAssociate.AddTransfer( nId, szTransfer); 
         } 
 
         LogMessage(TEXT("\tCMyServerConnection::SendAssociateAccept")); 
         SendAssociateAccept(&DicomAssociate); 
       
   } 
 
   L_VOID CMyServerConnection::OnReceiveAbort(L_UCHAR nSource, L_UCHAR nReason) 
   { 
      LogMessage(TEXT("\tCMyServerConnection::OnReceiveAbort")); 
 
      switch(nSource) 
      { 
      case PDU_ABORT_SOURCE_USER: 
         LogMessage(TEXT("\t\tSource: PDU_ABORT_SOURCE_USER")); 
         break; 
 
      case PDU_ABORT_SOURCE_PROVIDER: 
         LogMessage(TEXT("\t\tSource: PDU_ABORT_SOURCE_PROVIDER")); 
         break; 
      } 
 
      switch(nReason) 
      { 
      case PDU_ABORT_REASON_UNKNOWN: 
         LogMessage(TEXT("\t\tReason: PDU_ABORT_REASON_UNKNOWN")); 
         break; 
 
      case PDU_ABORT_REASON_UNRECOGNIZED: 
         LogMessage(TEXT("\t\tReason: PDU_ABORT_REASON_UNRECOGNIZED")); 
         break; 
 
      case PDU_ABORT_REASON_UNEXPECTED: 
         LogMessage(TEXT("\t\tReason: PDU_ABORT_REASON_UNEXPECTED")); 
         break; 
 
      case PDU_ABORT_REASON_UNRECOGNIZED_PARAM: 
         LogMessage(TEXT("\t\tReason: PDU_ABORT_REASON_UNRECOGNIZED_PARAM")); 
         break; 
 
      case PDU_ABORT_REASON_UNEXPECTED_PARAM: 
         LogMessage(TEXT("\t\tReason: PDU_ABORT_REASON_UNEXPECTED_PARAM")); 
         break; 
 
      case PDU_ABORT_REASON_INVALID_PARAM: 
         LogMessage(TEXT("\t\tReason: PDU_ABORT_REASON_INVALID_PARAM")); 
         break;        
      } 
 
      this->Close(); 
   } 
 
   L_VOID CMyServerConnection::OnReceiveReleaseRequest() 
   { 
      LogMessage(TEXT("\tCMyServerConnection::OnReceiveReleaseRequest")); 
      LogMessage(TEXT("\tCMyServerConnection::SendReleaseResponse")); 
      SendReleaseResponse(); 
   } 
 
   // ******************************************************************************************* 
   // Server Class  
   // 
   // Listens for connections 
   // When a client connects, this class creates a CMyServerConnection and accepts the connection 
   // ******************************************************************************************* 
   class CMyServer : public LDicomNet 
   { 
   public: 
      CMyServer(L_INT32 nMode): LDicomNet(NULL, nMode) 
      { 
         m_pServerConnection = NULL; 
      } 
 
      ~CMyServer(void) 
      { 
         if (m_pServerConnection != NULL) 
         { 
            delete m_pServerConnection; 
         } 
      } 
 
      L_VOID OnAccept       (L_INT nError); 
      L_VOID OnClose        (L_INT nError, LDicomNet *pServerConnection); 
 
      CMyServerConnection *m_pServerConnection; 
   }; 
 
   L_VOID CMyServer::OnAccept(L_INT nError) 
   { 
      LogMessage(TEXT("\tCMyServer::OnAccept")); 
      if (nError != DICOM_SUCCESS) 
      { 
         return; 
      } 
 
      if (m_pServerConnection != NULL) 
      { 
         delete m_pServerConnection; 
         m_pServerConnection = NULL; 
      } 
 
      m_pServerConnection = new CMyServerConnection(DICOM_SECURE_NONE); 
      if (m_pServerConnection == NULL) 
      { 
         return; 
      } 
 
      nError = LDicomNet::Accept(m_pServerConnection); 
      if (nError != DICOM_SUCCESS) 
      { 
         delete m_pServerConnection; 
         return; 
      } 
   } 
 
   L_VOID CMyServer::OnClose(L_INT nError, LDicomNet *pServerConnection) 
   { 
      UNREFERENCED_PARAMETER(nError); 
      LogMessage(TEXT("\tCMyServer::OnClose")); 
      if (m_pServerConnection == pServerConnection) 
      { 
         m_pServerConnection = NULL; 
      } 
      delete (CMyServerConnection *)pServerConnection; 
   } 
 
   // ******************************************************************************************* 
   // Sample starts here  
   // ******************************************************************************************* 
   #define WaitForProcessing() \ 
   { \ 
      if (!client.Wait()) \ 
      { \ 
         LogMessage(TEXT("Timeout: client.Connect")); \ 
         nRet = DICOM_ERROR_NET_TIME_OUT; \ 
         goto Cleanup; \ 
      } \ 
   }  
 
   L_INT LDicomNet_SendAbortExample() 
   { 
      LogMessage(TEXT("\n\n *** SendAbortExample ***")); 
 
      L_TCHAR *pszServerAddress = TEXT("127.0.0.1"); 
      L_UINT uServerPort = 105; 
      L_INT nRet = DICOM_SUCCESS; 
 
      LDicomNet::StartUp(); 
 
      CMyClient client(DICOM_SECURE_NONE); 
      CMyServer server(DICOM_SECURE_NONE); 
      
      LogMessage(TEXT("\tCMyServer::Listen")); 
      nRet = server.Listen(pszServerAddress, uServerPort, 5); 
 
      LogMessage(TEXT("CMyClient::Connect")); 
      client.Connect(NULL, 0, pszServerAddress, uServerPort); 
      if (!client.Wait(2000)) 
      { 
         if (!client.IsConnected()) 
         { 
            LogMessage(TEXT("Timeout: client.Connect"));  
            nRet = DICOM_ERROR_NET_TIME_OUT; 
            goto Cleanup; 
         } 
      } 
 
      if (nRet == DICOM_SUCCESS) 
      { 
         //create the Associate Class as Request 
         LDicomAssociate dicomAssociateRequest(TRUE); 
         dicomAssociateRequest.Default(); 
 
         // Send A-Associate-RQ message 
         dicomAssociateRequest.SetCalled(TEXT("LEAD_SERVER")); 
         dicomAssociateRequest.SetCalling(TEXT("LEAD_CLIENT")); 
 
         LogMessage(TEXT("CMyClient::SendAssociateRequest")); 
         nRet = client.SendAssociateRequest(&dicomAssociateRequest); 
         if (!client.Wait(2000)) 
         { 
            LogMessage(TEXT("Timeout: client.Connect"));  
            nRet = DICOM_ERROR_NET_TIME_OUT; 
            goto Cleanup; 
         } 
      } 
 
      LogMessage(TEXT("CMyClient::SendAbort")); 
      client.SendAbort( PDU_ABORT_SOURCE_USER, PDU_ABORT_REASON_UNKNOWN); 
      client.Wait(1000); 
 
Cleanup: 
      LogMessage(TEXT("CMyClient::CloseForced")); 
      if (client.IsConnected()) 
      { 
         client.CloseForced(TRUE); 
         client.Wait(1000); 
      } 
 
      LogMessage(TEXT("\tCMyServer::Close")); 
      server.Close(); 
 
      LDicomNet::ShutDown(); 
 
      return nRet; 
   } 
 
} 

Help Version 23.0.2024.7.1
Products | Support | Contact Us | Intellectual Property Notices
© 1991-2024 LEAD Technologies, Inc. All Rights Reserved.

LEADTOOLS DICOM C++ Class Library Help
Products | Support | Contact Us | Intellectual Property Notices
© 1991-2023 LEAD Technologies, Inc. All Rights Reserved.