LDicomNet::Initialize

#include "ltdic.h"

L_INT LDicomNet::Initialize(pszPath, nMode, pCtxCreate)

L_TCHAR *pszPath;

character string

L_INT32 nMode;

initialization mode

pL_SSL_CTX_CREATE *pCtxCreate;

pointer to a structure

This function is to be used in conjunction with the LDicomNet::LDicomNet(*pszPath, nMode, bReserved) constructor in order to change security options from the defaults. This function is available in the Medical Imaging Suite toolkits.

Parameter Description
pszPath Character string that contains the location of the temporary files. This should be the same string that was used in the LDicomNet constructor.
nMode Flag that indicates the security mode to use when initializing the network structure. This should be the same flag that was used in the LDicomNet constructor. Possible values are:
  Value Meaning
  DICOM_SECURE_NONE No security mode.
  DICOM_SECURE_ISCL Integrated Secure Communication Layer security mode.
  DICOM_SECURE_TLS Transport Layer Security security mode.
pCtxCreate Pointer to the L_SSL_CTX_CREATE structure that is used to modify the security defaults. This structure is used only if the nMode flag is DICOM_SECURE_TLS. Pass NULL to get the default values.

Returns

SUCCESS

The function was successful.

> 0

An error occurred. Refer to Return Codes..

Comments

This function is to be used in conjunction with the LDicomNet::LDicomNet(*pszPath, nMode, bReserved) constructor when changing security options from the defaults. Note that when using the LDicomNet::LDicomNet(*pszPath, nMode, bReserved) version of the constructor, in addition to calling LDicomNet::Startup it is also necessary to call LDicomNet::Initialize in order to prepare the LDicomNet object for use. Use the pCtxCreate parameter when the nMode flag is set to DICOM_SECURE_TLS.

Note that the following uses of the LDicomNet constructors are functionally equivalent:

1.

LDicomNet *pNet = new LDicomNet(pszPath, nMode);

2.

LDicomNet *pNet = new LDicomNet(pszPath, nMode, 0);
If (pNet)
 pNet->Initialize(pszPath, nMode, NULL);

Required DLLs and Libraries

LTDIC

For a listing of the exact DLLs and Libraries needed, based on the toolkit version, refer to Files To Be Included With Your Application

Platforms

Win32, x64

See Also

Functions:

LDicomNet::~LDicomNet, LDicomNet::StartUp, Class Members

Topics:

Adding TLS Security to a DICOM Connection

 

Negotiating a Ciphersuite

 

General Transport Layer Secure (TLS) Information

 

DICOM Network Connection: Creating a Network Connection

 

DICOM Connection: TLS Security

Example

This is a basic, but complete example that shows a DICOM client sending a C-Echo-REQ to a server, and the server processing the request using TLS Security.

#define MAKE_IMAGE_PATH(pFileName) TEXT("C:\\Users\\Public\\Documents\\LEADTOOLS Images\\")pFileName 
namespace LDicomNet_Initialize_Namespace 
{ 
#ifndef CA_CERT_NAME 
#define CA_CERT_NAME      MAKE_IMAGE_PATH(TEXT("CA.pem")) 
#endif 
#ifndef SERVER_CERT_NAME 
#define SERVER_CERT_NAME  MAKE_IMAGE_PATH(TEXT("Server.pem")) 
#endif 
#ifndef CLIENT_CERT_NAME 
#define CLIENT_CERT_NAME  MAKE_IMAGE_PATH(TEXT("Client.pem")) 
#endif 
   // 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); 
   } 
   L_VOID LogMessage(TCHAR *s, L_INT n) 
   { 
      TCHAR szLog[200] = {0}; 
      wsprintf(szLog, TEXT("%s [%d]"), s, n); 
      LogMessage(szLog); 
   } 
   L_INT PrivateKeyPassword(L_TCHAR *pszPassword, L_INT nSize, L_INT nFlag) 
   { 
      UNREFERENCED_PARAMETER(nFlag); 
      LPCTSTR pszMyPassword= TEXT("test"); 
      L_INT nRet = 0; 
      if ((L_INT)_tcslen(pszMyPassword) < nSize) 
      { 
         _tcsncpy_s(pszPassword, nSize, pszMyPassword, nSize); 
         nRet = (L_INT)_tcslen(pszMyPassword); 
      } 
      return nRet; 
   } 
   L_VOID SetupTlsContext(LDicomNet *pNet, L_TCHAR *pszCertName) 
   { 
      if (pNet != NULL) 
      { 
         L_SSL_CTX_CREATE ctxCreate; 
         memset(&ctxCreate, 0, sizeof(L_SSL_CTX_CREATE)); 
         ctxCreate.uStructSize   = sizeof(L_SSL_CTX_CREATE); 
         ctxCreate.uFlags        = FLAG_SSL_CTX_CREATE_METHOD_TYPE | FLAG_SSL_CTX_CREATE_VERIFY_MODE | 
         FLAG_SSL_CTX_CREATE_VERIFY_DEPTH | FLAG_SSL_CTX_CREATE_OPTIONS | FLAG_SSL_CTX_CREATE_CAFILE; 
         ctxCreate.nMethodTypeSSL= TYPE_SSLV23_METHOD; 
         ctxCreate.pszCAfile     = CA_CERT_NAME; 
         ctxCreate.uVerifyMode   = L_SSL_VERIFY_PEER | L_SSL_VERIFY_FAIL_IF_NO_PEER_CERT; 
         ctxCreate.nVerifyDepth  = 2; 
         ctxCreate.nOptions      = L_SSL_OP_NO_SSLv2|L_SSL_OP_ALL; 
         ctxCreate.nReserved1    = 0; 
         ctxCreate.nReserved2    = 0; 
         L_INT nRet = pNet->Initialize(NULL, DICOM_SECURE_TLS, &ctxCreate); 
         if (nRet == DICOM_SUCCESS) 
         { 
            L_TCHAR szMsg[200] = {0}; 
            // Assign the server the certificate 
            // Note that SERVER_CERT_NAME contains both the password and an encrypted private key 
            // When loading the private key, the OnPrivateKeyPassword virtual function is called 
            // so that the encryption password "test" can be supplied 
            nRet = pNet->SetServerCertificateTLS (pszCertName, L_TLS_FILETYPE_PEM, NULL); 
            if (nRet == DICOM_SUCCESS) 
               wsprintf(szMsg, TEXT("%s loaded successfully"), pszCertName); 
            else 
               wsprintf(szMsg, TEXT("%s could not be loaded successfully -- error[%d]"), pszCertName, nRet); 
            LogMessage(szMsg); 
         } 
      } 
   } 
   L_VOID DumpTlsInformation(LDicomNet *pNet) 
   { 
      L_CIPHERSUITE ciphersuite; 
      ciphersuite = pNet->GetCiphersuiteTLS(); 
      switch(ciphersuite) 
      { 
         case TLS_DHE_RSA_WITH_DES_CBC_SHA: 
         LogMessage( TEXT("           Secure connected, cipher is TLS_DHE_RSA_WITH_DES_CBC_SHA")); 
         break; 
         case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA: 
         LogMessage( TEXT("           Secure connected, cipher is TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA")); 
         break; 
         case TLS_DHE_RSA_AES256_SHA: 
         LogMessage( TEXT("           Secure connected, cipher is TLS_DHE_RSA_AES256_SHA")); 
         break; 
      } 
      L_UINT32 nEncryptionAlgorithm = pNet->GetEncryptionAlgorithmTLS(ciphersuite); 
      switch(nEncryptionAlgorithm) 
      { 
         case L_CRYPT_NONE: 
         LogMessage(TEXT("           Encryption Algorithm: L_CRYPT_NONE")); 
         break; 
         case L_CRYPT_DES: 
         LogMessage(TEXT("           Encryption Algorithm: L_CRYPT_DES")); 
         break; 
         case L_CRYPT_3DES: 
         LogMessage(TEXT("           Encryption Algorithm: L_CRYPT_3DES")); 
         break; 
         case L_CRYPT_RC4: 
         LogMessage(TEXT("           Encryption Algorithm: L_CRYPT_RC4")); 
         break; 
         case L_CRYPT_RC2: 
         LogMessage(TEXT("           Encryption Algorithm: L_CRYPT_RC2")); 
         break; 
         case L_CRYPT_IDEA: 
         LogMessage(TEXT("           Encryption Algorithm: L_CRYPT_IDEA")); 
         break; 
         case L_CRYPT_FORTEZZA: 
         LogMessage(TEXT("           Encryption Algorithm: L_CRYPT_FORTEZZA")); 
         break; 
         case L_CRYPT_AES: 
         LogMessage(TEXT("           Encryption Algorithm: L_CRYPT_AES")); 
         break; 
      } 
      L_UINT32 auth = pNet->GetAuthenticationAlgorithmTLS(ciphersuite); 
      switch(auth) 
      { 
         case L_MUTUALAUTH_NONE: 
         LogMessage(TEXT("           Authentication Algorithm: L_MUTUALAUTH_NONE")); 
         break; 
         case L_MUTUALAUTH_RSA: 
         LogMessage(TEXT("           Authentication Algorithm: L_MUTUALAUTH_RSA")); 
         break; 
         case L_MUTUALAUTH_DSS: 
         LogMessage(TEXT("           Authentication Algorithm: L_MUTUALAUTH_DSS")); 
         break; 
         case L_MUTUALAUTH_DH: 
         LogMessage(TEXT("           Authentication Algorithm: L_MUTUALAUTH_DH")); 
         break; 
      } 
      L_UINT32 integrity = pNet->GetIntegrityAlgorithmTLS(ciphersuite); 
      switch(integrity) 
      { 
         case L_MAC_NONE: 
         LogMessage(TEXT("           Message Authentication code type: L_MAC_NONE")); 
         break; 
         case L_MAC_SHA1: 
         LogMessage(TEXT("           Message Authentication code type: L_MAC_SHA1")); 
         break; 
         case L_MAC_MD5: 
         LogMessage(TEXT("           Message Authentication code type: L_MAC_MD5")); 
         break; 
      } 
      L_UINT32 keyExchange = pNet->GetKeyExchangeAlgorithmTLS(ciphersuite); 
      switch(keyExchange) 
      { 
         case L_KEYEXCHANGE_NONE: 
         LogMessage(TEXT("           Key Exchange Algorithm: L_KEYEXCHANGE_NONE")); 
         break; 
         case L_KEYEXCHANGE_RSA_SIGNED_DHE: 
         LogMessage(TEXT("           Key Exchange Algorithm: L_KEYEXCHANGE_RSA_SIGNED_DHE")); 
         break; 
         case L_KEYEXCHANGE_RSA: 
         LogMessage(TEXT("           Key Exchange Algorithm: L_KEYEXCHANGE_RSA")); 
         break; 
         case L_KEYEXCHANGE_DH: 
         LogMessage(TEXT("           Key Exchange Algorithm: L_KEYEXCHANGE_DH")); 
         break; 
         case L_KEYEXCHANGE_DH_DSS: 
         LogMessage(TEXT("           Key  Exchange Algorithm: L_KEYEXCHANGE_DH_DSS")); 
         break; 
         case L_KEYEXCHANGE_FORTEZZA: 
         LogMessage(TEXT("           Key Exchange Algorithm: L_KEYEXCHANGE_FORTEZZA")); 
         break; 
      } 
      L_UINT32 uKeyLength = pNet->GetEncryptKeyLengthTLS(ciphersuite); 
      LogMessage(TEXT("           Encrypt Key Length"), uKeyLength); 
      L_UINT32 uMutualAuthKeyLength  = pNet->GetMutualAuthKeyLengthTLS(ciphersuite); 
      LogMessage(TEXT("           Mutual authentication key length"), uMutualAuthKeyLength); 
   } 
   // ******************************************************************************************* 
   // 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); 
         this->SetCipherToIndexTLS(0, TLS_DHE_RSA_WITH_DES_CBC_SHA); 
         L_CIPHERSUITE ciphersuite; 
         ciphersuite = this->GetCipherFromIndexTLS(0); 
         assert(ciphersuite == TLS_DHE_RSA_WITH_DES_CBC_SHA); 
         this->SetClientCertificateTLS( MAKE_IMAGE_PATH(TEXT("Client.pem")), L_TLS_FILETYPE_PEM, NULL); 
      } 
      ~CMyClient(void) 
      { 
         CloseHandle(m_waitEvent); 
      } 
      // Client 
      L_VOID OnConnect                    (L_INT nError); 
      L_VOID OnSecureLinkReady            (L_UINT32 nError); 
      L_VOID OnReceiveAssociateAccept     (LDicomAssociate *pPDU); 
      L_VOID OnReceiveReleaseResponse     (); 
      L_VOID OnReceiveCEchoResponse       (L_UCHAR nPresentationID, L_UINT16 nMessageID, L_TCHAR *pszClass, L_UINT16 nStatus); 
      L_INT  OnPrivateKeyPassword         (L_TCHAR *pszPassword, L_INT nSize, L_INT nFlag); 
      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::OnSecureLinkReady(L_UINT32 nError) 
   { 
      UNREFERENCED_PARAMETER(nError); 
      SetEvent(m_waitEvent); 
      L_UINT32 uSecureMode = this->GetSecureMode(); 
      switch(uSecureMode) 
      { 
         case DICOM_SECURE_NONE: 
         LogMessage(TEXT("CMyClient::OnSecureLinkReady: DICOM_SECURE_NONE")); 
         break; 
         case DICOM_SECURE_ISCL: 
         LogMessage(TEXT("CMyClient::OnSecureLinkReady: DICOM_SECURE_ISCL")); 
         break; 
         case DICOM_SECURE_TLS: 
         { 
            LogMessage(TEXT("CMyClient::OnSecureLinkReady: DICOM_SECURE_TLS")); 
            if (nError == DICOM_SUCCESS) 
            { 
               DumpTlsInformation(this); 
            } 
            else 
            { 
               L_TCHAR szMsg[200] = {0}; 
               wsprintf(szMsg, TEXT(           "ClientTLS: Secure link error %d"), nError); 
               LogMessage(szMsg); 
            } 
         } 
         break; 
      } 
   } 
   L_VOID CMyClient::OnReceiveAssociateAccept  (LDicomAssociate *pPDU) 
   { 
      UNREFERENCED_PARAMETER(pPDU); 
      SetEvent(m_waitEvent); 
      LogMessage(TEXT("CMyClient::OnReceiveAssociateAccept")); 
   } 
   L_VOID CMyClient::OnReceiveCEchoResponse(L_UCHAR nPresentationID, L_UINT16 nMessageID, L_TCHAR *pszClass, L_UINT16 nStatus) 
   { 
      SetEvent(m_waitEvent); 
      L_TCHAR szMsg[200] = {0}; 
      if (pszClass == NULL) 
      { 
         pszClass = TEXT(""); 
      } 
      wsprintf(szMsg, TEXT("CMyClient::OnReceiveCEchoResponse: \n\tnPresentationID[%d], \n\tnMessageID[%d], \n\tpszClass[%s], \n\tnStatus[%d]"), nPresentationID, nMessageID, pszClass, nStatus); 
      LogMessage(szMsg); 
   } 
   L_INT CMyClient::OnPrivateKeyPassword(L_TCHAR *pszPassword, L_INT nSize, L_INT nFlag) 
   { 
      return PrivateKeyPassword(pszPassword, nSize, nFlag); 
   } 
   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 OnReceiveAssociateReject     (L_UCHAR nResult, L_UCHAR nSource, L_UCHAR nReason); 
      L_VOID OnReceiveCEchoRequest        (L_UCHAR nPresentationID, L_UINT16 nMessageID, L_TCHAR *pszClass); 
      L_VOID OnReceiveReleaseRequest      (); 
      L_INT  OnPrivateKeyPassword         (L_TCHAR *pszPassword, L_INT nSize, L_INT nFlag); 
   }; 
#define SIZEINWORD(p) sizeof(p)/sizeof(L_TCHAR) 
   L_VOID CMyServerConnection::OnReceiveAssociateRequest(LDicomAssociate *pPDU) 
   { 
      LogMessage(TEXT("\tCMyServerConnection::OnReceiveAssociateRequest")); 
      //check the version, if not 1, reject it 
      if (pPDU->GetVersion() != 1) 
      { 
         LogMessage(TEXT("\tCMyServerConnection::SendAssociateReject")); 
         SendAssociateReject( 
         PDU_REJECT_RESULT_PERMANENT, 
         PDU_REJECT_SOURCE_USER, 
         PDU_REJECT_REASON_UNKNOWN 
         ); 
      } 
      else 
      { 
         LDicomAssociate DicomAssociate(FALSE); 
         L_TCHAR clientAE[20] = {0}; 
         pPDU->GetCalling(clientAE, 20); 
         if (lstrcmp(clientAE, TEXT("LEAD_CLIENT")) != 0) 
         { 
            LogMessage(TEXT("\tCMyServerConnection::SendAssociateReject")); 
            SendAssociateReject( 
            PDU_REJECT_RESULT_PERMANENT, 
            PDU_REJECT_SOURCE_USER, 
            PDU_REJECT_REASON_UNKNOWN 
            ); 
            return; 
         } 
         //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::OnReceiveAssociateReject(L_UCHAR nResult, L_UCHAR nSource, L_UCHAR nReason) 
   { 
      L_TCHAR szMsg[200] = {0}; 
      wsprintf(szMsg, TEXT("\tOnReceiveAssociateReject\nResult[%d]\nSource[%d]\nReason[%d]"), nResult, nSource, nReason); 
      LogMessage(szMsg); 
   } 
   L_VOID CMyServerConnection::OnReceiveCEchoRequest(L_UCHAR nPresentationID, L_UINT16 nMessageID, L_TCHAR *pszClass) 
   { 
      LogMessage(TEXT("\tCMyServerConnection::OnReceiveCEchoRequest")); 
      LogMessage(TEXT("\tCMyServerConnection::SendCEchoResponse")); 
      SendCEchoResponse(nPresentationID, nMessageID, pszClass, COMMAND_STATUS_SUCCESS); 
   } 
   L_VOID CMyServerConnection::OnReceiveReleaseRequest() 
   { 
      LogMessage(TEXT("\tCMyServerConnection::OnReceiveReleaseRequest")); 
      LogMessage(TEXT("\tCMyServerConnection::SendReleaseResponse")); 
      SendReleaseResponse(); 
   } 
   L_INT CMyServerConnection::OnPrivateKeyPassword(L_TCHAR *pszPassword, L_INT nSize, L_INT nFlag) 
   { 
      return PrivateKeyPassword(pszPassword, nSize, nFlag); 
   } 
   // ******************************************************************************************* 
   // 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); 
      L_INT  OnPrivateKeyPassword         (L_TCHAR *pszPassword, L_INT nSize, L_INT nFlag); 
      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_TLS); 
      if (m_pServerConnection == NULL) 
      { 
         return; 
      } 
      SetupTlsContext(m_pServerConnection, SERVER_CERT_NAME); 
      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; 
   } 
   L_INT CMyServer::OnPrivateKeyPassword(L_TCHAR *pszPassword, L_INT nSize, L_INT nFlag) 
   { 
      return PrivateKeyPassword(pszPassword, nSize, nFlag); 
   } 
   // ******************************************************************************************* 
   // Sample starts here 
   // ******************************************************************************************* 
#define WaitForProcessing() \ 
   { \ 
      if (!client.Wait()) \ 
      { \ 
         LogMessage(TEXT("Timeout: client.Connect")); \ 
         nRet = DICOM_ERROR_NET_TIME_OUT; \ 
         goto Cleanup; \ 
      } \ 
   } 
   L_INT LDicomNet_InitializeExample() 
   { 
      LogMessage(TEXT("\n\n *** Initialize ***")); 
      L_TCHAR *pszServerAddress = TEXT("127.0.0.1"); 
      L_UINT uServerPort = 105; 
      L_INT nRet = DICOM_SUCCESS; 
      LDicomNet::StartUp(); 
      CMyClient client(DICOM_SECURE_TLS); 
      CMyServer server(DICOM_SECURE_TLS); 
      SetupTlsContext(&client, CLIENT_CERT_NAME); 
      SetupTlsContext(&server, SERVER_CERT_NAME); 
      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(5000)) 
         { 
            LogMessage(TEXT("Timeout: client.Connect")); 
            nRet = DICOM_ERROR_NET_TIME_OUT; 
            goto Cleanup; 
         } 
      } 
      L_UCHAR nPresentationID = client.GetAssociate()->FindAbstract(UID_VERIFICATION_CLASS); 
      L_UINT16 uUniqueID = 99; 
      LogMessage(TEXT("CMyClient::SendCEchoRequest")); 
      client.SendCEchoRequest( nPresentationID, uUniqueID, UID_VERIFICATION_CLASS); 
      WaitForProcessing(); 
      LogMessage(TEXT("CMyClient::SendReleaseRequest")); 
      client.SendReleaseRequest(); 
      WaitForProcessing(); 
Cleanup: 
      LogMessage(TEXT("CMyClient::Close")); 
      client.Close(); 
      client.Wait(1000); 
      LogMessage(TEXT("\tCMyServer::Close")); 
      server.Close(); 
      LDicomNet::ShutDown(); 
      return nRet; 
   } 
} 

Help Version 19.0.2017.10.27
Products | Support | Contact Us | Copyright Notices
© 1991-2017 LEAD Technologies, Inc. All Rights Reserved.
LEADTOOLS DICOM C++ Class Library Help