4a221000f3d9fc43db70a22d1e0c8393c321de6e
[public/netxms.git] / src / libnxcl / events.cpp
1 /*
2 ** NetXMS - Network Management System
3 ** Client Library
4 ** Copyright (C) 2004, 2005, 2006, 2007 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 ** File: events.cpp
21 **
22 **/
23
24 #include "libnxcl.h"
25
26
27 //
28 // Process events coming from server
29 //
30
31 void ProcessEvent(NXCL_Session *pSession, CSCPMessage *pMsg, CSCP_MESSAGE *pRawMsg)
32 {
33 WORD wCode;
34 #ifdef UNICODE
35 WCHAR *pSrc, *pDst;
36 #endif
37
38 wCode = (pMsg != NULL) ? pMsg->GetCode() : pRawMsg->wCode;
39
40 switch(wCode)
41 {
42 case CMD_EVENT_LIST_END:
43 pSession->CompleteSync(SYNC_EVENTS, RCC_SUCCESS);
44 break;
45 case CMD_EVENT:
46 if (pRawMsg != NULL) // We should receive events as raw data
47 {
48 NXC_EVENT event;
49
50 // Fill event structure with values from message
51 event.dwEventCode = ntohl(((NXC_EVENT *)pRawMsg->df)->dwEventCode);
52 event.qwEventId = ntohq(((NXC_EVENT *)pRawMsg->df)->qwEventId);
53 event.dwSeverity = ntohl(((NXC_EVENT *)pRawMsg->df)->dwSeverity);
54 event.dwSourceId = ntohl(((NXC_EVENT *)pRawMsg->df)->dwSourceId);
55 event.dwTimeStamp = ntohl(((NXC_EVENT *)pRawMsg->df)->dwTimeStamp);
56
57 // Convert bytes in message characters to host byte order
58 // and than to single-byte if we building non-unicode library
59 #ifdef UNICODE
60 #if WORDS_BIGENDIAN
61 memcpy(event.szMessage, ((NXC_EVENT *)pRawMsg->df)->szMessage,
62 MAX_EVENT_MSG_LENGTH * sizeof(WCHAR));
63 #else
64 for(pSrc = ((NXC_EVENT *)pRawMsg->df)->szMessage,
65 pDst = event.szMessage; *pSrc != 0; pSrc++, pDst++)
66 *pDst = ntohs(*pSrc);
67 *pDst = ntohs(*pSrc);
68 #endif
69 #else
70 SwapWideString((WCHAR *)((NXC_EVENT *)pRawMsg->df)->szMessage);
71 WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK | WC_DEFAULTCHAR,
72 (WCHAR *)((NXC_EVENT *)pRawMsg->df)->szMessage, -1,
73 event.szMessage, MAX_EVENT_MSG_LENGTH, NULL, NULL);
74 event.szMessage[MAX_EVENT_MSG_LENGTH - 1] = 0;
75 #endif
76
77 // Call client's callback to handle new record
78 pSession->CallEventHandler(NXC_EVENT_NEW_ELOG_RECORD,
79 (pRawMsg->wFlags & MF_REVERSE_ORDER) ?
80 RECORD_ORDER_REVERSED : RECORD_ORDER_NORMAL,
81 &event);
82 }
83 break;
84 default:
85 break;
86 }
87 }
88
89
90 //
91 // Synchronize event log
92 // This function is NOT REENTRANT
93 //
94
95 DWORD LIBNXCL_EXPORTABLE NXCSyncEvents(NXC_SESSION hSession, DWORD dwMaxRecords)
96 {
97 CSCPMessage msg;
98 DWORD dwRetCode, dwRqId;
99
100 dwRqId = ((NXCL_Session *)hSession)->CreateRqId();
101 ((NXCL_Session *)hSession)->PrepareForSync(SYNC_EVENTS);
102
103 msg.SetCode(CMD_GET_EVENTS);
104 msg.SetId(dwRqId);
105 msg.SetVariable(VID_MAX_RECORDS, dwMaxRecords);
106 ((NXCL_Session *)hSession)->SendMsg(&msg);
107
108 dwRetCode = ((NXCL_Session *)hSession)->WaitForRCC(dwRqId);
109 if (dwRetCode == RCC_SUCCESS)
110 dwRetCode = ((NXCL_Session *)hSession)->WaitForSync(SYNC_EVENTS, INFINITE);
111 else
112 ((NXCL_Session *)hSession)->UnlockSyncOp(SYNC_EVENTS);
113
114 return dwRetCode;
115 }
116
117
118 //
119 // Send event to server
120 //
121
122 DWORD LIBNXCL_EXPORTABLE NXCSendEvent(NXC_SESSION hSession, DWORD dwEventCode,
123 DWORD dwObjectId, int iNumArgs, TCHAR **pArgList,
124 TCHAR *pszUserTag)
125 {
126 CSCPMessage msg;
127 DWORD dwRqId;
128 int i;
129
130 dwRqId = ((NXCL_Session *)hSession)->CreateRqId();
131
132 msg.SetCode(CMD_TRAP);
133 msg.SetId(dwRqId);
134 msg.SetVariable(VID_EVENT_CODE, dwEventCode);
135 msg.SetVariable(VID_OBJECT_ID, dwObjectId);
136 msg.SetVariable(VID_USER_TAG, CHECK_NULL_EX(pszUserTag));
137 msg.SetVariable(VID_NUM_ARGS, (WORD)iNumArgs);
138 for(i = 0; i < iNumArgs; i++)
139 msg.SetVariable(VID_EVENT_ARG_BASE + i, pArgList[i]);
140 ((NXCL_Session *)hSession)->SendMsg(&msg);
141
142 return ((NXCL_Session *)hSession)->WaitForRCC(dwRqId);
143 }
144
145
146 //
147 // Process syslog records coming from server
148 //
149
150 void ProcessSyslogRecords(NXCL_Session *pSession, CSCPMessage *pMsg)
151 {
152 DWORD i, dwNumRecords, dwId;
153 NXC_SYSLOG_RECORD rec;
154 int nOrder;
155
156 dwNumRecords = pMsg->GetVariableLong(VID_NUM_RECORDS);
157 nOrder = (int)pMsg->GetVariableShort(VID_RECORDS_ORDER);
158 DebugPrintf(_T("ProcessSyslogRecords(): %d records in message, in %s order"),
159 dwNumRecords, (nOrder == RECORD_ORDER_NORMAL) ? _T("normal") : _T("reversed"));
160 for(i = 0, dwId = VID_SYSLOG_MSG_BASE; i < dwNumRecords; i++)
161 {
162 rec.qwMsgId = pMsg->GetVariableInt64(dwId++);
163 rec.dwTimeStamp = pMsg->GetVariableLong(dwId++);
164 rec.wFacility = pMsg->GetVariableShort(dwId++);
165 rec.wSeverity = pMsg->GetVariableShort(dwId++);
166 rec.dwSourceObject = pMsg->GetVariableLong(dwId++);
167 pMsg->GetVariableStr(dwId++, rec.szHost, MAX_SYSLOG_HOSTNAME_LEN);
168 pMsg->GetVariableStr(dwId++, rec.szTag, MAX_SYSLOG_TAG_LEN);
169 rec.pszText = pMsg->GetVariableStr(dwId++);
170
171 // Call client's callback to handle new record
172 pSession->CallEventHandler(NXC_EVENT_NEW_SYSLOG_RECORD, nOrder, &rec);
173 free(rec.pszText);
174 }
175
176 // Notify requestor thread if all messages was received
177 if (pMsg->IsEndOfSequence())
178 pSession->CompleteSync(SYNC_SYSLOG, RCC_SUCCESS);
179 }
180
181
182 //
183 // Synchronize syslog
184 // This function is NOT REENTRANT
185 //
186
187 DWORD LIBNXCL_EXPORTABLE NXCSyncSyslog(NXC_SESSION hSession, DWORD dwMaxRecords)
188 {
189 CSCPMessage msg;
190 DWORD dwRetCode, dwRqId;
191
192 dwRqId = ((NXCL_Session *)hSession)->CreateRqId();
193 ((NXCL_Session *)hSession)->PrepareForSync(SYNC_SYSLOG);
194
195 msg.SetCode(CMD_GET_SYSLOG);
196 msg.SetId(dwRqId);
197 msg.SetVariable(VID_MAX_RECORDS, dwMaxRecords);
198 ((NXCL_Session *)hSession)->SendMsg(&msg);
199
200 dwRetCode = ((NXCL_Session *)hSession)->WaitForRCC(dwRqId);
201 if (dwRetCode == RCC_SUCCESS)
202 dwRetCode = ((NXCL_Session *)hSession)->WaitForSync(SYNC_SYSLOG, INFINITE);
203 else
204 ((NXCL_Session *)hSession)->UnlockSyncOp(SYNC_SYSLOG);
205
206 return dwRetCode;
207 }