// VrfySCU.cpp: implementation of the LVrfySCU class. #include "stdafx.h" #include "VrfySCU.h" // Construction LVrfySCU::LVrfySCU(L_CHAR* pszPath, L_UINT32 nMode) : LDicomNet(pszPath, nMode) { m_pszServerName = NULL; m_pszClientName = NULL; } // Destruction LVrfySCU::~LVrfySCU() { // Free any allocated memory if (m_pszClientName) { delete [] m_pszClientName; } if (m_pszServerName) { delete [] m_pszServerName; } } // Close the connection L_VOID LVrfySCU::CloseConnection() { Close(); OnStatus(VRFY_CONNECTION_CLOSED, 0); } // Get the server and client information in order to start the verification process L_INT LVrfySCU::Verify(L_CHAR* pszServerName, L_CHAR* pszClientName, L_CHAR* pszServerIP, L_UINT nServerPort) { if (m_pszServerName) { delete [] m_pszServerName; m_pszServerName = NULL; } if (m_pszClientName) { delete [] m_pszClientName; m_pszClientName = NULL; } if (pszServerName) { m_pszServerName = new L_CHAR[lstrlen(pszServerName) + 1]; if (!m_pszServerName) { return DICOM_ERROR_MEMORY; } // The SCP AE name lstrcpy(m_pszServerName, pszServerName); } if (pszClientName) { m_pszClientName = new L_CHAR[lstrlen(pszClientName) + 1]; if (!m_pszClientName) { return DICOM_ERROR_MEMORY; } // The SCU AE name lstrcpy(m_pszClientName,pszClientName); } L_INT nRet; // Do the connection to the server nRet = Connect(NULL, 0, pszServerIP, nServerPort); if (nRet != DICOM_SUCCESS) { OnStatus(VRFY_CONNECT_FAILED, nRet); return nRet; } return 0; } // OnConnect() client receives this event from the SCP L_VOID LVrfySCU::OnConnect(L_INT nError) { if (nError != DICOM_SUCCESS) { // Failed connection OnStatus(VRFY_CONNECT_FAILED, nError); TerminateVrfy(); return; } // Succeeded connection OnStatus(VRFY_CONNECT_SUCCEEDED, 0); // Build the association for the C-ECHO LDicomAssociate VrfyAssociate(TRUE); L_INT nRet; // Set the version nRet = VrfyAssociate.SetVersion(1); if (nRet != 0) { OnStatus(VRFY_DICOM_ERROR, nRet); TerminateVrfy(); return; } // Set called application title nRet = VrfyAssociate.SetCalled(m_pszServerName ? m_pszServerName : ""); delete [] m_pszServerName; // Don't need it any more m_pszServerName = NULL; if (nRet != 0) { OnStatus(VRFY_DICOM_ERROR, nRet); TerminateVrfy(); return; } // Set calling application title nRet = VrfyAssociate.SetCalling(m_pszClientName ? m_pszClientName : ""); delete [] m_pszClientName; // Don't need it any more m_pszClientName = NULL; if (nRet != 0) { OnStatus(VRFY_DICOM_ERROR, nRet); TerminateVrfy(); return; } L_INT nPresID = 1; // Add presentation context for the verification service class nRet = VrfyAssociate.AddPresentation(nPresID, 0, UID_VERIFICATION_CLASS); if (nRet != 0) { OnStatus(VRFY_DICOM_ERROR, nRet); TerminateVrfy(); return; } // Add the transfere syntax for the verification service class nRet = VrfyAssociate.AddTransfer(nPresID, UID_IMPLICIT_VR_LITTLE_ENDIAN); if (nRet != 0) { OnStatus(VRFY_DICOM_ERROR, nRet); TerminateVrfy(); return; } // Add the Implementation Version nRet = VrfyAssociate.SetImplementVersion(TRUE, IMPLEMENTATION_VERSION_NAME); if (nRet != 0) { OnStatus(VRFY_DICOM_ERROR, nRet); TerminateVrfy(); return; } // Add the Implementation Class nRet = VrfyAssociate.SetImplementClass(TRUE, IMPLEMENTATION_CLASS_UID); if (nRet != 0) { OnStatus(VRFY_DICOM_ERROR, nRet); TerminateVrfy(); return; } // Sending the associate request OnStatus(VRFY_SEND_ASSOCIATION_REQUEST, 0); nRet = SendAssociateRequest(&VrfyAssociate); if (nRet != 0) { // Error sending the association request OnStatus(VRFY_DICOM_ERROR, nRet); TerminateVrfy(); } } // Receive the acceptance of the association L_VOID LVrfySCU::OnReceiveAssociateAccept(LDicomAssociate *pPDU) { L_UCHAR uPresID; // Server accept the association OnStatus(VRFY_RECEIVE_ASSOCIATE_ACCEPT, 0); // Check if the verification is supported uPresID = pPDU->FindAbstract(UID_VERIFICATION_CLASS); if ((uPresID == 0) || (pPDU->GetResult(uPresID) != PDU_ACCEPT_RESULT_SUCCESS)) { // Verification NOT supported OnStatus(VRFY_VERIFICATION_NOT_SUPPORTED, 0); return; } // Verification supported // Sneding the C-Echo request OnStatus(VRFY_SEND_CECHO_REQUEST, 0); L_INT nRet; nRet = SendCEchoRequest(uPresID, 1, UID_VERIFICATION_CLASS); if (nRet != 0) { // Error sending the CEcho Request OnStatus(VRFY_DICOM_ERROR, nRet); TerminateVrfy(); } } // Receive the rejection of the association L_VOID LVrfySCU::OnReceiveAssociateReject(L_UCHAR nResult, L_UCHAR nSource, L_UCHAR nReason) { // Server rejects this association OnStatus(VRFY_RECEIVE_ASSOCIATE_REJECT, 0); // Close the connection CloseConnection(); } // Receive the acceptance for the releasing of the association L_VOID LVrfySCU::OnReceiveReleaseResponse() { OnStatus(VRFY_RECEIVE_RELEASE_RESPONSE, 0); // Close the association CloseConnection(); } // Receiving Response for the C-ECHO form the SCP L_VOID LVrfySCU::OnReceiveCEchoResponse(L_UCHAR nPresentationID, L_UINT16 nMessageID, L_CHAR *pszClass, L_UINT16 nStatus) { OnStatus(VRFY_RECEIVE_CECHO_RESPONSE, 0); // Send a Release Request message L_INT nRet; OnStatus(VRFY_SEND_RELEASE_REQUEST, 0); nRet = SendReleaseRequest(); if (nRet != 0) { // Error sending release request OnStatus(VRFY_DICOM_ERROR, nRet); TerminateVrfy(); } } // Terminate the verification process L_VOID LVrfySCU::TerminateVrfy() { // Check if the connection is associated if (IsAssociated()) { // Send abort L_INT nRet; nRet = SendAbort(PDU_ABORT_SOURCE_USER, 0); if (nRet == 0) // Aborted { // Close the connection CloseConnection(); OnStatus(VRFY_PROCESS_TERMINATED, 0); return; } } // Check if the connection is established if (IsConnected()) { // Close the connection CloseConnection(); OnStatus(VRFY_PROCESS_TERMINATED, 0); } } L_VOID LVrfySCU::OnStatus(L_UINT uStatus, L_INT nErrorCode) { }