license changed to LGPL for libnxcl, libnxsnmp, libnxlp, libnxsl, and libnxmap
[public/netxms.git] / src / libnxcl / situation.cpp
1 /*
2 ** NetXMS - Network Management System
3 ** Client Library
4 ** Copyright (C) 2003-2010 Victor Kirhenshtein
5 **
6 ** This program is free software; you can redistribute it and/or modify
7 ** it under the terms of the GNU Lesser General Public License as published by
8 ** the Free Software Foundation; either version 3 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 Lesser 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: situation.cpp
21 **
22 **/
23
24 #include "libnxcl.h"
25
26
27 //
28 // Create NXC_SITUATION from message
29 //
30
31 static void SituationFromMessage(CSCPMessage *msg, NXC_SITUATION *situation)
32 {
33 int i, j, attrCount;
34 TCHAR *attr, *value;
35 DWORD id;
36
37 situation->m_id = msg->GetVariableLong(VID_SITUATION_ID);
38 situation->m_name = msg->GetVariableStr(VID_NAME);
39 situation->m_comments = msg->GetVariableStr(VID_COMMENTS);
40 situation->m_instanceCount = msg->GetVariableLong(VID_INSTANCE_COUNT);
41 situation->m_instanceList = (NXC_SITUATION_INSTANCE *)malloc(sizeof(NXC_SITUATION_INSTANCE) * situation->m_instanceCount);
42 for(i = 0, id = VID_INSTANCE_LIST_BASE; i < situation->m_instanceCount; i++)
43 {
44 situation->m_instanceList[i].m_name = msg->GetVariableStr(id++);
45 attrCount = msg->GetVariableLong(id++);
46 situation->m_instanceList[i].m_attrList = new StringMap;
47 for(j = 0; j < attrCount; j++)
48 {
49 attr = msg->GetVariableStr(id++);
50 value = msg->GetVariableStr(id++);
51 situation->m_instanceList[i].m_attrList->setPreallocated(attr, value);
52 }
53 }
54 }
55
56
57 //
58 // Process CMD_SITUATION_CHANGE message
59 //
60
61 void ProcessSituationChange(NXCL_Session *pSession, CSCPMessage *pMsg)
62 {
63 NXC_SITUATION st;
64 DWORD dwCode;
65
66 dwCode = pMsg->GetVariableShort(VID_NOTIFICATION_CODE);
67 SituationFromMessage(pMsg, &st);
68 pSession->callEventHandler(NXC_EVENT_SITUATION_UPDATE, dwCode, &st);
69 }
70
71
72 //
73 // Create situation
74 //
75
76 DWORD LIBNXCL_EXPORTABLE NXCCreateSituation(NXC_SESSION hSession, const TCHAR *name, const TCHAR *comments, DWORD *pdwId)
77 {
78 CSCPMessage msg, *pResponse;
79 DWORD dwRqId, rcc;
80
81 dwRqId = ((NXCL_Session *)hSession)->CreateRqId();
82
83 msg.SetCode(CMD_CREATE_SITUATION);
84 msg.SetId(dwRqId);
85 msg.SetVariable(VID_NAME, name);
86 msg.SetVariable(VID_COMMENTS, CHECK_NULL_EX(comments));
87 ((NXCL_Session *)hSession)->SendMsg(&msg);
88
89 pResponse = ((NXCL_Session *)hSession)->WaitForMessage(CMD_REQUEST_COMPLETED, dwRqId);
90 if (pResponse != NULL)
91 {
92 rcc = pResponse->GetVariableLong(VID_RCC);
93 if (rcc == RCC_SUCCESS)
94 {
95 *pdwId = pResponse->GetVariableLong(VID_SITUATION_ID);
96 }
97 delete pResponse;
98 }
99 else
100 {
101 rcc = RCC_TIMEOUT;
102 }
103 return rcc;
104 }
105
106
107 //
108 // Modify situation
109 //
110
111 DWORD LIBNXCL_EXPORTABLE NXCModifySituation(NXC_SESSION hSession, DWORD id,
112 const TCHAR *name, const TCHAR *comments)
113 {
114 CSCPMessage msg;
115 DWORD dwRqId;
116
117 dwRqId = ((NXCL_Session *)hSession)->CreateRqId();
118
119 msg.SetCode(CMD_UPDATE_SITUATION);
120 msg.SetId(dwRqId);
121 msg.SetVariable(VID_SITUATION_ID, id);
122 if (name != NULL)
123 msg.SetVariable(VID_NAME, name);
124 if (comments != NULL)
125 msg.SetVariable(VID_COMMENTS, comments);
126 ((NXCL_Session *)hSession)->SendMsg(&msg);
127
128 return ((NXCL_Session *)hSession)->WaitForRCC(dwRqId);
129 }
130
131
132 //
133 // Delete situation
134 //
135
136 DWORD LIBNXCL_EXPORTABLE NXCDeleteSituation(NXC_SESSION hSession, DWORD id)
137 {
138 CSCPMessage msg;
139 DWORD dwRqId;
140
141 dwRqId = ((NXCL_Session *)hSession)->CreateRqId();
142
143 msg.SetCode(CMD_DELETE_SITUATION);
144 msg.SetId(dwRqId);
145 msg.SetVariable(VID_SITUATION_ID, id);
146 ((NXCL_Session *)hSession)->SendMsg(&msg);
147
148 return ((NXCL_Session *)hSession)->WaitForRCC(dwRqId);
149 }
150
151
152 //
153 // Delete situation instance
154 //
155
156 DWORD LIBNXCL_EXPORTABLE NXCDeleteSituationInstance(NXC_SESSION hSession, DWORD id, const TCHAR *instance)
157 {
158 CSCPMessage msg;
159 DWORD dwRqId;
160
161 dwRqId = ((NXCL_Session *)hSession)->CreateRqId();
162
163 msg.SetCode(CMD_DEL_SITUATION_INSTANCE);
164 msg.SetId(dwRqId);
165 msg.SetVariable(VID_SITUATION_ID, id);
166 msg.SetVariable(VID_SITUATION_INSTANCE, instance);
167 ((NXCL_Session *)hSession)->SendMsg(&msg);
168
169 return ((NXCL_Session *)hSession)->WaitForRCC(dwRqId);
170 }
171
172
173 //
174 // Get situation list
175 //
176
177 DWORD LIBNXCL_EXPORTABLE NXCGetSituationList(NXC_SESSION hSession, NXC_SITUATION_LIST **list)
178 {
179 CSCPMessage msg, *pResponse;
180 DWORD dwRqId, rcc;
181 int i;
182
183 dwRqId = ((NXCL_Session *)hSession)->CreateRqId();
184
185 msg.SetCode(CMD_GET_SITUATION_LIST);
186 msg.SetId(dwRqId);
187 ((NXCL_Session *)hSession)->SendMsg(&msg);
188
189 pResponse = ((NXCL_Session *)hSession)->WaitForMessage(CMD_REQUEST_COMPLETED, dwRqId);
190 if (pResponse != NULL)
191 {
192 rcc = pResponse->GetVariableLong(VID_RCC);
193 if (rcc == RCC_SUCCESS)
194 {
195 *list = (NXC_SITUATION_LIST *)malloc(sizeof(NXC_SITUATION_LIST));
196 (*list)->m_count = pResponse->GetVariableLong(VID_SITUATION_COUNT);
197 (*list)->m_situations = (NXC_SITUATION *)malloc(sizeof(NXC_SITUATION) * (*list)->m_count);
198 memset((*list)->m_situations, 0, sizeof(NXC_SITUATION) * (*list)->m_count);
199 delete pResponse;
200 for(i = 0; i < (*list)->m_count; i++)
201 {
202 pResponse = ((NXCL_Session *)hSession)->WaitForMessage(CMD_SITUATION_DATA, dwRqId);
203 if (pResponse != NULL)
204 {
205 SituationFromMessage(pResponse, &((*list)->m_situations[i]));
206 delete pResponse;
207 }
208 else
209 {
210 NXCDestroySituationList(*list);
211 *list = NULL;
212 rcc = RCC_TIMEOUT;
213 break;
214 }
215 }
216 }
217 else
218 {
219 delete pResponse;
220 }
221 }
222 else
223 {
224 rcc = RCC_TIMEOUT;
225 }
226 return rcc;
227 }
228
229
230 //
231 // Copy NXC_SITUATION structure
232 //
233
234 static void CopySituation(NXC_SITUATION *dst, NXC_SITUATION *src)
235 {
236 int i;
237
238 dst->m_id = src->m_id;
239 dst->m_name = _tcsdup(CHECK_NULL_EX(src->m_name));
240 dst->m_comments = _tcsdup(CHECK_NULL_EX(src->m_comments));
241 dst->m_instanceCount = src->m_instanceCount;
242 dst->m_instanceList = (NXC_SITUATION_INSTANCE *)malloc(sizeof(NXC_SITUATION_INSTANCE) * dst->m_instanceCount);
243 for(i = 0; i < src->m_instanceCount; i++)
244 {
245 dst->m_instanceList[i].m_name = _tcsdup(CHECK_NULL_EX(src->m_instanceList[i].m_name));
246 dst->m_instanceList[i].m_attrList = new StringMap(*(src->m_instanceList[i].m_attrList));
247 }
248 }
249
250
251 //
252 // Find situation in list
253 //
254
255 static int FindSituationInList(NXC_SITUATION_LIST *list, DWORD id)
256 {
257 int i;
258
259 for(i = 0; i < list->m_count; i++)
260 if (list->m_situations[i].m_id == id)
261 return i;
262 return INVALID_INDEX;
263 }
264
265
266 //
267 // Destroy situation
268 //
269
270 static void DestroySituation(NXC_SITUATION *s)
271 {
272 int i;
273
274 safe_free(s->m_name);
275 safe_free(s->m_comments);
276 for(i = 0; i < s->m_instanceCount; i++)
277 {
278 safe_free(s->m_instanceList[i].m_name);
279 delete s->m_instanceList[i].m_attrList;
280 }
281 }
282
283
284 //
285 // Update existing situation list with new data
286 //
287
288 void LIBNXCL_EXPORTABLE NXCUpdateSituationList(NXC_SITUATION_LIST *list, int code, NXC_SITUATION *update)
289 {
290 int index;
291
292 switch(code)
293 {
294 case SITUATION_UPDATE:
295 index = FindSituationInList(list, update->m_id);
296 if (index != INVALID_INDEX)
297 {
298 DestroySituation(&list->m_situations[index]);
299 CopySituation(&list->m_situations[index], update);
300 break;
301 }
302 case SITUATION_CREATE:
303 list->m_count++;
304 list->m_situations = (NXC_SITUATION *)realloc(list->m_situations, sizeof(NXC_SITUATION) * list->m_count);
305 CopySituation(&list->m_situations[list->m_count - 1], update);
306 break;
307 case SITUATION_DELETE:
308 index = FindSituationInList(list, update->m_id);
309 if (index != INVALID_INDEX)
310 {
311 DestroySituation(&list->m_situations[index]);
312 list->m_count--;
313 memmove(&list->m_situations[index], &list->m_situations[index + 1], sizeof(NXC_SITUATION) * (list->m_count - index));
314 }
315 break;
316 default:
317 break;
318 }
319 }
320
321
322 //
323 // Destroy situation list
324 //
325
326 void LIBNXCL_EXPORTABLE NXCDestroySituationList(NXC_SITUATION_LIST *list)
327 {
328 int i;
329
330 if (list != NULL)
331 {
332 if (list->m_situations != NULL)
333 {
334 for(i = 0; i < list->m_count; i++)
335 {
336 DestroySituation(&list->m_situations[i]);
337 }
338 free(list->m_situations);
339 }
340 free(list);
341 }
342 }