2 ** NetXMS - Network Management System
4 ** Copyright (C) 2003-2010 Victor Kirhenshtein
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.
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.
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.
28 // Load data collection items list for specified node
29 // This function is NOT REENTRANT
32 DWORD LIBNXCL_EXPORTABLE
NXCOpenNodeDCIList(NXC_SESSION hSession
, DWORD dwNodeId
,
33 NXC_DCI_LIST
**ppItemList
)
35 return ((NXCL_Session
*)hSession
)->OpenNodeDCIList(dwNodeId
, ppItemList
);
40 // Unlock and destroy previously opened node's DCI list
43 DWORD LIBNXCL_EXPORTABLE
NXCCloseNodeDCIList(NXC_SESSION hSession
, NXC_DCI_LIST
*pItemList
)
45 DWORD i
, j
, dwRetCode
= RCC_INVALID_ARGUMENT
, dwRqId
;
48 if (pItemList
!= NULL
)
50 dwRqId
= ((NXCL_Session
*)hSession
)->CreateRqId();
52 msg
.SetCode(CMD_UNLOCK_NODE_DCI_LIST
);
54 msg
.SetVariable(VID_OBJECT_ID
, pItemList
->dwNodeId
);
55 ((NXCL_Session
*)hSession
)->SendMsg(&msg
);
57 dwRetCode
= ((NXCL_Session
*)hSession
)->WaitForRCC(dwRqId
);
59 for(i
= 0; i
< pItemList
->dwNumItems
; i
++)
61 for(j
= 0; j
< pItemList
->pItems
[i
].dwNumSchedules
; j
++)
62 free(pItemList
->pItems
[i
].ppScheduleList
[j
]);
63 safe_free(pItemList
->pItems
[i
].ppScheduleList
);
64 safe_free(pItemList
->pItems
[i
].pThresholdList
);
65 safe_free(pItemList
->pItems
[i
].pszFormula
);
66 safe_free(pItemList
->pItems
[i
].pszCustomUnitName
);
67 safe_free(pItemList
->pItems
[i
].pszPerfTabSettings
);
69 safe_free(pItemList
->pItems
);
77 // Create new data collection item
80 DWORD LIBNXCL_EXPORTABLE
NXCCreateNewDCI(NXC_SESSION hSession
, NXC_DCI_LIST
*pItemList
,
83 DWORD dwRetCode
, dwRqId
;
84 CSCPMessage msg
, *pResponse
;
86 CHECK_SESSION_HANDLE();
88 dwRqId
= ((NXCL_Session
*)hSession
)->CreateRqId();
90 msg
.SetCode(CMD_CREATE_NEW_DCI
);
92 msg
.SetVariable(VID_OBJECT_ID
, pItemList
->dwNodeId
);
93 ((NXCL_Session
*)hSession
)->SendMsg(&msg
);
95 pResponse
= ((NXCL_Session
*)hSession
)->WaitForMessage(CMD_REQUEST_COMPLETED
, dwRqId
);
96 if (pResponse
!= NULL
)
98 dwRetCode
= pResponse
->GetVariableLong(VID_RCC
);
99 if (dwRetCode
== RCC_SUCCESS
)
101 *pdwItemId
= pResponse
->GetVariableLong(VID_DCI_ID
);
103 // Create new entry in list
104 pItemList
->pItems
= (NXC_DCI
*)realloc(pItemList
->pItems
,
105 sizeof(NXC_DCI
) * (pItemList
->dwNumItems
+ 1));
106 memset(&pItemList
->pItems
[pItemList
->dwNumItems
], 0, sizeof(NXC_DCI
));
107 pItemList
->pItems
[pItemList
->dwNumItems
].dwId
= *pdwItemId
;
108 pItemList
->pItems
[pItemList
->dwNumItems
].iStatus
= ITEM_STATUS_ACTIVE
;
109 pItemList
->pItems
[pItemList
->dwNumItems
].iPollingInterval
= 60;
110 pItemList
->pItems
[pItemList
->dwNumItems
].iRetentionTime
= 30;
111 pItemList
->pItems
[pItemList
->dwNumItems
].iDeltaCalculation
= DCM_ORIGINAL_VALUE
;
112 pItemList
->pItems
[pItemList
->dwNumItems
].iAdvSchedule
= 0;
113 pItemList
->pItems
[pItemList
->dwNumItems
].dwNumSchedules
= 0;
114 pItemList
->pItems
[pItemList
->dwNumItems
].ppScheduleList
= NULL
;
115 pItemList
->pItems
[pItemList
->dwNumItems
].iProcessAllThresholds
= 0;
116 pItemList
->pItems
[pItemList
->dwNumItems
].nBaseUnits
= DCI_BASEUNITS_OTHER
;
117 pItemList
->pItems
[pItemList
->dwNumItems
].nMultiplier
= 1;
118 pItemList
->dwNumItems
++;
124 dwRetCode
= RCC_TIMEOUT
;
132 // Update data collection item
135 DWORD LIBNXCL_EXPORTABLE
NXCUpdateDCI(NXC_SESSION hSession
, DWORD dwNodeId
, NXC_DCI
*pItem
)
137 DWORD i
, dwId
, dwRqId
, dwRetCode
;
138 CSCPMessage msg
, *pResponse
;
140 CHECK_SESSION_HANDLE();
142 dwRqId
= ((NXCL_Session
*)hSession
)->CreateRqId();
144 msg
.SetCode(CMD_MODIFY_NODE_DCI
);
146 msg
.SetVariable(VID_OBJECT_ID
, dwNodeId
);
147 msg
.SetVariable(VID_DCI_ID
, pItem
->dwId
);
148 msg
.SetVariable(VID_DCI_DATA_TYPE
, (WORD
)pItem
->iDataType
);
149 msg
.SetVariable(VID_POLLING_INTERVAL
, (DWORD
)pItem
->iPollingInterval
);
150 msg
.SetVariable(VID_RETENTION_TIME
, (DWORD
)pItem
->iRetentionTime
);
151 msg
.SetVariable(VID_DCI_SOURCE_TYPE
, (WORD
)pItem
->iSource
);
152 msg
.SetVariable(VID_DCI_DELTA_CALCULATION
, (WORD
)pItem
->iDeltaCalculation
);
153 msg
.SetVariable(VID_DCI_STATUS
, (WORD
)pItem
->iStatus
);
154 msg
.SetVariable(VID_NAME
, pItem
->szName
);
155 msg
.SetVariable(VID_DESCRIPTION
, pItem
->szDescription
);
156 msg
.SetVariable(VID_INSTANCE
, pItem
->szInstance
);
157 msg
.SetVariable(VID_SYSTEM_TAG
, pItem
->szSystemTag
);
158 msg
.SetVariable(VID_DCI_FORMULA
, CHECK_NULL_EX(pItem
->pszFormula
));
159 msg
.SetVariable(VID_ALL_THRESHOLDS
, (WORD
)pItem
->iProcessAllThresholds
);
160 msg
.SetVariable(VID_ADV_SCHEDULE
, (WORD
)pItem
->iAdvSchedule
);
161 msg
.SetVariable(VID_RESOURCE_ID
, pItem
->dwResourceId
);
162 msg
.SetVariable(VID_PROXY_NODE
, pItem
->dwProxyNode
);
163 msg
.SetVariable(VID_BASE_UNITS
, (WORD
)pItem
->nBaseUnits
);
164 msg
.SetVariable(VID_MULTIPLIER
, (DWORD
)pItem
->nMultiplier
);
165 if (pItem
->pszCustomUnitName
!= NULL
)
166 msg
.SetVariable(VID_CUSTOM_UNITS_NAME
, pItem
->pszCustomUnitName
);
167 if (pItem
->pszPerfTabSettings
)
168 msg
.SetVariable(VID_PERFTAB_SETTINGS
, pItem
->pszPerfTabSettings
);
169 if (pItem
->iAdvSchedule
)
171 msg
.SetVariable(VID_NUM_SCHEDULES
, pItem
->dwNumSchedules
);
172 for(i
= 0, dwId
= VID_DCI_SCHEDULE_BASE
; i
< pItem
->dwNumSchedules
; i
++, dwId
++)
173 msg
.SetVariable(dwId
, pItem
->ppScheduleList
[i
]);
177 msg
.SetVariable(VID_NUM_SCHEDULES
, (DWORD
)0);
179 msg
.SetVariable(VID_NUM_THRESHOLDS
, pItem
->dwNumThresholds
);
180 for(i
= 0, dwId
= VID_DCI_THRESHOLD_BASE
; i
< pItem
->dwNumThresholds
; i
++, dwId
++)
182 msg
.SetVariable(dwId
++, pItem
->pThresholdList
[i
].dwId
);
183 msg
.SetVariable(dwId
++, pItem
->pThresholdList
[i
].dwEvent
);
184 msg
.SetVariable(dwId
++, pItem
->pThresholdList
[i
].dwRearmEvent
);
185 msg
.SetVariable(dwId
++, pItem
->pThresholdList
[i
].wFunction
);
186 msg
.SetVariable(dwId
++, pItem
->pThresholdList
[i
].wOperation
);
187 msg
.SetVariable(dwId
++, pItem
->pThresholdList
[i
].dwArg1
);
188 msg
.SetVariable(dwId
++, pItem
->pThresholdList
[i
].dwArg2
);
189 msg
.SetVariable(dwId
++, (DWORD
)pItem
->pThresholdList
[i
].nRepeatInterval
);
190 msg
.SetVariable(dwId
++, pItem
->pThresholdList
[i
].szValue
);
192 ((NXCL_Session
*)hSession
)->SendMsg(&msg
);
194 pResponse
= ((NXCL_Session
*)hSession
)->WaitForMessage(CMD_REQUEST_COMPLETED
, dwRqId
);
195 if (pResponse
!= NULL
)
197 dwRetCode
= pResponse
->GetVariableLong(VID_RCC
);
198 if (dwRetCode
== RCC_SUCCESS
)
200 DWORD dwNumMaps
, *pdwMapId
, *pdwMapIndex
;
202 // Get index to id mapping for newly created thresholds
203 dwNumMaps
= pResponse
->GetVariableLong(VID_DCI_NUM_MAPS
);
206 pdwMapId
= (DWORD
*)malloc(sizeof(DWORD
) * dwNumMaps
);
207 pdwMapIndex
= (DWORD
*)malloc(sizeof(DWORD
) * dwNumMaps
);
208 pResponse
->GetVariableBinary(VID_DCI_MAP_IDS
, (BYTE
*)pdwMapId
, sizeof(DWORD
) * dwNumMaps
);
209 pResponse
->GetVariableBinary(VID_DCI_MAP_INDEXES
, (BYTE
*)pdwMapIndex
, sizeof(DWORD
) * dwNumMaps
);
210 for(i
= 0; i
< dwNumMaps
; i
++)
211 pItem
->pThresholdList
[ntohl(pdwMapIndex
[i
])].dwId
= ntohl(pdwMapId
[i
]);
220 dwRetCode
= RCC_TIMEOUT
;
228 // Delete data collection item
231 DWORD LIBNXCL_EXPORTABLE
NXCDeleteDCI(NXC_SESSION hSession
, NXC_DCI_LIST
*pItemList
,
234 DWORD i
, j
, dwRqId
, dwResult
= RCC_INVALID_DCI_ID
;
237 CHECK_SESSION_HANDLE();
239 // Find item with given ID in list
240 for(i
= 0; i
< pItemList
->dwNumItems
; i
++)
241 if (pItemList
->pItems
[i
].dwId
== dwItemId
)
243 dwRqId
= ((NXCL_Session
*)hSession
)->CreateRqId();
245 msg
.SetCode(CMD_DELETE_NODE_DCI
);
247 msg
.SetVariable(VID_OBJECT_ID
, pItemList
->dwNodeId
);
248 msg
.SetVariable(VID_DCI_ID
, dwItemId
);
249 ((NXCL_Session
*)hSession
)->SendMsg(&msg
);
251 dwResult
= ((NXCL_Session
*)hSession
)->WaitForRCC(dwRqId
);
252 if (dwResult
== RCC_SUCCESS
)
254 // Item was successfully deleted on server, delete it from our list
255 for(j
= 0; j
< pItemList
->pItems
[i
].dwNumSchedules
; j
++)
256 free(pItemList
->pItems
[i
].ppScheduleList
[j
]);
257 safe_free(pItemList
->pItems
[i
].ppScheduleList
);
258 safe_free(pItemList
->pItems
[i
].pThresholdList
);
259 safe_free(pItemList
->pItems
[i
].pszFormula
);
260 safe_free(pItemList
->pItems
[i
].pszCustomUnitName
);
261 safe_free(pItemList
->pItems
[i
].pszPerfTabSettings
);
262 pItemList
->dwNumItems
--;
263 memmove(&pItemList
->pItems
[i
], &pItemList
->pItems
[i
+ 1],
264 sizeof(NXC_DCI
) * (pItemList
->dwNumItems
- i
));
273 // Set status for multiple DCIs
276 DWORD LIBNXCL_EXPORTABLE
NXCSetDCIStatus(NXC_SESSION hSession
, DWORD dwNodeId
, DWORD dwNumItems
,
277 DWORD
*pdwItemList
, int iStatus
)
282 CHECK_SESSION_HANDLE();
284 dwRqId
= ((NXCL_Session
*)hSession
)->CreateRqId();
286 msg
.SetCode(CMD_SET_DCI_STATUS
);
288 msg
.SetVariable(VID_OBJECT_ID
, dwNodeId
);
289 msg
.SetVariable(VID_DCI_STATUS
, (WORD
)iStatus
);
290 msg
.SetVariable(VID_NUM_ITEMS
, dwNumItems
);
291 msg
.SetVariableToInt32Array(VID_ITEM_LIST
, dwNumItems
, pdwItemList
);
292 ((NXCL_Session
*)hSession
)->SendMsg(&msg
);
293 return ((NXCL_Session
*)hSession
)->WaitForRCC(dwRqId
);
298 // Find item in list by id and return it's index
301 DWORD LIBNXCL_EXPORTABLE
NXCItemIndex(NXC_DCI_LIST
*pItemList
, DWORD dwItemId
)
305 for(i
= 0; i
< pItemList
->dwNumItems
; i
++)
306 if (pItemList
->pItems
[i
].dwId
== dwItemId
)
308 return INVALID_INDEX
;
313 // Retrieve collected data from server
316 DWORD LIBNXCL_EXPORTABLE
NXCGetDCIData(NXC_SESSION hSession
, DWORD dwNodeId
, DWORD dwItemId
,
317 DWORD dwMaxRows
, DWORD dwTimeFrom
, DWORD dwTimeTo
,
318 NXC_DCI_DATA
**ppData
)
320 return NXCGetDCIDataEx(hSession
, dwNodeId
, dwItemId
, dwMaxRows
, dwTimeFrom
, dwTimeTo
, ppData
, NULL
, NULL
);
323 DWORD LIBNXCL_EXPORTABLE
NXCGetDCIDataEx(NXC_SESSION hSession
, DWORD dwNodeId
, DWORD dwItemId
,
324 DWORD dwMaxRows
, DWORD dwTimeFrom
, DWORD dwTimeTo
,
325 NXC_DCI_DATA
**ppData
, NXC_DCI_THRESHOLD
**thresholds
, DWORD
*numThresholds
)
327 CSCPMessage msg
, *response
;
328 DWORD i
, dwRqId
, dwId
, dwResult
;
331 CHECK_SESSION_HANDLE();
333 msg
.SetCode(CMD_GET_DCI_DATA
);
334 msg
.SetVariable(VID_OBJECT_ID
, dwNodeId
);
335 msg
.SetVariable(VID_DCI_ID
, dwItemId
);
337 // Allocate memory for results and initialize header
338 *ppData
= (NXC_DCI_DATA
*)malloc(sizeof(NXC_DCI_DATA
));
339 (*ppData
)->dwNumRows
= 0;
340 (*ppData
)->dwNodeId
= dwNodeId
;
341 (*ppData
)->dwItemId
= dwItemId
;
342 (*ppData
)->pRows
= NULL
;
343 if (thresholds
!= NULL
)
351 dwRqId
= ((NXCL_Session
*)hSession
)->CreateRqId();
354 msg
.SetVariable(VID_MAX_ROWS
, dwMaxRows
);
355 msg
.SetVariable(VID_TIME_FROM
, dwTimeFrom
);
356 msg
.SetVariable(VID_TIME_TO
, dwTimeTo
);
357 ((NXCL_Session
*)hSession
)->SendMsg(&msg
);
359 response
= ((NXCL_Session
*)hSession
)->WaitForMessage(CMD_REQUEST_COMPLETED
, dwRqId
);
360 if (response
== NULL
)
362 dwResult
= RCC_TIMEOUT
;
365 dwResult
= response
->GetVariableLong(VID_RCC
);
366 if (dwResult
== RCC_SUCCESS
)
368 CSCP_MESSAGE
*pRawMsg
;
370 if ((thresholds
!= NULL
) && (*thresholds
== NULL
))
372 *numThresholds
= response
->GetVariableLong(VID_NUM_THRESHOLDS
);
373 *thresholds
= (NXC_DCI_THRESHOLD
*)malloc(sizeof(NXC_DCI_THRESHOLD
) * (*numThresholds
));
374 for(i
= 0, dwId
= VID_DCI_THRESHOLD_BASE
; i
< *numThresholds
; i
++, dwId
++)
376 (*thresholds
)[i
].dwId
= response
->GetVariableLong(dwId
++);
377 (*thresholds
)[i
].dwEvent
= response
->GetVariableLong(dwId
++);
378 (*thresholds
)[i
].dwRearmEvent
= response
->GetVariableLong(dwId
++);
379 (*thresholds
)[i
].wFunction
= response
->GetVariableShort(dwId
++);
380 (*thresholds
)[i
].wOperation
= response
->GetVariableShort(dwId
++);
381 (*thresholds
)[i
].dwArg1
= response
->GetVariableLong(dwId
++);
382 (*thresholds
)[i
].dwArg2
= response
->GetVariableLong(dwId
++);
383 (*thresholds
)[i
].nRepeatInterval
= (LONG
)response
->GetVariableLong(dwId
++);
384 response
->GetVariableStr(dwId
++, (*thresholds
)[i
].szValue
, MAX_STRING_VALUE
);
388 // We wait a long time because data message can be quite large
389 pRawMsg
= ((NXCL_Session
*)hSession
)->WaitForRawMessage(CMD_DCI_DATA
, dwRqId
, 60000);
392 DCI_DATA_HEADER
*pHdr
;
395 DWORD dwPrevRowCount
, dwRecvRows
;
396 static WORD m_wRowSize
[] = { 8, 8, 12, 12, 260, 12 };
398 pHdr
= (DCI_DATA_HEADER
*)pRawMsg
->df
;
399 dwRecvRows
= ntohl(pHdr
->dwNumRows
);
401 // Allocate memory for results
402 dwPrevRowCount
= (*ppData
)->dwNumRows
;
403 (*ppData
)->dwNumRows
+= dwRecvRows
;
404 (*ppData
)->wDataType
= (WORD
)ntohl(pHdr
->dwDataType
);
405 if ((*ppData
)->wDataType
> 5)
406 (*ppData
)->wDataType
= 0;
407 (*ppData
)->wRowSize
= m_wRowSize
[(*ppData
)->wDataType
];
409 (*ppData
)->pRows
= (NXC_DCI_ROW
*)realloc((*ppData
)->pRows
, (*ppData
)->dwNumRows
* (*ppData
)->wRowSize
);
411 // Convert and copy values from message to rows in result
412 pSrc
= (DCI_DATA_ROW
*)(((char *)pHdr
) + sizeof(DCI_DATA_HEADER
));
413 pDst
= (NXC_DCI_ROW
*)(((char *)((*ppData
)->pRows
)) + dwPrevRowCount
* (*ppData
)->wRowSize
);
414 for(i
= 0; i
< dwRecvRows
; i
++)
416 pDst
->dwTimeStamp
= ntohl(pSrc
->dwTimeStamp
);
417 switch((*ppData
)->wDataType
)
421 pDst
->value
.dwInt32
= ntohl(pSrc
->value
.dwInteger
);
425 pDst
->value
.qwInt64
= ntohq(pSrc
->value
.qwInt64
);
428 pDst
->value
.dFloat
= ntohd(pSrc
->value
.dFloat
);
431 SwapWideString(pSrc
->value
.szString
);
434 ucs2_to_ucs4(pSrc
->value
.szString
, -1, pDst
->value
.szString
, MAX_STRING_VALUE
);
436 wcscpy(pDst
->value
.szString
, pSrc
->value
.szString
);
439 ucs2_to_mb(pSrc
->value
.szString
, -1, pDst
->value
.szString
, MAX_STRING_VALUE
);
444 pSrc
= (DCI_DATA_ROW
*)(((char *)pSrc
) + (*ppData
)->wRowSize
);
445 pDst
= (NXC_DCI_ROW
*)(((char *)pDst
) + (*ppData
)->wRowSize
);
449 if (((dwMaxRows
== 0) || (dwMaxRows
> MAX_DCI_DATA_RECORDS
)) &&
450 (dwRecvRows
== MAX_DCI_DATA_RECORDS
))
452 // Shift to last record
453 pDst
= (NXC_DCI_ROW
*)(((char *)pDst
) - (*ppData
)->wRowSize
);
454 dwTimeTo
= pDst
->dwTimeStamp
- 1; // Assume that we have no more than one value per second
456 dwMaxRows
-= MAX_DCI_DATA_RECORDS
;
468 dwResult
= RCC_TIMEOUT
;
471 } while((dwResult
== RCC_SUCCESS
) && bRun
);
473 // Destroy already allocated buffer if request was unsuccessful
474 if (dwResult
!= RCC_SUCCESS
)
476 safe_free((*ppData
)->pRows
);
478 if (thresholds
!= NULL
)
479 safe_free(*thresholds
);
487 // Destroy DCI result set
490 void LIBNXCL_EXPORTABLE
NXCDestroyDCIData(NXC_DCI_DATA
*pData
)
494 safe_free(pData
->pRows
);
501 // Get pointer to specific row in result set
504 NXC_DCI_ROW LIBNXCL_EXPORTABLE
*NXCGetRowPtr(NXC_DCI_DATA
*pData
, DWORD dwRow
)
506 if (dwRow
>= pData
->dwNumRows
)
509 return (NXC_DCI_ROW
*)(((char *)(pData
->pRows
)) + dwRow
* pData
->wRowSize
);
514 // Add threshold to item
517 DWORD LIBNXCL_EXPORTABLE
NXCAddThresholdToItem(NXC_DCI
*pItem
, NXC_DCI_THRESHOLD
*pThreshold
)
521 dwIndex
= pItem
->dwNumThresholds
++;
522 pItem
->pThresholdList
= (NXC_DCI_THRESHOLD
*)realloc(pItem
->pThresholdList
,
523 sizeof(NXC_DCI_THRESHOLD
) * pItem
->dwNumThresholds
);
524 memcpy(&pItem
->pThresholdList
[dwIndex
], pThreshold
, sizeof(NXC_DCI_THRESHOLD
));
530 // Delete threshold from item
533 BOOL LIBNXCL_EXPORTABLE
NXCDeleteThresholdFromItem(NXC_DCI
*pItem
, DWORD dwIndex
)
535 BOOL bResult
= FALSE
;
537 if (pItem
->dwNumThresholds
> dwIndex
)
539 pItem
->dwNumThresholds
--;
540 if (pItem
->dwNumThresholds
> 0)
541 memmove(&pItem
->pThresholdList
[dwIndex
], &pItem
->pThresholdList
[dwIndex
+ 1],
542 sizeof(NXC_DCI_THRESHOLD
) * (pItem
->dwNumThresholds
- dwIndex
));
550 // Swap two threshold items
553 BOOL LIBNXCL_EXPORTABLE
NXCSwapThresholds(NXC_DCI
*pItem
, DWORD dwIndex1
, DWORD dwIndex2
)
555 BOOL bResult
= FALSE
;
556 NXC_DCI_THRESHOLD dct
;
558 if ((pItem
->dwNumThresholds
> dwIndex1
) &&
559 (pItem
->dwNumThresholds
> dwIndex2
) &&
560 (dwIndex1
!= dwIndex2
))
562 memcpy(&dct
, &pItem
->pThresholdList
[dwIndex1
], sizeof(NXC_DCI_THRESHOLD
));
563 memcpy(&pItem
->pThresholdList
[dwIndex1
], &pItem
->pThresholdList
[dwIndex2
], sizeof(NXC_DCI_THRESHOLD
));
564 memcpy(&pItem
->pThresholdList
[dwIndex2
], &dct
, sizeof(NXC_DCI_THRESHOLD
));
572 // Copy data collection items from one node to another
575 DWORD LIBNXCL_EXPORTABLE
NXCCopyDCI(NXC_SESSION hSession
, DWORD dwSrcNodeId
, DWORD dwDstNodeId
,
576 DWORD dwNumItems
, DWORD
*pdwItemList
, BOOL bMove
)
581 CHECK_SESSION_HANDLE();
583 dwRqId
= ((NXCL_Session
*)hSession
)->CreateRqId();
585 msg
.SetCode(CMD_COPY_DCI
);
587 msg
.SetVariable(VID_SOURCE_OBJECT_ID
, dwSrcNodeId
);
588 msg
.SetVariable(VID_DESTINATION_OBJECT_ID
, dwDstNodeId
);
589 msg
.SetVariable(VID_NUM_ITEMS
, dwNumItems
);
590 msg
.SetVariableToInt32Array(VID_ITEM_LIST
, dwNumItems
, pdwItemList
);
591 msg
.SetVariable(VID_MOVE_FLAG
, (WORD
)bMove
);
592 ((NXCL_Session
*)hSession
)->SendMsg(&msg
);
594 return ((NXCL_Session
*)hSession
)->WaitForRCC(dwRqId
);
599 // Query value of specific parameter from node
602 DWORD LIBNXCL_EXPORTABLE
NXCQueryParameter(NXC_SESSION hSession
, DWORD dwNodeId
, int iOrigin
,
603 TCHAR
*pszParameter
, TCHAR
*pszBuffer
,
606 CSCPMessage msg
, *pResponse
;
607 DWORD dwRqId
, dwResult
;
609 CHECK_SESSION_HANDLE();
611 dwRqId
= ((NXCL_Session
*)hSession
)->CreateRqId();
613 msg
.SetCode(CMD_QUERY_PARAMETER
);
615 msg
.SetVariable(VID_OBJECT_ID
, dwNodeId
);
616 msg
.SetVariable(VID_DCI_SOURCE_TYPE
, (WORD
)iOrigin
);
617 msg
.SetVariable(VID_NAME
, pszParameter
);
618 ((NXCL_Session
*)hSession
)->SendMsg(&msg
);
620 pResponse
= ((NXCL_Session
*)hSession
)->WaitForMessage(CMD_REQUEST_COMPLETED
, dwRqId
, 120000);
621 if (pResponse
!= NULL
)
623 dwResult
= pResponse
->GetVariableLong(VID_RCC
);
624 if (dwResult
== RCC_SUCCESS
)
625 pResponse
->GetVariableStr(VID_VALUE
, pszBuffer
, dwBufferSize
);
630 dwResult
= RCC_TIMEOUT
;
637 // Get threshold list for given DCI
640 DWORD LIBNXCL_EXPORTABLE
NXCGetDCIThresholds(NXC_SESSION hSession
, DWORD dwNodeId
, DWORD dwItemId
,
641 NXC_DCI_THRESHOLD
**ppList
, DWORD
*pdwSize
)
643 CSCPMessage msg
, *pResponse
;
644 DWORD i
, dwId
, dwRqId
, dwResult
;
646 CHECK_SESSION_HANDLE();
651 dwRqId
= ((NXCL_Session
*)hSession
)->CreateRqId();
653 msg
.SetCode(CMD_GET_DCI_THRESHOLDS
);
655 msg
.SetVariable(VID_OBJECT_ID
, dwNodeId
);
656 msg
.SetVariable(VID_DCI_ID
, dwItemId
);
657 ((NXCL_Session
*)hSession
)->SendMsg(&msg
);
659 pResponse
= ((NXCL_Session
*)hSession
)->WaitForMessage(CMD_REQUEST_COMPLETED
, dwRqId
);
660 if (pResponse
!= NULL
)
662 dwResult
= pResponse
->GetVariableLong(VID_RCC
);
663 if (dwResult
== RCC_SUCCESS
)
665 *pdwSize
= pResponse
->GetVariableLong(VID_NUM_THRESHOLDS
);
666 *ppList
= (NXC_DCI_THRESHOLD
*)malloc(sizeof(NXC_DCI_THRESHOLD
) * (*pdwSize
));
667 for(i
= 0, dwId
= VID_DCI_THRESHOLD_BASE
; i
< *pdwSize
; i
++, dwId
++)
669 (*ppList
)[i
].dwId
= pResponse
->GetVariableLong(dwId
++);
670 (*ppList
)[i
].dwEvent
= pResponse
->GetVariableLong(dwId
++);
671 (*ppList
)[i
].dwRearmEvent
= pResponse
->GetVariableLong(dwId
++);
672 (*ppList
)[i
].wFunction
= pResponse
->GetVariableShort(dwId
++);
673 (*ppList
)[i
].wOperation
= pResponse
->GetVariableShort(dwId
++);
674 (*ppList
)[i
].dwArg1
= pResponse
->GetVariableLong(dwId
++);
675 (*ppList
)[i
].dwArg2
= pResponse
->GetVariableLong(dwId
++);
676 (*ppList
)[i
].nRepeatInterval
= (LONG
)pResponse
->GetVariableLong(dwId
++);
677 pResponse
->GetVariableStr(dwId
++, (*ppList
)[i
].szValue
, MAX_STRING_VALUE
);
684 dwResult
= RCC_TIMEOUT
;
691 // Get last values for all DCIs of selected node
694 DWORD LIBNXCL_EXPORTABLE
NXCGetLastValues(NXC_SESSION hSession
, DWORD dwNodeId
,
695 DWORD
*pdwNumItems
, NXC_DCI_VALUE
**ppValueList
)
697 CSCPMessage msg
, *pResponse
;
698 DWORD i
, dwId
, dwRqId
, dwResult
;
703 CHECK_SESSION_HANDLE();
705 dwRqId
= ((NXCL_Session
*)hSession
)->CreateRqId();
707 msg
.SetCode(CMD_GET_LAST_VALUES
);
709 msg
.SetVariable(VID_OBJECT_ID
, dwNodeId
);
710 ((NXCL_Session
*)hSession
)->SendMsg(&msg
);
712 pResponse
= ((NXCL_Session
*)hSession
)->WaitForMessage(CMD_REQUEST_COMPLETED
, dwRqId
);
713 if (pResponse
!= NULL
)
715 dwResult
= pResponse
->GetVariableLong(VID_RCC
);
716 if (dwResult
== RCC_SUCCESS
)
718 *pdwNumItems
= pResponse
->GetVariableLong(VID_NUM_ITEMS
);
719 *ppValueList
= (NXC_DCI_VALUE
*)malloc(sizeof(NXC_DCI_VALUE
) * (*pdwNumItems
));
720 memset(*ppValueList
, 0, sizeof(NXC_DCI_VALUE
) * (*pdwNumItems
));
721 for(i
= 0, dwId
= VID_DCI_VALUES_BASE
; i
< *pdwNumItems
; i
++, dwId
+=2)
723 (*ppValueList
)[i
].dwId
= pResponse
->GetVariableLong(dwId
++);
724 pResponse
->GetVariableStr(dwId
++, (*ppValueList
)[i
].szName
, MAX_ITEM_NAME
);
725 pResponse
->GetVariableStr(dwId
++, (*ppValueList
)[i
].szDescription
, MAX_DB_STRING
);
726 (*ppValueList
)[i
].nSource
= (BYTE
)pResponse
->GetVariableShort(dwId
++);
727 (*ppValueList
)[i
].nDataType
= (BYTE
)pResponse
->GetVariableShort(dwId
++);
728 pResponse
->GetVariableStr(dwId
++, (*ppValueList
)[i
].szValue
, MAX_DB_STRING
);
729 (*ppValueList
)[i
].dwTimestamp
= pResponse
->GetVariableLong(dwId
++);
730 (*ppValueList
)[i
].nStatus
= (BYTE
)pResponse
->GetVariableShort(dwId
++);
737 dwResult
= RCC_TIMEOUT
;
744 // Apply template to node
747 DWORD LIBNXCL_EXPORTABLE
NXCApplyTemplate(NXC_SESSION hSession
, DWORD dwTemplateId
, DWORD dwNodeId
)
752 CHECK_SESSION_HANDLE();
754 dwRqId
= ((NXCL_Session
*)hSession
)->CreateRqId();
756 msg
.SetCode(CMD_APPLY_TEMPLATE
);
758 msg
.SetVariable(VID_SOURCE_OBJECT_ID
, dwTemplateId
);
759 msg
.SetVariable(VID_DESTINATION_OBJECT_ID
, dwNodeId
);
760 ((NXCL_Session
*)hSession
)->SendMsg(&msg
);
762 return ((NXCL_Session
*)hSession
)->WaitForRCC(dwRqId
);
770 DWORD LIBNXCL_EXPORTABLE
NXCResolveDCINames(NXC_SESSION hSession
, DWORD dwNumDCI
,
771 INPUT_DCI
*pDCIList
, TCHAR
***pppszNames
)
773 CSCPMessage msg
, *pResponse
;
774 DWORD i
, j
, dwId
, dwRqId
, dwResult
, *pdwList
;
776 CHECK_SESSION_HANDLE();
778 dwRqId
= ((NXCL_Session
*)hSession
)->CreateRqId();
780 msg
.SetCode(CMD_RESOLVE_DCI_NAMES
);
782 msg
.SetVariable(VID_NUM_ITEMS
, dwNumDCI
);
784 pdwList
= (DWORD
*)malloc(sizeof(DWORD
) * dwNumDCI
* 2);
785 for(i
= 0, j
= dwNumDCI
; i
< dwNumDCI
; i
++, j
++)
787 pdwList
[i
] = pDCIList
[i
].dwNodeId
;
788 pdwList
[j
] = pDCIList
[i
].dwId
;
790 msg
.SetVariableToInt32Array(VID_NODE_LIST
, dwNumDCI
, pdwList
);
791 msg
.SetVariableToInt32Array(VID_DCI_LIST
, dwNumDCI
, &pdwList
[dwNumDCI
]);
794 ((NXCL_Session
*)hSession
)->SendMsg(&msg
);
796 pResponse
= ((NXCL_Session
*)hSession
)->WaitForMessage(CMD_REQUEST_COMPLETED
, dwRqId
);
797 if (pResponse
!= NULL
)
799 dwResult
= pResponse
->GetVariableLong(VID_RCC
);
800 if (dwResult
== RCC_SUCCESS
)
802 *pppszNames
= (TCHAR
**)malloc(sizeof(TCHAR
*) * dwNumDCI
);
803 for(i
= 0, dwId
= VID_DCI_LIST_BASE
; i
< dwNumDCI
; i
++)
804 (*pppszNames
)[i
] = pResponse
->GetVariableStr(dwId
++);
810 dwResult
= RCC_TIMEOUT
;
820 DWORD LIBNXCL_EXPORTABLE
NXCPushDCIData(NXC_SESSION hSession
, DWORD dwNumItems
,
821 NXC_DCI_PUSH_DATA
*pItems
, DWORD
*pdwIndex
)
823 CSCPMessage msg
, *pResponse
;
824 DWORD i
, dwRqId
, dwId
, dwResult
;
826 CHECK_SESSION_HANDLE();
828 dwRqId
= ((NXCL_Session
*)hSession
)->CreateRqId();
830 msg
.SetCode(CMD_PUSH_DCI_DATA
);
832 msg
.SetVariable(VID_NUM_ITEMS
, dwNumItems
);
834 for(i
= 0, dwId
= VID_PUSH_DCI_DATA_BASE
; i
< dwNumItems
; i
++)
836 msg
.SetVariable(dwId
++, pItems
[i
].dwNodeId
);
837 if (pItems
[i
].dwNodeId
== 0)
839 msg
.SetVariable(dwId
++, pItems
[i
].pszNodeName
);
842 msg
.SetVariable(dwId
++, pItems
[i
].dwId
);
843 if (pItems
[i
].dwId
== 0)
845 msg
.SetVariable(dwId
++, pItems
[i
].pszName
);
848 msg
.SetVariable(dwId
++, pItems
[i
].pszValue
);
851 ((NXCL_Session
*)hSession
)->SendMsg(&msg
);
853 pResponse
= ((NXCL_Session
*)hSession
)->WaitForMessage(CMD_REQUEST_COMPLETED
, dwRqId
);
854 if (pResponse
!= NULL
)
856 dwResult
= pResponse
->GetVariableLong(VID_RCC
);
857 if (dwResult
!= RCC_SUCCESS
)
859 *pdwIndex
= pResponse
->GetVariableLong(VID_FAILED_DCI_INDEX
);
865 dwResult
= RCC_TIMEOUT
;
876 DWORD LIBNXCL_EXPORTABLE
NXCGetDCIInfo(NXC_SESSION hSession
, DWORD dwNodeId
,
877 DWORD dwItemId
, NXC_DCI
*pInfo
)
879 CSCPMessage msg
, *pResponse
;
880 DWORD dwRqId
, dwResult
;
882 CHECK_SESSION_HANDLE();
884 dwRqId
= ((NXCL_Session
*)hSession
)->CreateRqId();
886 msg
.SetCode(CMD_GET_DCI_INFO
);
888 msg
.SetVariable(VID_OBJECT_ID
, dwNodeId
);
889 msg
.SetVariable(VID_DCI_ID
, dwItemId
);
891 ((NXCL_Session
*)hSession
)->SendMsg(&msg
);
893 pResponse
= ((NXCL_Session
*)hSession
)->WaitForMessage(CMD_REQUEST_COMPLETED
, dwRqId
);
894 if (pResponse
!= NULL
)
896 dwResult
= pResponse
->GetVariableLong(VID_RCC
);
897 if (dwResult
== RCC_SUCCESS
)
899 memset(pInfo
, 0, sizeof(NXC_DCI
));
900 pInfo
->dwId
= dwItemId
;
901 pInfo
->dwResourceId
= pResponse
->GetVariableLong(VID_RESOURCE_ID
);
902 pInfo
->dwTemplateId
= pResponse
->GetVariableLong(VID_TEMPLATE_ID
);
903 pInfo
->iDataType
= (BYTE
)pResponse
->GetVariableShort(VID_DCI_DATA_TYPE
);
904 pInfo
->iSource
= (BYTE
)pResponse
->GetVariableShort(VID_DCI_SOURCE_TYPE
);
905 pResponse
->GetVariableStr(VID_NAME
, pInfo
->szName
, MAX_ITEM_NAME
);
906 pResponse
->GetVariableStr(VID_DESCRIPTION
, pInfo
->szDescription
, MAX_DB_STRING
);
912 dwResult
= RCC_TIMEOUT
;
919 // Get list of system DCIs
922 DWORD LIBNXCL_EXPORTABLE
NXCGetPerfTabDCIList(NXC_SESSION hSession
, DWORD dwNodeId
,
923 DWORD
*pdwNumItems
, NXC_PERFTAB_DCI
**ppList
)
925 CSCPMessage msg
, *pResponse
;
926 DWORD i
, dwId
, dwRqId
, dwResult
;
928 CHECK_SESSION_HANDLE();
930 dwRqId
= ((NXCL_Session
*)hSession
)->CreateRqId();
934 msg
.SetCode(CMD_GET_PERFTAB_DCI_LIST
);
936 msg
.SetVariable(VID_OBJECT_ID
, dwNodeId
);
938 ((NXCL_Session
*)hSession
)->SendMsg(&msg
);
940 pResponse
= ((NXCL_Session
*)hSession
)->WaitForMessage(CMD_REQUEST_COMPLETED
, dwRqId
);
941 if (pResponse
!= NULL
)
943 dwResult
= pResponse
->GetVariableLong(VID_RCC
);
944 if (dwResult
== RCC_SUCCESS
)
946 *pdwNumItems
= pResponse
->GetVariableLong(VID_NUM_ITEMS
);
947 *ppList
= (NXC_PERFTAB_DCI
*)malloc(sizeof(NXC_PERFTAB_DCI
) * (*pdwNumItems
));
948 for(i
= 0, dwId
= VID_SYSDCI_LIST_BASE
; i
< *pdwNumItems
; i
++, dwId
+= 6)
950 (*ppList
)[i
].dwId
= pResponse
->GetVariableLong(dwId
++);
951 pResponse
->GetVariableStr(dwId
++, (*ppList
)[i
].szName
, MAX_DB_STRING
);
952 (*ppList
)[i
].nStatus
= pResponse
->GetVariableShort(dwId
++);
953 (*ppList
)[i
].pszSettings
= pResponse
->GetVariableStr(dwId
++);
960 dwResult
= RCC_TIMEOUT
;
967 // Clear collected data for DCI
970 DWORD LIBNXCL_EXPORTABLE
NXCClearDCIData(NXC_SESSION hSession
, DWORD dwNodeId
, DWORD dwItemId
)
975 CHECK_SESSION_HANDLE();
977 dwRqId
= ((NXCL_Session
*)hSession
)->CreateRqId();
979 msg
.SetCode(CMD_CLEAR_DCI_DATA
);
981 msg
.SetVariable(VID_OBJECT_ID
, dwNodeId
);
982 msg
.SetVariable(VID_DCI_ID
, dwItemId
);
983 ((NXCL_Session
*)hSession
)->SendMsg(&msg
);
985 return ((NXCL_Session
*)hSession
)->WaitForRCC(dwRqId
);
990 // Test DCI's transformation script
993 DWORD LIBNXCL_EXPORTABLE
NXCTestDCITransformation(NXC_SESSION hSession
, DWORD dwNodeId
, DWORD dwItemId
,
994 const TCHAR
*script
, const TCHAR
*value
, BOOL
*execStatus
,
995 TCHAR
*execResult
, size_t resultBufSize
)
997 DWORD dwRqId
, dwResult
;
998 CSCPMessage msg
, *pResponse
;
1000 CHECK_SESSION_HANDLE();
1002 dwRqId
= ((NXCL_Session
*)hSession
)->CreateRqId();
1004 msg
.SetCode(CMD_TEST_DCI_TRANSFORMATION
);
1006 msg
.SetVariable(VID_OBJECT_ID
, dwNodeId
);
1007 msg
.SetVariable(VID_DCI_ID
, dwItemId
);
1008 msg
.SetVariable(VID_SCRIPT
, script
);
1009 msg
.SetVariable(VID_VALUE
, value
);
1010 ((NXCL_Session
*)hSession
)->SendMsg(&msg
);
1012 pResponse
= ((NXCL_Session
*)hSession
)->WaitForMessage(CMD_REQUEST_COMPLETED
, dwRqId
);
1013 if (pResponse
!= NULL
)
1015 dwResult
= pResponse
->GetVariableLong(VID_RCC
);
1016 if (dwResult
== RCC_SUCCESS
)
1018 *execStatus
= pResponse
->GetVariableShort(VID_EXECUTION_STATUS
);
1019 pResponse
->GetVariableStr(VID_EXECUTION_RESULT
, execResult
, (DWORD
)resultBufSize
);
1025 dwResult
= RCC_TIMEOUT
;