fixed broken non-unicode build
[public/netxms.git] / src / agent / core / trap.cpp
CommitLineData
5039dede
AK
1/*
2** NetXMS multiplatform core agent
0137b9f7 3** Copyright (C) 2003-2013 Victor Kirhenshtein
5039dede
AK
4**
5** This program is free software; you can redistribute it and/or modify
6** it under the terms of the GNU General Public License as published by
7** the Free Software Foundation; either version 2 of the License, or
8** (at your option) any later version.
9**
10** This program is distributed in the hope that it will be useful,
11** but WITHOUT ANY WARRANTY; without even the implied warranty of
12** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13** GNU General Public License for more details.
14**
15** You should have received a copy of the GNU General Public License
16** along with this program; if not, write to the Free Software
17** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18**
19** File: trap.cpp
20**
21**/
22
23#include "nxagentd.h"
24#include <stdarg.h>
25
0137b9f7
VK
26/**
27 * Static data
28 */
7f78ab75 29static Queue *s_trapQueue = NULL;
06debb26
VK
30static UINT64 s_genTrapCount = 0; // Number of generated traps
31static UINT64 s_sentTrapCount = 0; // Number of sent traps
32static UINT64 s_trapIdBase = 0;
33static VolatileCounter s_trapIdCounter = 0;
7f78ab75 34static time_t s_lastTrapTime = 0;
5039dede 35
0137b9f7
VK
36/**
37 * Trap sender
38 */
5039dede
AK
39THREAD_RESULT THREAD_CALL TrapSender(void *pArg)
40{
b368969c 41 NXCP_MESSAGE *pMsg;
967893bb 42 UINT32 i;
0137b9f7 43 bool trapSent;
5039dede 44
7f78ab75 45 s_trapQueue = new Queue;
06debb26 46 s_trapIdBase = (QWORD)time(NULL) << 32;
5039dede
AK
47 while(1)
48 {
19dbc8ef 49 pMsg = (NXCP_MESSAGE *)s_trapQueue->getOrBlock();
5039dede
AK
50 if (pMsg == INVALID_POINTER_VALUE)
51 break;
52
0137b9f7 53 trapSent = false;
5039dede 54
0137b9f7
VK
55 if (g_dwFlags & AF_SUBAGENT_LOADER)
56 {
57 trapSent = SendRawMessageToMasterAgent(pMsg);
58 }
59 else
60 {
61 MutexLock(g_hSessionListAccess);
62 for(i = 0; i < g_dwMaxSessions; i++)
63 if (g_pSessionList[i] != NULL)
64 if (g_pSessionList[i]->canAcceptTraps())
65 {
66 g_pSessionList[i]->sendRawMessage(pMsg);
67 trapSent = true;
68 }
69 MutexUnlock(g_hSessionListAccess);
70 }
5039dede 71
0137b9f7 72 if (trapSent)
5039dede
AK
73 {
74 free(pMsg);
7f78ab75 75 s_sentTrapCount++;
5039dede
AK
76 }
77 else
78 {
19dbc8ef 79 s_trapQueue->insert(pMsg); // Re-queue trap
5039dede
AK
80 ThreadSleep(1);
81 }
82 }
7f78ab75
VK
83 delete s_trapQueue;
84 s_trapQueue = NULL;
c303351c 85 DebugPrintf(INVALID_INDEX, 1, _T("Trap sender thread terminated"));
5039dede
AK
86 return THREAD_OK;
87}
88
fcec42a9
VK
89/**
90 * Shutdown trap sender
91 */
5039dede
AK
92void ShutdownTrapSender()
93{
19dbc8ef 94 s_trapQueue->setShutdownMode();
5039dede
AK
95}
96
fcec42a9
VK
97/**
98 * Send trap to server
99 */
967893bb 100void SendTrap(UINT32 dwEventCode, const TCHAR *eventName, int iNumArgs, TCHAR **ppArgList)
5039dede
AK
101{
102 int i;
b368969c 103 NXCPMessage msg;
5039dede 104
2dd24569
VK
105 DebugPrintf(INVALID_INDEX, 5, _T("SendTrap(): event_code=%d, event_name=%s, num_args=%d, arg[0]=\"%s\" arg[1]=\"%s\" arg[2]=\"%s\""),
106 dwEventCode, CHECK_NULL(eventName), iNumArgs,
9fcdfda7
VK
107 (iNumArgs > 0) ? ppArgList[0] : _T("(null)"),
108 (iNumArgs > 1) ? ppArgList[1] : _T("(null)"),
109 (iNumArgs > 2) ? ppArgList[2] : _T("(null)"));
110
b368969c
VK
111 msg.setCode(CMD_TRAP);
112 msg.setId(0);
06debb26 113 msg.setField(VID_TRAP_ID, s_trapIdBase | (UINT64)InterlockedIncrement(&s_trapIdCounter));
b368969c 114 msg.setField(VID_EVENT_CODE, dwEventCode);
2dd24569 115 if (eventName != NULL)
b368969c
VK
116 msg.setField(VID_EVENT_NAME, eventName);
117 msg.setField(VID_NUM_ARGS, (WORD)iNumArgs);
5039dede 118 for(i = 0; i < iNumArgs; i++)
b368969c 119 msg.setField(VID_EVENT_ARG_BASE + i, ppArgList[i]);
7f78ab75
VK
120 if (s_trapQueue != NULL)
121 {
122 s_genTrapCount++;
123 s_lastTrapTime = time(NULL);
19dbc8ef 124 s_trapQueue->put(msg.createMessage());
7f78ab75 125 }
5039dede
AK
126}
127
5c44534b
VK
128/**
129 * Send trap - variant 2
130 * Arguments:
131 * dwEventCode - Event code
132 * eventName - event name; to send event by name, eventCode must be set to 0
133 * pszFormat - Parameter format string, each parameter represented by one character.
134 * The following format characters can be used:
135 * s - String
72a6d469 136 * m - Multibyte (non-UNICODE) string
5c44534b
VK
137 * d - Decimal integer
138 * x - Hex integer
139 * a - IP address
140 * i - Object ID
141 * D - 64-bit decimal integer
142 * X - 64-bit hex integer
143 */
967893bb 144void SendTrap(UINT32 dwEventCode, const TCHAR *eventName, const char *pszFormat, va_list args)
5039dede
AK
145{
146 int i, iNumArgs;
147 TCHAR *ppArgList[64];
148 static TCHAR badFormat[] = _T("BAD FORMAT");
149
150 iNumArgs = (pszFormat == NULL) ? 0 : (int)strlen(pszFormat);
151 for(i = 0; i < iNumArgs; i++)
152 {
153 switch(pszFormat[i])
154 {
155 case 's':
156 ppArgList[i] = va_arg(args, TCHAR *);
5039dede 157 break;
72a6d469 158 case 'm':
6a5c95f5 159#ifdef UNICODE
72a6d469 160 ppArgList[i] = WideStringFromMBString(va_arg(args, char *));
6a5c95f5
VK
161#else
162 ppArgList[i] = va_arg(args, char *);
163#endif
72a6d469 164 break;
5039dede 165 case 'd':
cb5360cc 166 ppArgList[i] = (TCHAR *)malloc(16 * sizeof(TCHAR)); //
bf3b7f79 167 _sntprintf(ppArgList[i], 16, _T("%d"), va_arg(args, LONG)); //
5039dede
AK
168 break;
169 case 'D':
cb5360cc 170 ppArgList[i] = (TCHAR *)malloc(32 * sizeof(TCHAR)); //
bf3b7f79 171 _sntprintf(ppArgList[i], 32, INT64_FMT, va_arg(args, INT64)); //
5039dede
AK
172 break;
173 case 'x':
174 case 'i':
cb5360cc 175 ppArgList[i] = (TCHAR *)malloc(16 * sizeof(TCHAR)); //
967893bb 176 _sntprintf(ppArgList[i], 16, _T("0x%08X"), va_arg(args, UINT32)); //
5039dede
AK
177 break;
178 case 'X':
cb5360cc 179 ppArgList[i] = (TCHAR *)malloc(32 * sizeof(TCHAR));
bf3b7f79 180 _sntprintf(ppArgList[i], 32, UINT64X_FMT(_T("016")), va_arg(args, QWORD));
5039dede
AK
181 break;
182 case 'a':
cb5360cc 183 ppArgList[i] = (TCHAR *)malloc(16 * sizeof(TCHAR));
967893bb 184 IpToStr(va_arg(args, UINT32), ppArgList[i]);
5039dede
AK
185 break;
186 default:
187 ppArgList[i] = badFormat;
188 break;
189 }
190 }
191
2dd24569 192 SendTrap(dwEventCode, eventName, iNumArgs, ppArgList);
5039dede
AK
193
194 for(i = 0; i < iNumArgs; i++)
195 if ((pszFormat[i] == 'd') || (pszFormat[i] == 'x') ||
196 (pszFormat[i] == 'D') || (pszFormat[i] == 'X') ||
6a5c95f5
VK
197 (pszFormat[i] == 'i') || (pszFormat[i] == 'a')
198#ifdef UNICODE
199 || (pszFormat[i] == 'm')
200#endif
201 )
5039dede 202 free(ppArgList[i]);
bf3b7f79 203
5039dede
AK
204}
205
0137b9f7
VK
206/**
207 * Send trap - variant 3
208 * Same as variant 2, but uses argument list instead of va_list
209 */
967893bb 210void SendTrap(UINT32 dwEventCode, const TCHAR *eventName, const char *pszFormat, ...)
5039dede
AK
211{
212 va_list args;
213
214 va_start(args, pszFormat);
2dd24569 215 SendTrap(dwEventCode, eventName, pszFormat, args);
5039dede 216 va_end(args);
bf3b7f79 217
5039dede 218}
7f78ab75 219
0137b9f7
VK
220/**
221 * Forward trap from external subagent to server
222 */
b368969c 223void ForwardTrap(NXCPMessage *msg)
0137b9f7 224{
06debb26 225 msg->setField(VID_TRAP_ID, s_trapIdBase | (UINT64)InterlockedIncrement(&s_trapIdCounter));
0137b9f7
VK
226 if (s_trapQueue != NULL)
227 {
228 s_genTrapCount++;
229 s_lastTrapTime = time(NULL);
19dbc8ef 230 s_trapQueue->put(msg->createMessage());
0137b9f7
VK
231 }
232}
7f78ab75 233
0137b9f7
VK
234/**
235 * Handler for trap statistic DCIs
236 */
060c5a11 237LONG H_AgentTraps(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session)
7f78ab75
VK
238{
239 switch(arg[0])
240 {
241 case 'G':
242 ret_uint64(value, s_genTrapCount);
243 break;
244 case 'S':
245 ret_uint64(value, s_sentTrapCount);
246 break;
247 case 'T':
248 ret_uint64(value, (QWORD)s_lastTrapTime);
249 break;
250 default:
251 return SYSINFO_RC_UNSUPPORTED;
252 }
253 return SYSINFO_RC_SUCCESS;
254}