Event log sending changed to use raw data messages
[public/netxms.git] / src / libnxcl / comm.cpp
CommitLineData
05d9bba3
VK
1/*
2** NetXMS - Network Management System
3** Client Library
4** Copyright (C) 2004 Victor Kirhenshtein
5**
6** This program is free software; you can redistribute it and/or modify
7** it under the terms of the GNU General Public License as published by
8** the Free Software Foundation; either version 2 of the License, or
9** (at your option) any later version.
10**
11** This program is distributed in the hope that it will be useful,
12** but WITHOUT ANY WARRANTY; without even the implied warranty of
13** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14** GNU General Public License for more details.
15**
16** You should have received a copy of the GNU General Public License
17** along with this program; if not, write to the Free Software
18** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19**
20** $module: comm.cpp
21**
22**/
23
24#include "libnxcl.h"
25
26
27//
28// Static data
29//
30
31static SOCKET m_hSocket = -1;
32static DWORD m_dwMsgId;
33static char m_szServer[MAX_SERVER_NAME];
34static char m_szLogin[MAX_LOGIN_NAME];
35static char m_szPassword[MAX_PASSWORD_LEN];
36static MsgWaitQueue m_msgWaitQueue;
37
38
39//
40// Send raw message
41//
42
43static BOOL SendRawMsg(CSCP_MESSAGE *pMsg)
44{
45 return send(m_hSocket, (char *)pMsg, ntohs(pMsg->wSize), 0) == (int)ntohs(pMsg->wSize);
46}
47
48
49//
50// Send message
51//
52
53BOOL SendMsg(CSCPMessage *pMsg)
54{
55 CSCP_MESSAGE *pRawMsg;
56 BOOL bResult;
57
58 pRawMsg = pMsg->CreateMessage();
59 bResult = SendRawMsg(pRawMsg);
5b9ed9ac 60 MemFree(pRawMsg);
05d9bba3
VK
61 return bResult;
62}
63
64
65//
66// Network receiver thread
67//
68
69static void NetReceiver(void *pArg)
70{
71 CSCPMessage *pMsg;
72 CSCP_MESSAGE *pRawMsg;
73 CSCP_BUFFER *pMsgBuffer;
74 int iErr;
75
76 // Initialize raw message receiving function
5b9ed9ac 77 pMsgBuffer = (CSCP_BUFFER *)MemAlloc(sizeof(CSCP_BUFFER));
05d9bba3
VK
78 RecvCSCPMessage(0, NULL, pMsgBuffer);
79
80 // Allocate space for raw message
5b9ed9ac 81 pRawMsg = (CSCP_MESSAGE *)MemAlloc(65536);
05d9bba3
VK
82
83 // Message receiving loop
84 while(1)
85 {
86 // Receive raw message
87 if ((iErr = RecvCSCPMessage(m_hSocket, pRawMsg, pMsgBuffer)) <= 0)
88 break;
89
90 // Check that actual received packet size is equal to encoded in packet
91 if (ntohs(pRawMsg->wSize) != iErr)
92 {
93 DebugPrintf("RECV_MSG: Bad packet length [wSize=%d ActualSize=%d]", ntohs(pRawMsg->wSize), iErr);
94 continue; // Bad packet, wait for next
95 }
96
97 // Create message object from raw message
98 pMsg = new CSCPMessage(pRawMsg);
99 DebugPrintf("RECV_MSG: Code=%d ID=%d", pMsg->GetCode(), pMsg->GetId());
100
101 // Process message
102 switch(pMsg->GetCode())
103 {
104 case CMD_KEEPALIVE: // Keepalive message, ignore it
105 delete pMsg;
106 break;
107 case CMD_OBJECT: // Object information
108 case CMD_OBJECT_LIST_END:
109 ProcessObjectUpdate(pMsg);
110 delete pMsg;
111 break;
5b9ed9ac
VK
112 case CMD_EVENT: // Event information
113 case CMD_EVENT_LIST_END:
114 ProcessEvent(pMsg);
115 delete pMsg;
116 break;
05d9bba3
VK
117 default:
118 m_msgWaitQueue.Put(pMsg);
119 break;
120 }
121 }
122
123 ChangeState(STATE_DISCONNECTED);
5b9ed9ac
VK
124 MemFree(pRawMsg);
125 MemFree(pMsgBuffer);
05d9bba3
VK
126}
127
128
129//
130// Connect to server
131//
132
133BOOL Connect(void)
134{
135 struct sockaddr_in servAddr;
136 CSCPMessage msg, *pResp;
137 BOOL bSuccess;
138
139 ChangeState(STATE_CONNECTING);
140
141 // Reset unique message ID
142 m_dwMsgId = 1;
143
144 // Prepare address structure
145 memset(&servAddr, 0, sizeof(struct sockaddr_in));
146 servAddr.sin_family = AF_INET;
147 servAddr.sin_addr.s_addr = inet_addr(m_szServer);
148 if (servAddr.sin_addr.s_addr == INADDR_NONE)
149 {
150 struct hostent *hs;
151
152 hs = gethostbyname(m_szServer);
153 if (hs == NULL)
154 {
155 return FALSE; // Unable to resolve host name
156 }
157 else
158 {
159 memcpy(&servAddr.sin_addr, hs->h_addr, hs->h_length);
160 }
161 }
162 servAddr.sin_port = htons((WORD)SERVER_LISTEN_PORT);
163
164 // Create socket
165 if ((m_hSocket = socket(AF_INET, SOCK_STREAM, 0)) == -1)
166 {
167 return FALSE;
168 }
169
170 // Connect to target
171 if (connect(m_hSocket, (struct sockaddr *)&servAddr, sizeof(struct sockaddr_in)) != 0)
172 {
173 closesocket(m_hSocket);
174 m_hSocket = -1;
175 return FALSE;
176 }
177
178 // Start receiver thread
179 ThreadCreate(NetReceiver, 0, NULL);
180
181 // Prepare login message
182 msg.SetId(m_dwMsgId++);
183 msg.SetCode(CMD_LOGIN);
a5f8dbb8
VK
184 msg.SetVariable(VID_LOGIN_NAME, m_szLogin);
185 msg.SetVariable(VID_PASSWORD, m_szPassword);
05d9bba3
VK
186
187 if (!SendMsg(&msg))
188 {
189 // Message send failed, drop connection
190 shutdown(m_hSocket, 2);
191 closesocket(m_hSocket);
192 m_hSocket = -1;
193 return FALSE;
194 }
195
196 // Receive responce message
197 pResp = m_msgWaitQueue.WaitForMessage(CMD_LOGIN_RESP, msg.GetId(), 2000);
198 if (pResp == NULL) // Connection is broken or timed out
199 {
200 shutdown(m_hSocket, 2);
201 closesocket(m_hSocket);
202 m_hSocket = -1;
203 return FALSE;
204 }
205
a5f8dbb8 206 bSuccess = pResp->GetVariableLong(VID_LOGIN_RESULT);
05d9bba3
VK
207 delete pResp;
208
209 CallEventHandler(NXC_EVENT_LOGIN_RESULT, bSuccess, NULL);
210 if (!bSuccess)
211 {
212 shutdown(m_hSocket, 2);
213 closesocket(m_hSocket);
214 m_hSocket = -1;
215 }
216 return bSuccess;
217}
218
219
220//
221// Initiate connection to server
222//
223
224BOOL EXPORTABLE NXCConnect(char *szServer, char *szLogin, char *szPassword)
225{
226 if (g_dwState != STATE_DISCONNECTED)
227 return FALSE;
228
229 strcpy(m_szServer, szServer);
230 strcpy(m_szLogin, szLogin);
231 strcpy(m_szPassword, szPassword);
232
233 CreateRequest(RQ_CONNECT, NULL, FALSE);
234
235 return TRUE;
236}
237
238
239//
240// Disconnect from server
241//
242
243void EXPORTABLE NXCDisconnect(void)
244{
245 // Close socket
246 shutdown(m_hSocket, 2);
247 closesocket(m_hSocket);
248
249 // Clear message wait queue
250 m_msgWaitQueue.Clear();
251}