Sends an Abort message to a connection. This function is available in the PACS Imaging Toolkit.
#include "ltdic.h"
L_INT LDicomNet::SendAbort(nSource, nReason)
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) |
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 |
| Value | Meaning |
|---|---|
| 0 | SUCCESS |
| >0 | An error occurred. Refer to Return Codes. |
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.
Win32, x64
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 windowL_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);}// ClientL_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 timeoutL_BOOL MessageLoop (HANDLE hEvent, // handles that need to be waited onDWORD 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){}// ServerL_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 hPDUL_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 RequestLDicomAssociate dicomAssociateRequest(TRUE);dicomAssociateRequest.Default();// Send A-Associate-RQ messagedicomAssociateRequest.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;}}