2 ** NetXMS - Network Management System
3 ** Copyright (C) 2003-2016 Victor Kirhenshtein
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.
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.
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.
28 void ProcessTrap(SNMP_PDU
*pdu
, const InetAddress
& srcAddr
, UINT32 zoneId
, int srcPort
, SNMP_Transport
*pTransport
, SNMP_Engine
*localEngine
, bool isInformRq
);
31 * Destructor for extended agent connection class
33 AgentConnectionEx::~AgentConnectionEx()
40 void AgentConnectionEx::onTrap(NXCPMessage
*pMsg
)
45 TCHAR
*pszArgList
[32], szBuffer
[32];
46 char szFormat
[] = "ssssssssssssssssssssssssssssssss";
48 DbgPrintf(3, _T("AgentConnectionEx::onTrap(): Received trap message from agent at %s, node ID %d"), getIpAddr().toString(szBuffer
), m_nodeId
);
50 pNode
= (Node
*)FindObjectById(m_nodeId
, OBJECT_NODE
);
52 pNode
= FindNodeByIP(0, getIpAddr().getAddressV4());
55 if (pNode
->getStatus() != STATUS_UNMANAGED
)
57 // Check for duplicate traps - only accept traps with ID
58 // higher than last received
59 // agents prior to 1.1.6 will not send trap id
60 // we should accept trap in that case to maintain compatibility
62 QWORD trapId
= pMsg
->getFieldAsUInt64(VID_TRAP_ID
);
65 acceptTrap
= pNode
->checkAgentTrapId(trapId
);
66 DbgPrintf(5, _T("AgentConnectionEx::onTrap(): trapID is%s valid"), acceptTrap
? _T("") : _T(" not"));
71 DbgPrintf(5, _T("AgentConnectionEx::onTrap(): trap ID not provided"));
76 dwEventCode
= pMsg
->getFieldAsUInt32(VID_EVENT_CODE
);
77 if ((dwEventCode
== 0) && pMsg
->isFieldExist(VID_EVENT_NAME
))
80 pMsg
->getFieldAsString(VID_EVENT_NAME
, eventName
, 256);
81 dwEventCode
= EventCodeFromName(eventName
, 0);
83 iNumArgs
= (int)pMsg
->getFieldAsUInt16(VID_NUM_ARGS
);
86 for(i
= 0; i
< iNumArgs
; i
++)
87 pszArgList
[i
] = pMsg
->getFieldAsString(VID_EVENT_ARG_BASE
+ i
);
88 DbgPrintf(3, _T("Event from trap: %d"), dwEventCode
);
90 szFormat
[iNumArgs
] = 0;
91 PostEvent(dwEventCode
, pNode
->getId(), (iNumArgs
> 0) ? szFormat
: NULL
,
92 pszArgList
[0], pszArgList
[1], pszArgList
[2], pszArgList
[3],
93 pszArgList
[4], pszArgList
[5], pszArgList
[6], pszArgList
[7],
94 pszArgList
[8], pszArgList
[9], pszArgList
[10], pszArgList
[11],
95 pszArgList
[12], pszArgList
[13], pszArgList
[14], pszArgList
[15],
96 pszArgList
[16], pszArgList
[17], pszArgList
[18], pszArgList
[19],
97 pszArgList
[20], pszArgList
[21], pszArgList
[22], pszArgList
[23],
98 pszArgList
[24], pszArgList
[25], pszArgList
[26], pszArgList
[27],
99 pszArgList
[28], pszArgList
[29], pszArgList
[30], pszArgList
[31]);
102 for(i
= 0; i
< iNumArgs
; i
++)
108 DbgPrintf(3, _T("AgentConnectionEx::onTrap(): node %s [%d] in in UNMANAGED state - trap ignored"), pNode
->getName(), pNode
->getId());
113 DbgPrintf(3, _T("AgentConnectionEx::onTrap(): Cannot find node for IP address %s"), getIpAddr().toString(szBuffer
));
118 * Handler for data push
120 void AgentConnectionEx::onDataPush(NXCPMessage
*msg
)
122 if (g_flags
& AF_SHUTDOWN
)
125 TCHAR name
[MAX_PARAM_NAME
], value
[MAX_RESULT_LENGTH
];
126 msg
->getFieldAsString(VID_NAME
, name
, MAX_PARAM_NAME
);
127 msg
->getFieldAsString(VID_VALUE
, value
, MAX_RESULT_LENGTH
);
131 sender
= (Node
*)FindObjectById(m_nodeId
, OBJECT_NODE
);
133 sender
= FindNodeByIP(0, getIpAddr());
137 // Check for duplicate data requests - only accept requests with ID
138 // higher than last received
139 // agents prior to 1.2.10 will not send request id
140 // we should accept data in that case to maintain compatibility
142 QWORD requestId
= msg
->getFieldAsUInt64(VID_REQUEST_ID
);
145 acceptRequest
= sender
->checkAgentPushRequestId(requestId
);
146 DbgPrintf(5, _T("AgentConnectionEx::onDataPush(): requestId is%s valid"), acceptRequest
? _T("") : _T(" not"));
150 acceptRequest
= true;
151 DbgPrintf(5, _T("AgentConnectionEx::onDataPush(): request ID not provided"));
157 UINT32 objectId
= msg
->getFieldAsUInt32(VID_OBJECT_ID
);
160 // push on behalf of other node
161 target
= (Node
*)FindObjectById(objectId
, OBJECT_NODE
);
164 if (target
->isTrustedNode(sender
->getId()))
166 DbgPrintf(5, _T("%s: agent data push: target set to %s [%d]"), sender
->getName(), target
->getName(), target
->getId());
170 DbgPrintf(5, _T("%s: agent data push: not in trusted node list for target %s [%d]"), sender
->getName(), target
->getName(), target
->getId());
182 DbgPrintf(5, _T("%s: agent data push: %s=%s"), target
->getName(), name
, value
);
183 DCObject
*dci
= target
->getDCObjectByName(name
);
184 if ((dci
!= NULL
) && (dci
->getType() == DCO_TYPE_ITEM
) && (dci
->getDataSource() == DS_PUSH_AGENT
) && (dci
->getStatus() == ITEM_STATUS_ACTIVE
))
186 DbgPrintf(5, _T("%s: agent data push: found DCI %d"), target
->getName(), dci
->getId());
187 time_t t
= msg
->getFieldAsTime(VID_TIMESTAMP
);
190 target
->processNewDCValue(dci
, t
, value
);
191 if (t
> dci
->getLastPollTime())
192 dci
->setLastPollTime(t
);
196 DbgPrintf(5, _T("%s: agent data push: DCI not found for %s"), target
->getName(), name
);
201 DbgPrintf(5, _T("%s: agent data push: target node not found or not accessible"), sender
->getName());
210 void AgentConnectionEx::printMsg(const TCHAR
*format
, ...)
213 va_start(args
, format
);
214 nxlog_debug2(6, format
, args
);
219 * Cancel unknown file monitoring
221 static void CancelUnknownFileMonitoring(Node
*object
,TCHAR
*remoteFile
)
223 DbgPrintf(6, _T("AgentConnectionEx::onFileMonitoringData: unknown subscription will be canceled."));
224 AgentConnection
*conn
= object
->createAgentConnection();
228 request
.setId(conn
->generateRequestId());
229 request
.setCode(CMD_CANCEL_FILE_MONITORING
);
230 request
.setField(VID_FILE_NAME
, remoteFile
);
231 request
.setField(VID_OBJECT_ID
, object
->getId());
232 NXCPMessage
* response
= conn
->customRequest(&request
);
239 * Recieve file monitoring information and resend to all required user sessions
241 void AgentConnectionEx::onFileMonitoringData(NXCPMessage
*pMsg
)
245 object
= (Node
*)FindObjectById(m_nodeId
, OBJECT_NODE
);
248 TCHAR remoteFile
[MAX_PATH
];
249 pMsg
->getFieldAsString(VID_FILE_NAME
, remoteFile
, MAX_PATH
);
250 ObjectArray
<ClientSession
>* result
= g_monitoringList
.findClientByFNameAndNodeID(remoteFile
, object
->getId());
251 DbgPrintf(6, _T("AgentConnectionEx::onFileMonitoringData: found %d sessions for remote file %s on node %s [%d]"), result
->size(), remoteFile
, object
->getName(), object
->getId());
252 int validSessionCount
= result
->size();
253 for(int i
= 0; i
< result
->size(); i
++)
255 if(!result
->get(i
)->sendMessage(pMsg
))
258 _tcsncpy(file
.fileName
, remoteFile
, MAX_PATH
);
259 file
.nodeID
= m_nodeId
;
260 file
.session
= result
->get(i
);
261 g_monitoringList
.removeMonitoringFile(&file
);
264 if (validSessionCount
== 0)
265 CancelUnknownFileMonitoring(object
, remoteFile
);
268 if (result
->size() == 0)
270 CancelUnknownFileMonitoring(object
, remoteFile
);
276 g_monitoringList
.removeDisconnectedNode(m_nodeId
);
277 DbgPrintf(6, _T("AgentConnectionEx::onFileMonitoringData: node object not found"));
282 * Ask modules if they can procress custom message
284 bool AgentConnectionEx::processCustomMessage(NXCPMessage
*msg
)
287 DbgPrintf(6, _T("AgentConnectionEx::processCustomMessage: processing message %s ID %d"),
288 NXCPMessageCodeName(msg
->getCode(), buffer
), msg
->getId());
290 for(UINT32 i
= 0; i
< g_dwNumModules
; i
++)
292 if (g_pModuleList
[i
].pfOnAgentMessage
!= NULL
)
294 if (g_pModuleList
[i
].pfOnAgentMessage(msg
, m_nodeId
))
295 return true; // accepted by module
302 * Create SNMP proxy transport for sending trap response
304 static SNMP_ProxyTransport
*CreateSNMPProxyTransport(AgentConnectionEx
*conn
, Node
*originNode
, const InetAddress
& originAddr
, UINT16 port
)
307 SNMP_ProxyTransport
*snmpTransport
= new SNMP_ProxyTransport(conn
, originAddr
, port
);
308 if (originNode
!= NULL
)
310 snmpTransport
->setSecurityContext(originNode
->getSnmpSecurityContext());
312 return snmpTransport
;
316 * Recieve trap sent throught proxy agent
318 void AgentConnectionEx::onSnmpTrap(NXCPMessage
*msg
)
320 Node
*proxyNode
= NULL
;
321 TCHAR ipStringBuffer
[4096];
323 static BYTE engineId
[] = { 0x80, 0x00, 0x00, 0x00, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00 };
324 SNMP_Engine
localEngine(engineId
, 12);
326 DbgPrintf(3, _T("AgentConnectionEx::onSnmpTrap(): Received SNMP trap message from agent at %s, node ID %d"),
327 getIpAddr().toString(ipStringBuffer
), m_nodeId
);
330 proxyNode
= (Node
*)FindObjectById(m_nodeId
, OBJECT_NODE
);
331 if (proxyNode
!= NULL
)
333 // Check for duplicate traps - only accept traps with ID
334 // higher than last received
336 UINT32 trapId
= msg
->getId();
339 acceptTrap
= proxyNode
->checkSNMPTrapId(trapId
);
340 DbgPrintf(5, _T("AgentConnectionEx::onSnmpTrap(): SNMP trapID is%s valid"), acceptTrap
? _T("") : _T(" not"));
345 DbgPrintf(5, _T("AgentConnectionEx::onSnmpTrap(): SNMP trap ID not provided"));
350 InetAddress originSenderIP
= msg
->getFieldAsInetAddress(VID_IP_ADDRESS
);
351 UINT32 pduLenght
= msg
->getFieldAsUInt32(VID_PDU_SIZE
);
352 BYTE
*pduBytes
= (BYTE
*)malloc(pduLenght
);
353 msg
->getFieldAsBinary(VID_PDU
, pduBytes
, pduLenght
);
354 UINT32 zoneId
= IsZoningEnabled() ? msg
->getFieldAsUInt32(VID_ZONE_ID
) : 0;
355 Node
*originNode
= FindNodeByIP(zoneId
, originSenderIP
);
356 if ((originNode
!= NULL
) || ConfigReadInt(_T("LogAllSNMPTraps"), FALSE
))
358 SNMP_PDU
*pdu
= new SNMP_PDU
;
359 if (pdu
->parse(pduBytes
, pduLenght
, (originNode
!= NULL
) ? originNode
->getSnmpSecurityContext() : NULL
, true))
361 DbgPrintf(6, _T("SNMPTrapReceiver: received PDU of type %d"), pdu
->getCommand());
362 if ((pdu
->getCommand() == SNMP_TRAP
) || (pdu
->getCommand() == SNMP_INFORM_REQUEST
))
364 bool isInformRequest
= (pdu
->getCommand() == SNMP_INFORM_REQUEST
);
365 SNMP_ProxyTransport
*snmpTransport
= isInformRequest
? CreateSNMPProxyTransport(this, originNode
, originSenderIP
, msg
->getFieldAsUInt16(VID_PORT
)) : NULL
;
366 if ((pdu
->getVersion() == SNMP_VERSION_3
) && (pdu
->getCommand() == SNMP_INFORM_REQUEST
))
368 SNMP_SecurityContext
*context
= snmpTransport
->getSecurityContext();
369 context
->setAuthoritativeEngine(localEngine
);
371 ProcessTrap(pdu
, originSenderIP
, zoneId
, msg
->getFieldAsUInt16(VID_PORT
), snmpTransport
, &localEngine
, isInformRequest
);
372 delete snmpTransport
;
374 else if ((pdu
->getVersion() == SNMP_VERSION_3
) && (pdu
->getCommand() == SNMP_GET_REQUEST
) && (pdu
->getAuthoritativeEngine().getIdLen() == 0))
376 // Engine ID discovery
377 DbgPrintf(6, _T("SNMPTrapReceiver: EngineId discovery"));
379 SNMP_ProxyTransport
*snmpTransport
= CreateSNMPProxyTransport(this, originNode
, originSenderIP
, msg
->getFieldAsUInt16(VID_PORT
));
381 SNMP_PDU
*response
= new SNMP_PDU(SNMP_REPORT
, pdu
->getRequestId(), pdu
->getVersion());
382 response
->setReportable(false);
383 response
->setMessageId(pdu
->getMessageId());
384 response
->setContextEngineId(localEngine
.getId(), localEngine
.getIdLen());
386 SNMP_Variable
*var
= new SNMP_Variable(_T(".1.3.6.1.6.3.15.1.1.4.0"));
387 var
->setValueFromString(ASN_INTEGER
, _T("2"));
388 response
->bindVariable(var
);
390 SNMP_SecurityContext
*context
= new SNMP_SecurityContext();
391 localEngine
.setTime((int)time(NULL
));
392 context
->setAuthoritativeEngine(localEngine
);
393 context
->setSecurityModel(SNMP_SECURITY_MODEL_USM
);
394 context
->setAuthMethod(SNMP_AUTH_NONE
);
395 context
->setPrivMethod(SNMP_ENCRYPT_NONE
);
396 snmpTransport
->setSecurityContext(context
);
398 snmpTransport
->setWaitForResponse(false);
399 snmpTransport
->sendMessage(response
);
401 delete snmpTransport
;
403 else if (pdu
->getCommand() == SNMP_REPORT
)
405 DbgPrintf(6, _T("AgentConnectionEx::onSnmpTrap(): REPORT PDU with error %s"), (const TCHAR
*)pdu
->getVariable(0)->getName().toString());
409 else if (pdu
->getCommand() == SNMP_REPORT
)
411 DbgPrintf(6, _T("AgentConnectionEx::onSnmpTrap(): REPORT PDU with error %s"), (const TCHAR
*)pdu
->getVariable(0)->getName().toString());
416 DbgPrintf(3, _T("AgentConnectionEx::onSnmpTrap(): cannot find origin node with IP %s and not accepting traps from unknown sources"), originSenderIP
.toString(ipStringBuffer
));
422 DbgPrintf(3, _T("AgentConnectionEx::onSnmpTrap(): Cannot find node for IP address %s"), getIpAddr().toString(ipStringBuffer
));
427 * Deploy policy to agent
429 UINT32
AgentConnectionEx::deployPolicy(AgentPolicy
*policy
)
432 NXCPMessage
msg(getProtocolVersion());
434 rqId
= generateRequestId();
436 msg
.setCode(CMD_DEPLOY_AGENT_POLICY
);
437 if (policy
->createDeploymentMessage(&msg
))
439 if (sendMessage(&msg
))
441 rcc
= waitForRCC(rqId
, getCommandTimeout());
445 rcc
= ERR_CONNECTION_BROKEN
;
450 rcc
= ERR_INTERNAL_ERROR
;
456 * Uninstall policy from agent
458 UINT32
AgentConnectionEx::uninstallPolicy(AgentPolicy
*policy
)
461 NXCPMessage
msg(getProtocolVersion());
463 rqId
= generateRequestId();
465 msg
.setCode(CMD_UNINSTALL_AGENT_POLICY
);
466 if (policy
->createUninstallMessage(&msg
))
468 if (sendMessage(&msg
))
470 rcc
= waitForRCC(rqId
, getCommandTimeout());
474 rcc
= ERR_CONNECTION_BROKEN
;
479 rcc
= ERR_INTERNAL_ERROR
;
485 * Process collected data information (for DCI with agent-side cache)
487 UINT32
AgentConnectionEx::processCollectedData(NXCPMessage
*msg
)
489 if (g_flags
& AF_SHUTDOWN
)
490 return ERR_INTERNAL_ERROR
;
494 DbgPrintf(5, _T("AgentConnectionEx::processCollectedData: node ID is 0 for agent session"));
495 return ERR_INTERNAL_ERROR
;
498 Node
*node
= (Node
*)FindObjectById(m_nodeId
, OBJECT_NODE
);
501 DbgPrintf(5, _T("AgentConnectionEx::processCollectedData: cannot find node object (node ID = %d)"), m_nodeId
);
502 return ERR_INTERNAL_ERROR
;
505 int origin
= msg
->getFieldAsInt16(VID_DCI_SOURCE_TYPE
);
506 if ((origin
!= DS_NATIVE_AGENT
) && (origin
!= DS_SNMP_AGENT
))
508 DbgPrintf(5, _T("AgentConnectionEx::processCollectedData: unsupported data source type %d"), origin
);
509 return ERR_INTERNAL_ERROR
;
512 DataCollectionTarget
*target
;
513 uuid targetId
= msg
->getFieldAsGUID(VID_NODE_ID
);
514 if (!targetId
.isNull())
516 NetObj
*object
= FindObjectByGUID(targetId
, -1);
520 nxlog_debug(5, _T("AgentConnectionEx::processCollectedData: cannot find target node with GUID %s"), targetId
.toString(buffer
));
521 return ERR_INTERNAL_ERROR
;
523 if (!object
->isDataCollectionTarget())
526 nxlog_debug(5, _T("AgentConnectionEx::processCollectedData: object with GUID %s is not a data collection target"), targetId
.toString(buffer
));
527 return ERR_INTERNAL_ERROR
;
529 target
= (DataCollectionTarget
*)object
;
536 UINT32 dciId
= msg
->getFieldAsUInt32(VID_DCI_ID
);
537 DCObject
*dcObject
= target
->getDCObjectById(dciId
);
538 if (dcObject
== NULL
)
540 nxlog_debug(5, _T("AgentConnectionEx::processCollectedData: cannot find DCI with ID %d on object %s [%d]"),
541 dciId
, target
->getName(), target
->getId());
542 return ERR_INTERNAL_ERROR
;
545 int type
= msg
->getFieldAsInt16(VID_DCOBJECT_TYPE
);
546 if ((dcObject
->getType() != type
) || (dcObject
->getDataSource() != origin
) || (dcObject
->getAgentCacheMode() != AGENT_CACHE_ON
))
548 nxlog_debug(5, _T("AgentConnectionEx::processCollectedData: DCI %s [%d] on object %s [%d] configuration mismatch"),
549 dcObject
->getName(), dciId
, target
->getName(), target
->getId());
550 return ERR_INTERNAL_ERROR
;
553 time_t t
= msg
->getFieldAsTime(VID_TIMESTAMP
);
554 UINT32 status
= msg
->getFieldAsUInt32(VID_STATUS
);
561 value
= msg
->getFieldAsString(VID_VALUE
);
564 value
= new StringList();
567 value
= new Table(msg
);
570 nxlog_debug(5, _T("AgentConnectionEx::processCollectedData: invalid type %d of DCI %s [%d] on object %s [%d]"),
571 type
, dcObject
->getName(), dciId
, target
->getName(), target
->getId());
572 return ERR_INTERNAL_ERROR
;
574 nxlog_debug(7, _T("AgentConnectionEx::processCollectedData: processing DCI %s [%d] (type=%d) (status=%d) on object %s [%d]"),
575 dcObject
->getName(), dciId
, type
, status
, target
->getName(), target
->getId());
581 if (dcObject
->getStatus() == ITEM_STATUS_NOT_SUPPORTED
)
582 dcObject
->setStatus(ITEM_STATUS_ACTIVE
, true);
583 success
= target
->processNewDCValue(dcObject
, t
, value
);
584 if (t
> dcObject
->getLastPollTime())
585 dcObject
->setLastPollTime(t
);
588 case ERR_UNKNOWN_PARAMETER
:
589 if (dcObject
->getStatus() == ITEM_STATUS_NOT_SUPPORTED
)
590 dcObject
->setStatus(ITEM_STATUS_ACTIVE
, true);
591 dcObject
->processNewError(false, t
);
593 case ERR_NO_SUCH_INSTANCE
:
594 dcObject
->processNewError(true, t
);
596 case ERR_INTERNAL_ERROR
:
597 dcObject
->processNewError(true, t
);
607 delete (StringList
*)value
;
611 return success
? ERR_SUCCESS
: ERR_INTERNAL_ERROR
;
615 * Process collected data information in bulk mode (for DCI with agent-side cache)
617 UINT32
AgentConnectionEx::processBulkCollectedData(NXCPMessage
*request
, NXCPMessage
*response
)
619 if (g_flags
& AF_SHUTDOWN
)
620 return ERR_INTERNAL_ERROR
;
624 DbgPrintf(5, _T("AgentConnectionEx::processBulkCollectedData: node ID is 0 for agent session"));
625 return ERR_INTERNAL_ERROR
;
628 Node
*node
= (Node
*)FindObjectById(m_nodeId
, OBJECT_NODE
);
631 DbgPrintf(5, _T("AgentConnectionEx::processBulkCollectedData: cannot find node object (node ID = %d)"), m_nodeId
);
632 return ERR_INTERNAL_ERROR
;
635 int count
= request
->getFieldAsInt16(VID_NUM_ELEMENTS
);
636 if (count
> MAX_BULK_DATA_BLOCK_SIZE
)
637 count
= MAX_BULK_DATA_BLOCK_SIZE
;
638 DbgPrintf(5, _T("AgentConnectionEx::processBulkCollectedData: %d elements from node %s [%d]"), count
, node
->getName(), node
->getId());
640 BYTE status
[MAX_BULK_DATA_BLOCK_SIZE
];
641 memset(status
, 0, MAX_BULK_DATA_BLOCK_SIZE
);
642 UINT32 fieldId
= VID_ELEMENT_LIST_BASE
;
643 for(int i
= 0; i
< count
; i
++, fieldId
+= 10)
645 int origin
= request
->getFieldAsInt16(fieldId
+ 1);
646 if ((origin
!= DS_NATIVE_AGENT
) && (origin
!= DS_SNMP_AGENT
))
648 nxlog_debug(5, _T("AgentConnectionEx::processBulkCollectedData: unsupported data source type %d (element %d)"), origin
, i
);
649 status
[i
] = BULK_DATA_REC_FAILURE
;
653 DataCollectionTarget
*target
;
654 uuid targetId
= request
->getFieldAsGUID(fieldId
+ 3);
655 if (!targetId
.isNull())
657 NetObj
*object
= FindObjectByGUID(targetId
, -1);
661 nxlog_debug(5, _T("AgentConnectionEx::processBulkCollectedData: cannot find target object with GUID %s (element %d)"),
662 targetId
.toString(buffer
), i
);
663 status
[i
] = BULK_DATA_REC_FAILURE
;
666 if (!object
->isDataCollectionTarget())
669 nxlog_debug(5, _T("AgentConnectionEx::processBulkCollectedData: object with GUID %s (element %d) is not a data collection target"),
670 targetId
.toString(buffer
), i
);
671 status
[i
] = BULK_DATA_REC_FAILURE
;
674 target
= (DataCollectionTarget
*)object
;
681 UINT32 dciId
= request
->getFieldAsUInt32(fieldId
);
682 DCObject
*dcObject
= target
->getDCObjectById(dciId
);
683 if (dcObject
== NULL
)
685 nxlog_debug(5, _T("AgentConnectionEx::processBulkCollectedData: cannot find DCI with ID %d on object %s [%d] (element %d)"),
686 dciId
, target
->getName(), target
->getId(), i
);
687 status
[i
] = BULK_DATA_REC_FAILURE
;
691 int type
= request
->getFieldAsInt16(fieldId
+ 2);
692 if ((type
!= DCO_TYPE_ITEM
) || (dcObject
->getType() != type
) || (dcObject
->getDataSource() != origin
) || (dcObject
->getAgentCacheMode() != AGENT_CACHE_ON
))
694 nxlog_debug(5, _T("AgentConnectionEx::processBulkCollectedData: DCI %s [%d] on object %s [%d] configuration mismatch (element %d)"),
695 dcObject
->getName(), dciId
, target
->getName(), target
->getId(), i
);
696 status
[i
] = BULK_DATA_REC_FAILURE
;
700 void *value
= request
->getFieldAsString(fieldId
+ 5);
701 UINT32 status_code
= request
->getFieldAsUInt32(fieldId
+ 6);
702 nxlog_debug(7, _T("AgentConnectionEx::processBulkCollectedData: processing DCI %s [%d] (type=%d) (status=%d) on object %s [%d] (element %d)"),
703 dcObject
->getName(), dciId
, type
, status
, target
->getName(), target
->getId(), i
);
704 time_t t
= request
->getFieldAsTime(fieldId
+ 4);
711 if (dcObject
->getStatus() == ITEM_STATUS_NOT_SUPPORTED
)
712 dcObject
->setStatus(ITEM_STATUS_ACTIVE
, true);
713 success
= target
->processNewDCValue(dcObject
, t
, value
);
714 if (t
> dcObject
->getLastPollTime())
715 dcObject
->setLastPollTime(t
);
718 case ERR_UNKNOWN_PARAMETER
:
719 if (dcObject
->getStatus() == ITEM_STATUS_NOT_SUPPORTED
)
720 dcObject
->setStatus(ITEM_STATUS_ACTIVE
, true);
721 dcObject
->processNewError(false, t
);
723 case ERR_NO_SUCH_INSTANCE
:
724 dcObject
->processNewError(true, t
);
726 case ERR_INTERNAL_ERROR
:
727 dcObject
->processNewError(true, t
);
732 status
[i
] = success
? BULK_DATA_REC_SUCCESS
: BULK_DATA_REC_FAILURE
;
736 response
->setField(VID_STATUS
, status
, count
);