- Added function RecvEx
authorVictor Kirhenshtein <victor@netxms.org>
Sat, 3 Dec 2005 22:53:05 +0000 (22:53 +0000)
committerVictor Kirhenshtein <victor@netxms.org>
Sat, 3 Dec 2005 22:53:05 +0000 (22:53 +0000)
- Added timeout parameter to RecvCSCPMessage
- Other minor changes

17 files changed:
.gitattributes
include/nms_util.h
include/nxcscpapi.h
src/agent/core/session.cpp
src/console/nxuilib/AlarmSoundDlg.cpp [new file with mode: 0644]
src/console/nxuilib/AlarmSoundDlg.h [new file with mode: 0644]
src/console/nxuilib/Makefile.am
src/console/nxuilib/nxuilib.clw
src/console/nxuilib/nxuilib.dsp
src/console/nxuilib/nxuilib.rc
src/console/nxuilib/resource.h
src/libnetxms/tools.cpp
src/libnxcl/comm.cpp
src/server/core/admin.cpp
src/server/core/session.cpp
src/server/include/nxsrvapi.h
src/server/libnxsrv/agent.cpp

index e8d4e2d..80422c3 100644 (file)
@@ -417,6 +417,8 @@ src/console/nxav/res/small_logo.bmp -text
 src/console/nxav/res/warning.ico -text
 src/console/nxav/resource.h -text
 src/console/nxav/tools.cpp -text
+src/console/nxuilib/AlarmSoundDlg.cpp -text
+src/console/nxuilib/AlarmSoundDlg.h -text
 src/console/nxuilib/LoginDialog.cpp -text
 src/console/nxuilib/LoginDialog.h -text
 src/console/nxuilib/Makefile.am -text
index 2cd4f41..d194075 100644 (file)
@@ -187,7 +187,9 @@ typedef struct _dir_struc
 extern "C"
 {
 #endif
-       int LIBNETXMS_EXPORTABLE SendEx(int, const void *, size_t, int);
+       int LIBNETXMS_EXPORTABLE SendEx(SOCKET, const void *, size_t, int);
+   int LIBNETXMS_EXPORTABLE RecvEx(SOCKET nSocket, const void *pBuff,
+                                   size_t nSize, int nFlags, DWORD dwTimeout);
 
 #if defined(_WIN32) || !(HAVE_DECL___BSWAP_64)
    QWORD LIBNETXMS_EXPORTABLE __bswap_64(QWORD qwVal);
index 19b488c..05bf02a 100644 (file)
@@ -183,7 +183,7 @@ extern "C" {
 int LIBNXCSCP_EXPORTABLE RecvCSCPMessage(SOCKET hSocket, CSCP_MESSAGE *pMsg,
                                          CSCP_BUFFER *pBuffer, DWORD dwMaxMsgSize,
                                          CSCP_ENCRYPTION_CONTEXT **ppCtx,
-                                         BYTE *pDecryptionBuffer);
+                                         BYTE *pDecryptionBuffer, DWORD dwTimeout);
 CSCP_MESSAGE LIBNXCSCP_EXPORTABLE *CreateRawCSCPMessage(WORD wCode, DWORD dwId,
                                                         DWORD dwDataSize, void *pData,
                                                         CSCP_MESSAGE *pBuffer);
index fd6df92..91a2fc4 100644 (file)
@@ -169,7 +169,7 @@ void CommSession::ReadThread(void)
    WORD wFlags;
 
    // Initialize raw message receiving function
-   RecvCSCPMessage(0, NULL, m_pMsgBuffer, 0, NULL, NULL);
+   RecvCSCPMessage(0, NULL, m_pMsgBuffer, 0, NULL, NULL, 0);
 
    pRawMsg = (CSCP_MESSAGE *)malloc(RAW_MSG_SIZE);
 #ifdef _WITH_ENCRYPTION
@@ -178,7 +178,7 @@ void CommSession::ReadThread(void)
    while(1)
    {
       if ((iErr = RecvCSCPMessage(m_hSocket, pRawMsg, m_pMsgBuffer, RAW_MSG_SIZE,
-                                  &m_pCtx, pDecryptionBuffer)) <= 0)
+                                  &m_pCtx, pDecryptionBuffer, 0)) <= 0)
       {
          break;
       }
diff --git a/src/console/nxuilib/AlarmSoundDlg.cpp b/src/console/nxuilib/AlarmSoundDlg.cpp
new file mode 100644 (file)
index 0000000..104677a
--- /dev/null
@@ -0,0 +1,57 @@
+// AlarmSoundDlg.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "nxuilib.h"
+#include "AlarmSoundDlg.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// CAlarmSoundDlg dialog
+
+
+CAlarmSoundDlg::CAlarmSoundDlg(CWnd* pParent /*=NULL*/)
+       : CDialog(CAlarmSoundDlg::IDD, pParent)
+{
+       //{{AFX_DATA_INIT(CAlarmSoundDlg)
+       m_iSoundType = -1;
+       m_strSound1 = _T("");
+       m_strSound2 = _T("");
+       m_bIncludeSource = FALSE;
+       m_bIncludeSeverity = FALSE;
+       m_bIncludeMessage = FALSE;
+       m_bNotifyOnAck = FALSE;
+       //}}AFX_DATA_INIT
+}
+
+
+void CAlarmSoundDlg::DoDataExchange(CDataExchange* pDX)
+{
+       CDialog::DoDataExchange(pDX);
+       //{{AFX_DATA_MAP(CAlarmSoundDlg)
+       DDX_Radio(pDX, IDC_RADIO_NO_SOUND, m_iSoundType);
+       DDX_CBString(pDX, IDC_COMBO_SOUND1, m_strSound1);
+       DDV_MaxChars(pDX, m_strSound1, 255);
+       DDX_CBString(pDX, IDC_COMBO_SOUND2, m_strSound2);
+       DDV_MaxChars(pDX, m_strSound2, 255);
+       DDX_Check(pDX, IDC_CHECK_SOURCE, m_bIncludeSource);
+       DDX_Check(pDX, IDC_CHECK_SEVERITY, m_bIncludeSeverity);
+       DDX_Check(pDX, IDC_CHECK_MESSAGE, m_bIncludeMessage);
+       DDX_Check(pDX, IDC_CHECK_ACK, m_bNotifyOnAck);
+       //}}AFX_DATA_MAP
+}
+
+
+BEGIN_MESSAGE_MAP(CAlarmSoundDlg, CDialog)
+       //{{AFX_MSG_MAP(CAlarmSoundDlg)
+               // NOTE: the ClassWizard will add message map macros here
+       //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// CAlarmSoundDlg message handlers
diff --git a/src/console/nxuilib/AlarmSoundDlg.h b/src/console/nxuilib/AlarmSoundDlg.h
new file mode 100644 (file)
index 0000000..b3c3928
--- /dev/null
@@ -0,0 +1,52 @@
+#if !defined(AFX_ALARMSOUNDDLG_H__9EEE8F77_A307_48F1_8E49_152F5A9D01DE__INCLUDED_)
+#define AFX_ALARMSOUNDDLG_H__9EEE8F77_A307_48F1_8E49_152F5A9D01DE__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+// AlarmSoundDlg.h : header file
+//
+
+/////////////////////////////////////////////////////////////////////////////
+// CAlarmSoundDlg dialog
+
+class CAlarmSoundDlg : public CDialog
+{
+// Construction
+public:
+       CAlarmSoundDlg(CWnd* pParent = NULL);   // standard constructor
+
+// Dialog Data
+       //{{AFX_DATA(CAlarmSoundDlg)
+       enum { IDD = IDD_ALARM_SOUNDS };
+       int             m_iSoundType;
+       CString m_strSound1;
+       CString m_strSound2;
+       BOOL    m_bIncludeSource;
+       BOOL    m_bIncludeSeverity;
+       BOOL    m_bIncludeMessage;
+       BOOL    m_bNotifyOnAck;
+       //}}AFX_DATA
+
+
+// Overrides
+       // ClassWizard generated virtual function overrides
+       //{{AFX_VIRTUAL(CAlarmSoundDlg)
+       protected:
+       virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
+       //}}AFX_VIRTUAL
+
+// Implementation
+protected:
+
+       // Generated message map functions
+       //{{AFX_MSG(CAlarmSoundDlg)
+               // NOTE: the ClassWizard will add member functions here
+       //}}AFX_MSG
+       DECLARE_MESSAGE_MAP()
+};
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_ALARMSOUNDDLG_H__9EEE8F77_A307_48F1_8E49_152F5A9D01DE__INCLUDED_)
index c3ae12c..b2597c4 100644 (file)
@@ -10,6 +10,7 @@
 
 SUBDIRS = res
 EXTRA_DIST = \
+       AlarmSoundDlg.cpp AlarmSoundDlg.h \
        LoginDialog.cpp LoginDialog.h \
        nxuilib.clw \
        nxuilib.cpp \
index f5f1a85..b093bd5 100644 (file)
@@ -2,12 +2,15 @@
 
 [General Info]
 Version=1
-ClassCount=1
-ResourceCount=1
+ClassCount=2
+ResourceCount=2
 NewFileInclude1=#include "stdafx.h"
 Class1=CLoginDialog
-LastClass=CLoginDialog
+LastClass=CAlarmSoundDlg
 Resource1=IDD_LOGIN (English (U.S.))
+Class2=CAlarmSoundDlg
+LastTemplate=CDialog
+Resource2=IDD_ALARM_SOUNDS (English (U.S.))
 
 [DLG:IDD_LOGIN (English (U.S.))]
 Type=1
@@ -41,3 +44,35 @@ Filter=D
 LastObject=CLoginDialog
 VirtualFilter=dWC
 
+[DLG:IDD_ALARM_SOUNDS (English (U.S.))]
+Type=1
+Class=CAlarmSoundDlg
+ControlCount=18
+Control1=IDC_RADIO_NO_SOUND,button,1342373897
+Control2=IDC_RADIO_SOUND,button,1342242825
+Control3=IDC_COMBO_SOUND1,combobox,1344340226
+Control4=IDC_BROWSE_1,button,1342242816
+Control5=IDC_COMBO_SOUND2,combobox,1344340226
+Control6=IDC_BROWSE_2,button,1342242816
+Control7=IDC_CHECK_SEVERITY,button,1342242819
+Control8=IDC_CHECK_SOURCE,button,1342242819
+Control9=IDC_CHECK_MESSAGE,button,1342242819
+Control10=IDC_CHECK_ACK,button,1342252035
+Control11=IDOK,button,1342242817
+Control12=IDCANCEL,button,1342242816
+Control13=IDC_STATIC,static,1342308352
+Control14=IDC_RADIO_SPEECH,button,1342242825
+Control15=IDC_STATIC,static,1342308352
+Control16=IDC_STATIC,static,1342177296
+Control17=IDC_STATIC,static,1342177296
+Control18=IDC_STATIC,static,1342177296
+
+[CLS:CAlarmSoundDlg]
+Type=0
+HeaderFile=AlarmSoundDlg.h
+ImplementationFile=AlarmSoundDlg.cpp
+BaseClass=CDialog
+Filter=D
+LastObject=CAlarmSoundDlg
+VirtualFilter=dWC
+
index 90ab981..b3351d7 100644 (file)
@@ -97,6 +97,10 @@ PostBuild_Cmds=copy Debug\nxuilib.dll ..\..\..\bin
 # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
 # Begin Source File
 
+SOURCE=.\AlarmSoundDlg.cpp
+# End Source File
+# Begin Source File
+
 SOURCE=.\LoginDialog.cpp
 # End Source File
 # Begin Source File
@@ -130,6 +134,10 @@ SOURCE=.\tools.cpp
 # PROP Default_Filter "h;hpp;hxx;hm;inl"
 # Begin Source File
 
+SOURCE=.\AlarmSoundDlg.h
+# End Source File
+# Begin Source File
+
 SOURCE=.\LoginDialog.h
 # End Source File
 # Begin Source File
index 999651b..511a1e9 100644 (file)
@@ -105,6 +105,41 @@ BEGIN
     LTEXT           "Options",IDC_STATIC,7,134,25,8
 END
 
+IDD_ALARM_SOUNDS DIALOG DISCARDABLE  0, 0, 175, 214
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Alarm Sounds Configuration"
+FONT 8, "MS Sans Serif"
+BEGIN
+    CONTROL         "&No alarm sounds",IDC_RADIO_NO_SOUND,"Button",
+                    BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,7,7,69,10
+    CONTROL         "&Play sound",IDC_RADIO_SOUND,"Button",
+                    BS_AUTORADIOBUTTON | WS_TABSTOP,7,21,51,10
+    COMBOBOX        IDC_COMBO_SOUND1,25,47,125,66,CBS_DROPDOWN | CBS_SORT | 
+                    WS_VSCROLL | WS_TABSTOP
+    PUSHBUTTON      "...",IDC_BROWSE_1,154,46,14,12
+    COMBOBOX        IDC_COMBO_SOUND2,25,79,125,75,CBS_DROPDOWN | CBS_SORT | 
+                    WS_VSCROLL | WS_TABSTOP
+    PUSHBUTTON      "...",IDC_BROWSE_2,154,78,14,12
+    CONTROL         "Include &severity",IDC_CHECK_SEVERITY,"Button",
+                    BS_AUTOCHECKBOX | WS_TABSTOP,25,115,65,10
+    CONTROL         "Include s&ource",IDC_CHECK_SOURCE,"Button",
+                    BS_AUTOCHECKBOX | WS_TABSTOP,25,129,63,10
+    CONTROL         "Include &message",IDC_CHECK_MESSAGE,"Button",
+                    BS_AUTOCHECKBOX | WS_TABSTOP,25,143,69,10
+    CONTROL         "Play notification when alarm being acknowleged",
+                    IDC_CHECK_ACK,"Button",BS_AUTOCHECKBOX | BS_TOP | 
+                    BS_MULTILINE | WS_TABSTOP,25,156,143,17
+    DEFPUSHBUTTON   "OK",IDOK,62,193,50,14
+    PUSHBUTTON      "Cancel",IDCANCEL,118,193,50,14
+    LTEXT           "When new alarm arrives:",IDC_STATIC,25,36,79,8
+    CONTROL         "Use &voice notifications",IDC_RADIO_SPEECH,"Button",
+                    BS_AUTORADIOBUTTON | WS_TABSTOP,7,100,87,10
+    LTEXT           "When alarm being acknowleged:",IDC_STATIC,25,68,105,8
+    CONTROL         "",IDC_STATIC,"Static",SS_ETCHEDHORZ,57,26,111,1
+    CONTROL         "",IDC_STATIC,"Static",SS_ETCHEDHORZ,94,105,74,1
+    CONTROL         "",IDC_STATIC,"Static",SS_ETCHEDHORZ,7,182,161,1
+END
+
 
 /////////////////////////////////////////////////////////////////////////////
 //
@@ -128,6 +163,14 @@ BEGIN
         TOPMARGIN, 7
         BOTTOMMARGIN, 210
     END
+
+    IDD_ALARM_SOUNDS, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 168
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 207
+    END
 END
 #endif    // APSTUDIO_INVOKED
 
index d99b9cc..5928865 100644 (file)
 #define IDC_CHECK_VERSION_MATCH         5007
 #define IDC_CHECK_NOCACHE               5008
 #define IDC_CHECK_ENCRYPT               5009
+#define IDD_ALARM_SOUNDS                5010
+#define IDC_RADIO_NO_SOUND              5200
+#define IDC_RADIO_SOUND                 5201
+#define IDC_COMBO_SOUND1                5202
+#define IDC_RADIO_SPEECH                5203
+#define IDC_CHECK_SEVERITY              5204
+#define IDC_CHECK_SOURCE                5205
+#define IDC_CHECK_MESSAGE               5206
+#define IDC_BROWSE_1                    5207
+#define IDC_COMBO_SOUND2                5208
+#define IDC_BROWSE_2                    5209
+#define IDC_CHECK_ACK                   5211
 
 // Next default values for new objects
 // 
 #ifdef APSTUDIO_INVOKED
 #ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE        5010
+#define _APS_NEXT_RESOURCE_VALUE        5011
 #define _APS_NEXT_COMMAND_VALUE         28000
-#define _APS_NEXT_CONTROL_VALUE         5200
+#define _APS_NEXT_CONTROL_VALUE         5212
 #define _APS_NEXT_SYMED_VALUE           5700
 #endif
 #endif
index 4db6638..54389a4 100644 (file)
@@ -651,7 +651,7 @@ int LIBNETXMS_EXPORTABLE NxDCIDataTypeFromText(TCHAR *pszText)
 // cannot handle them all
 //
 
-int LIBNETXMS_EXPORTABLE SendEx(int nSocket, const void *pBuff,
+int LIBNETXMS_EXPORTABLE SendEx(SOCKET nSocket, const void *pBuff,
                                          size_t nSize, int nFlags)
 {
        int nLeft = nSize;
@@ -671,6 +671,53 @@ int LIBNETXMS_EXPORTABLE SendEx(int nSocket, const void *pBuff,
 }
 
 
+//
+// Extended recv() - receive data with timeout
+//
+
+int LIBNETXMS_EXPORTABLE RecvEx(SOCKET nSocket, const void *pBuff,
+                                size_t nSize, int nFlags, DWORD dwTimeout)
+{
+   int iErr;
+#if HAVE_POLL
+   struct pollfd fds;
+#else
+   struct timeval tv;
+   fd_set rdfs;
+#endif
+
+   if (dwTimeout > 0)
+   {
+#if HAVE_POLL
+      fds.fd = nSocket;
+      fds.events = POLLIN;
+      fds.revents = POLLIN;
+          iErr = poll(&fds, 1, dwTimeout);
+#else
+          FD_ZERO(&rdfs);
+          FD_SET(nSocket, &rdfs);
+      tv.tv_sec = dwTimeout / 1000;
+      tv.tv_usec = (dwTimeout % 1000) * 1000;
+      iErr = select(nSocket + 1, &rdfs, NULL, NULL, &tv);
+#endif
+      if (iErr > 0)
+      {
+         iErr = recv(nSocket, (char *)pBuff, nSize, nFlags);
+      }
+      else
+      {
+         iErr = -2;
+      }
+   }
+   else
+   {
+      iErr = recv(nSocket, (char *)pBuff, nSize, nFlags);
+   }
+
+   return iErr;
+}
+
+
 //
 // Resolve host name to IP address
 //
index e172148..3809a6b 100644 (file)
@@ -40,7 +40,7 @@ THREAD_RESULT THREAD_CALL NetReceiver(NXCL_Session *pSession)
 
    // Initialize raw message receiving function
    pMsgBuffer = (CSCP_BUFFER *)malloc(sizeof(CSCP_BUFFER));
-   RecvCSCPMessage(0, NULL, pMsgBuffer, 0, NULL, NULL);
+   RecvCSCPMessage(0, NULL, pMsgBuffer, 0, NULL, NULL, 0);
 
    // Allocate space for raw message
    pRawMsg = (CSCP_MESSAGE *)malloc(pSession->m_dwReceiverBufferSize);
@@ -54,7 +54,7 @@ THREAD_RESULT THREAD_CALL NetReceiver(NXCL_Session *pSession)
       // Receive raw message
       if ((iErr = RecvCSCPMessage(pSession->m_hSocket, pRawMsg, 
                                   pMsgBuffer, pSession->m_dwReceiverBufferSize,
-                                  &pSession->m_pCtx, pDecryptionBuffer)) <= 0)
+                                  &pSession->m_pCtx, pDecryptionBuffer, 0)) <= 0)
          break;
 
       // Check if we get too large message
index cdb3b21..8f44cf7 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: admin.cpp,v 1.12 2005-08-17 12:09:25 victor Exp $ */
+/* $Id: admin.cpp,v 1.13 2005-12-03 22:53:04 victor Exp $ */
 
 /* 
 ** NetXMS - Network Management System
@@ -50,13 +50,13 @@ static THREAD_RESULT THREAD_CALL ProcessingThread(void *pArg)
 
    pRawMsg = (CSCP_MESSAGE *)malloc(MAX_MSG_SIZE);
    pRecvBuffer = (CSCP_BUFFER *)malloc(sizeof(CSCP_BUFFER));
-   RecvCSCPMessage(0, NULL, pRecvBuffer, 0, NULL, NULL);
+   RecvCSCPMessage(0, NULL, pRecvBuffer, 0, NULL, NULL, 0);
    ctx.hSocket = sock;
    ctx.pMsg = &response;
 
    while(1)
    {
-      iError = RecvCSCPMessage(sock, pRawMsg, pRecvBuffer, MAX_MSG_SIZE, &pDummyCtx, NULL);
+      iError = RecvCSCPMessage(sock, pRawMsg, pRecvBuffer, MAX_MSG_SIZE, &pDummyCtx, NULL, 0);
       if (iError <= 0)
          break;   // Communication error or closed connection
 
@@ -164,6 +164,9 @@ THREAD_RESULT THREAD_CALL LocalAdminListener(void *pArg)
 /*
 
 $Log: not supported by cvs2svn $
+Revision 1.12  2005/08/17 12:09:25  victor
+responce changed to response (issue #37)
+
 Revision 1.11  2005/06/19 21:39:20  victor
 Encryption between server and agent fully working
 
index e9237c2..04e140f 100644 (file)
@@ -287,7 +287,7 @@ void ClientSession::ReadThread(void)
    WORD wFlags;
 
    // Initialize raw message receiving function
-   RecvCSCPMessage(0, NULL, m_pMsgBuffer, 0, NULL, NULL);
+   RecvCSCPMessage(0, NULL, m_pMsgBuffer, 0, NULL, NULL, 0);
 
    pRawMsg = (CSCP_MESSAGE *)malloc(RAW_MSG_SIZE);
 #ifdef _WITH_ENCRYPTION
@@ -297,7 +297,7 @@ void ClientSession::ReadThread(void)
    {
       if ((iErr = RecvCSCPMessage(m_hSocket, pRawMsg, 
                                   m_pMsgBuffer, RAW_MSG_SIZE, 
-                                  &m_pCtx, pDecryptionBuffer)) <= 0)
+                                  &m_pCtx, pDecryptionBuffer, 0)) <= 0)
          break;
 
       // Check if message is too large
index e0afd45..54f6e1c 100644 (file)
@@ -209,6 +209,7 @@ private:
    DWORD m_dwNumDataLines;
    DWORD m_dwRequestId;
    DWORD m_dwCommandTimeout;
+   DWORD m_dwRecvTimeout;
    TCHAR **m_ppDataLines;
    MsgWaitQueue *m_pMsgWaitQueue;
    BOOL m_bIsConnected;
@@ -269,6 +270,7 @@ public:
    const TCHAR *GetDataLine(DWORD dwIndex) { return dwIndex < m_dwNumDataLines ? m_ppDataLines[dwIndex] : _T("(error)"); }
 
    void SetCommandTimeout(DWORD dwTimeout) { if (dwTimeout > 500) m_dwCommandTimeout = dwTimeout; }
+   void SetRecvTimeout(DWORD dwTimeout) { if (dwTimeout > 10000) m_dwRecvTimeout = dwTimeout; }
    void SetEncryptionPolicy(int iPolicy) { m_iEncryptionPolicy = iPolicy; }
    void SetProxy(DWORD dwAddr, WORD wPort = AGENT_LISTEN_PORT,
                  int iAuthMethod = AUTH_NONE, TCHAR *pszSecret = NULL);
index 758ca06..4b46c5f 100644 (file)
@@ -89,6 +89,7 @@ AgentConnection::AgentConnection()
    m_pCtx = NULL;
    m_iEncryptionPolicy = m_iDefaultEncryptionPolicy;
    m_bUseProxy = FALSE;
+   m_dwRecvTimeout = 420000;  // 7 minutes
 }
 
 
@@ -128,6 +129,7 @@ AgentConnection::AgentConnection(DWORD dwAddr, WORD wPort,
    m_pCtx = NULL;
    m_iEncryptionPolicy = m_iDefaultEncryptionPolicy;
    m_bUseProxy = FALSE;
+   m_dwRecvTimeout = 420000;  // 7 minutes
 }
 
 
@@ -187,7 +189,7 @@ void AgentConnection::ReceiverThread(void)
 
    // Initialize raw message receiving function
    pMsgBuffer = (CSCP_BUFFER *)malloc(sizeof(CSCP_BUFFER));
-   RecvCSCPMessage(0, NULL, pMsgBuffer, 0, NULL, NULL);
+   RecvCSCPMessage(0, NULL, pMsgBuffer, 0, NULL, NULL, 0);
 
    // Allocate space for raw message
    pRawMsg = (CSCP_MESSAGE *)malloc(RECEIVER_BUFFER_SIZE);
@@ -200,7 +202,7 @@ void AgentConnection::ReceiverThread(void)
    {
       // Receive raw message
       if ((iErr = RecvCSCPMessage(m_hSocket, pRawMsg, pMsgBuffer, RECEIVER_BUFFER_SIZE,
-                                  &m_pCtx, pDecryptionBuffer)) <= 0)
+                                  &m_pCtx, pDecryptionBuffer, m_dwRecvTimeout)) <= 0)
          break;
 
       // Check if we get too large message
@@ -219,6 +221,13 @@ void AgentConnection::ReceiverThread(void)
          continue;
       }
 
+      // Check for timeout
+      if (iErr == 3)
+      {
+         PrintMsg(_T("Timed out waiting for message"));
+         break;
+      }
+
       // Check that actual received packet size is equal to encoded in packet
       if ((int)ntohl(pRawMsg->dwSize) != iErr)
       {