WIENER_SNMP  1.1
A C/C++ library for MPOD crate access via SNMP
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
WIENER_SNMP.cpp
Go to the documentation of this file.
1 // WIENER SNMP basic SNMP library to Demonstrate C-Access to WIENER-Crates via SNMP
2 // modified for LabView import 04/23/06, Andreas Ruben
3 //
4 // The path to the Net-SNMP include files (default /usr/include) must be added to the
5 // include file search path!
6 // The following libraries must be included:
7 // netsnmp.lib ws2_32.lib
8 // The path to the Net-SNMP library must be added to the linker files.
9 // /usr/lib
10 // path for the WIENER MIB file (mibdirs) c:/usr/share/snmp/mibs
11 
12 #include "WIENER_SNMP.h"
13 #include "version.h"
14 
15 #ifdef _MSC_VER
16 #define strdup _strdup
17 #define vsnprintf vsprintf_s
18 #define strPrintf sprintf_s
19 #else
20 #define strPrintf snprintf
21 #endif
22 
23 #ifndef UNREFERENCED_PARAMETER
24 #define UNREFERENCED_PARAMETER(P) (void)(P)
25 #endif
26 
27 static const char WienerMibFileName[] = "WIENER-CRATE-MIB";
28 static const char DefaultReadCommunity[] = "public";
29 static const char DefaultWriteCommunity[] = "guru";
30 
31 static char *m_readCommunity = (char *)DefaultReadCommunity;
32 static char *m_writeCommunity = (char *)DefaultWriteCommunity;
33 
37 class SnmpObject {
38 public:
39  oid id[MAX_OID_LEN];
40  size_t len;
41  char desc[100];
42 };
43 
44 static SnmpObject moduleIndex[MaxSlotsPerCrate];
45 static SnmpObject moduleDescription[MaxSlotsPerCrate];
47 static SnmpObject moduleHardwareLimitVoltage[MaxSlotsPerCrate];
48 static SnmpObject moduleHardwareLimitCurrent[MaxSlotsPerCrate];
49 static SnmpObject moduleRampSpeedVoltage[MaxSlotsPerCrate];
50 static SnmpObject moduleRampSpeedCurrent[MaxSlotsPerCrate];
51 static SnmpObject moduleStatus[MaxSlotsPerCrate];
52 static SnmpObject moduleEventStatus[MaxSlotsPerCrate];
53 static SnmpObject moduleDoClear[MaxSlotsPerCrate];
54 static SnmpObject moduleAuxiliaryMeasurementTemperature[MaxModuleAuxTemperatures][MaxSlotsPerCrate];
55 
56 static SnmpObject sysDescr;
57 static SnmpObject sysMainSwitch;
58 static SnmpObject sysStatus;
59 static SnmpObject sysVmeSysReset;
60 static SnmpObject outputNumber;
61 static SnmpObject groupsNumber;
62 static SnmpObject highVoltageGroupsSwitch;
63 static SnmpObject lowVoltageGroupsSwitch;
64 static SnmpObject ipStaticAddress;
65 
66 static SnmpObject outputName[MaxChannelsPerCrate];
67 static SnmpObject outputIndex[MaxChannelsPerCrate];
68 static SnmpObject outputGroup[MaxChannelsPerCrate];
69 static SnmpObject outputStatus[MaxChannelsPerCrate];
70 static SnmpObject outputMeasurementSenseVoltage[MaxChannelsPerCrate];
71 static SnmpObject outputMeasurementTerminalVoltage[MaxChannelsPerCrate];
72 static SnmpObject outputMeasurementCurrent[MaxChannelsPerCrate];
73 static SnmpObject outputMeasurementTemperature[MaxChannelsPerCrate];
74 static SnmpObject outputSwitch[MaxChannelsPerCrate];
75 static SnmpObject outputVoltage[MaxChannelsPerCrate];
76 static SnmpObject outputCurrent[MaxChannelsPerCrate];
77 static SnmpObject outputVoltageRiseRate[MaxChannelsPerCrate];
78 static SnmpObject outputVoltageFallRate[MaxChannelsPerCrate];
79 static SnmpObject outputCurrentRiseRate[MaxChannelsPerCrate];
80 static SnmpObject outputCurrentFallRate[MaxChannelsPerCrate];
81 static SnmpObject outputSupervisionBehavior[MaxChannelsPerCrate];
82 static SnmpObject outputSupervisionMinSenseVoltage[MaxChannelsPerCrate];
83 static SnmpObject outputSupervisionMaxSenseVoltage[MaxChannelsPerCrate];
84 static SnmpObject outputSupervisionMaxTerminalVoltage[MaxChannelsPerCrate];
85 static SnmpObject outputSupervisionMaxCurrent[MaxChannelsPerCrate];
86 static SnmpObject outputSupervisionMaxTemperature[MaxChannelsPerCrate];
87 static SnmpObject outputConfigMaxSenseVoltage[MaxChannelsPerCrate];
88 static SnmpObject outputConfigMaxTerminalVoltage[MaxChannelsPerCrate];
89 static SnmpObject outputConfigMaxCurrent[MaxChannelsPerCrate];
90 static SnmpObject outputSupervisionMaxPower[MaxChannelsPerCrate];
91 static SnmpObject outputTripTimeMaxCurrent[MaxChannelsPerCrate];
92 
93 static SnmpObject sensorNumber;
94 static SnmpObject sensorTemperature[MaxSensors];
95 static SnmpObject sensorWarningThreshold[MaxSensors];
96 static SnmpObject sensorFailureThreshold[MaxSensors];
97 
98 //static SnmpObject psFirmwareVersion;
99 static SnmpObject psSerialNumber;
100 static SnmpObject psOperatingTime;
101 static SnmpObject psDirectAccess;
102 static SnmpObject fanNumberOfFans;
103 static SnmpObject fanOperatingTime;
104 //static SnmpObject fanFirmwareVersion;
105 static SnmpObject fanSerialNumber;
106 static SnmpObject fanAirTemperature;
107 static SnmpObject fanSwitchOffDelay;
108 static SnmpObject fanNominalSpeed;
109 static SnmpObject fanSpeed[MaxFans];
110 
111 static SnmpObject psAuxVoltage[MaxPsAuxSupplies];
112 static SnmpObject psAuxCurrent[MaxPsAuxSupplies];
113 
114 static SnmpObject snmpCommunityName[MaxCommunities];
115 
116 static double snmpSetDouble(HSNMP session, const SnmpObject &object, double value);
117 static double snmpGetDouble(HSNMP session, const SnmpObject &object);
118 static int snmpSetInt(HSNMP session, const SnmpObject &object, int value);
119 static int snmpGetInt(HSNMP session, const SnmpObject &object);
120 static char *snmpGetString(HSNMP session, const SnmpObject &object);
121 
122 char snmpStringBuffer[1024];
124 
127 
128 #ifdef _MSC_VER
129 
130 BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
131 {
132  UNREFERENCED_PARAMETER(hModule);
133  UNREFERENCED_PARAMETER(ul_reason_for_call);
134  UNREFERENCED_PARAMETER(lpReserved);
135 
136  return TRUE;
137 }
138 
139 #endif
140 
147 static void sysLog(int priority, const char *format, ...)
148 {
149  UNREFERENCED_PARAMETER(priority);
150 
151  va_list vaPrintf;
152  va_start(vaPrintf, format);
153  vprintf(format, vaPrintf);
154  putchar('\n');
155 
156  // store errors in snmpLastErrorBuffer, which can be read by snmpGetLastError()
157  if (priority == LOG_ERR)
158  vsnprintf(snmpLastErrorBuffer, sizeof(snmpLastErrorBuffer), format, vaPrintf);
159 
160  va_end(vaPrintf);
161 }
162 
163 // Helper functions
164 
173 static int getNode(const char * const node, SnmpObject *object)
174 {
175  object->len = MAX_OID_LEN;
176  if (!get_node(node, object->id, &object->len)) {
177  snmp_log(LOG_ERR, "OID %s not found!\n", node);
178  return false;
179  }
180 
181 #ifdef _MSC_VER
182  strcpy_s(object->desc, sizeof(object->desc), node);
183 #else
184  strncpy(object->desc, node, sizeof(object->desc));
185 #endif
186 
187  return true;
188 }
189 
199 static int getIndexNode(const char * const nodeBase, int index, SnmpObject *object)
200 {
201  char node[100];
202 
203  strPrintf(node, sizeof(node), "%s.%i", nodeBase, index);
204 
205  return getNode(node, object);
206 }
207 
214 {
215  snmp_enable_stderrlog();
216 }
217 
226 void snmpSetFileLog(const char * const fileName)
227 {
228  snmp_enable_filelog(fileName, 1);
229 }
230 
238 unsigned int snmpGetVersion(void)
239 {
240  const uint32_t version[] = { VER_FILEVERSION };
241 
242  return (version[0] << 24) + (version[1] << 16) + (version[2] << 8) + version[3];
243 }
244 
253 {
254  return VER_FILEVERSION_STR;
255 }
256 
261 static void setDefaultSettings(void)
262 {
264 
265  m_readCommunity = (char *)DefaultReadCommunity;
266  m_writeCommunity = (char *)DefaultWriteCommunity;
267 
268  memset(snmpLastErrorBuffer, 0, sizeof(snmpLastErrorBuffer));
269 }
270 
278 int snmpInit(void)
279 {
280  setDefaultSettings();
281 
282  snmp_log(LOG_DEBUG, "*** Initialise SNMP ***\n");
283 
284  init_snmp("WIENER_SNMP_DLL");
285  init_mib(); // init MIB processing
286  if (!read_module(WienerMibFileName)) { // read specific mibs
287  snmp_log(LOG_ERR, "Unable to load SNMP MIB file \"%s\"\n", WienerMibFileName);
288  return false;
289  }
290  snmp_log(LOG_DEBUG, "*** Translate OIDs ***\n");
291 
292  // Translate System OIDS
293  getNode("sysDescr.0", &sysDescr); // FIXME: doesn't work atm in Linux
294 
295  if (
296  (!getNode("sysMainSwitch.0", &sysMainSwitch)) ||
297  (!getNode("sysStatus.0", &sysStatus)) ||
298  (!getNode("sysVmeSysReset.0", &sysVmeSysReset)) ||
299  (!getNode("outputNumber.0", &outputNumber)) ||
300  (!getNode("groupsNumber.0", &groupsNumber)) ||
301  (!getNode("groupsSwitch.64", &highVoltageGroupsSwitch)) ||
302  (!getNode("groupsSwitch.128", &lowVoltageGroupsSwitch)) ||
303  (!getNode("ipStaticAddress.0", &ipStaticAddress)) ||
304 // (!getNode("psFirmwareVersion.0", &psFirmwareVersion)) ||
305  (!getNode("psSerialNumber.0", &psSerialNumber)) ||
306  (!getNode("psOperatingTime.0", &psOperatingTime)) ||
307  (!getNode("psDirectAccess.0", &psDirectAccess)) ||
308  (!getNode("sensorNumber.0", &sensorNumber)) ||
309 // (!getNode("fanFirmwareVersion.0", &fanFirmwareVersion)) ||
310  (!getNode("fanSerialNumber.0", &fanSerialNumber)) ||
311  (!getNode("fanOperatingTime.0", &fanOperatingTime)) ||
312  (!getNode("fanAirTemperature.0", &fanAirTemperature))||
313  (!getNode("fanSwitchOffDelay.0", &fanSwitchOffDelay)) ||
314  (!getNode("fanNominalSpeed.0", &fanNominalSpeed)) ||
315  (!getNode("fanNumberOfFans.0", &fanNumberOfFans))
316  ) {
317  return false;
318  }
319 
320  // Translate module and channel information OIDs
321  for (int slot = 0; slot < MaxSlotsPerCrate; ++slot) {
322 
323  if (
324  (!getIndexNode("moduleIndex", slot + 1, &moduleIndex[slot])) ||
325  (!getIndexNode("moduleDescription", slot + 1, &moduleDescription[slot])) ||
326  (!getIndexNode("moduleAuxiliaryMeasurementVoltage0", slot + 1, &moduleSupply[0][slot])) ||
327  (!getIndexNode("moduleAuxiliaryMeasurementVoltage1", slot + 1, &moduleSupply[1][slot])) ||
328  (!getIndexNode("moduleAuxiliaryMeasurementTemperature0", slot + 1, &moduleAuxiliaryMeasurementTemperature[0][slot])) ||
329  (!getIndexNode("moduleAuxiliaryMeasurementTemperature1", slot + 1, &moduleAuxiliaryMeasurementTemperature[1][slot])) ||
330  (!getIndexNode("moduleAuxiliaryMeasurementTemperature2", slot + 1, &moduleAuxiliaryMeasurementTemperature[2][slot])) ||
331  (!getIndexNode("moduleAuxiliaryMeasurementTemperature3", slot + 1, &moduleAuxiliaryMeasurementTemperature[3][slot])) ||
332  (!getIndexNode("moduleHardwareLimitVoltage", slot + 1, &moduleHardwareLimitVoltage[slot])) ||
333  (!getIndexNode("moduleHardwareLimitCurrent", slot + 1, &moduleHardwareLimitCurrent[slot])) ||
334  (!getIndexNode("moduleRampSpeedVoltage", slot + 1, &moduleRampSpeedVoltage[slot])) ||
335  (!getIndexNode("moduleRampSpeedCurrent", slot + 1, &moduleRampSpeedCurrent[slot])) ||
336  (!getIndexNode("moduleStatus", slot + 1, &moduleStatus[slot])) ||
337  (!getIndexNode("moduleEventStatus", slot + 1, &moduleEventStatus[slot])) ||
338  (!getIndexNode("moduleDoClear", slot + 1, &moduleDoClear[slot]))
339  ) {
340  return false;
341  }
342 
343  int base = MaxChannelsPerSlot * slot; // array index
344 
345  for (int channel = base; channel < base + MaxChannelsPerSlot; ++channel) {
346  if (
347  (!getIndexNode("outputName", channel + 1, &outputName[channel])) ||
348  (!getIndexNode("outputIndex", channel + 1, &outputIndex[channel])) ||
349  (!getIndexNode("outputGroup", channel + 1, &outputGroup[channel])) ||
350  (!getIndexNode("outputStatus", channel + 1, &outputStatus[channel])) ||
351  (!getIndexNode("outputMeasurementSenseVoltage", channel + 1, &outputMeasurementSenseVoltage[channel])) ||
352  (!getIndexNode("outputMeasurementTerminalVoltage", channel + 1, &outputMeasurementTerminalVoltage[channel])) ||
353  (!getIndexNode("outputMeasurementCurrent", channel + 1, &outputMeasurementCurrent[channel])) ||
354  (!getIndexNode("outputMeasurementTemperature", channel + 1, &outputMeasurementTemperature[channel])) ||
355  (!getIndexNode("outputSwitch", channel + 1, &outputSwitch[channel])) ||
356  (!getIndexNode("outputVoltage", channel + 1, &outputVoltage[channel])) ||
357  (!getIndexNode("outputCurrent", channel + 1, &outputCurrent[channel])) ||
358  (!getIndexNode("outputVoltageRiseRate", channel + 1, &outputVoltageRiseRate[channel])) ||
359  (!getIndexNode("outputVoltageFallRate", channel + 1, &outputVoltageFallRate[channel])) ||
360  (!getIndexNode("outputCurrentRiseRate", channel + 1, &outputCurrentRiseRate[channel])) ||
361  (!getIndexNode("outputCurrentFallRate", channel + 1, &outputCurrentFallRate[channel])) ||
362  (!getIndexNode("outputSupervisionBehavior", channel + 1, &outputSupervisionBehavior[channel])) ||
363  (!getIndexNode("outputSupervisionMinSenseVoltage", channel + 1, &outputSupervisionMinSenseVoltage[channel])) ||
364  (!getIndexNode("outputSupervisionMaxSenseVoltage", channel + 1, &outputSupervisionMaxSenseVoltage[channel])) ||
365  (!getIndexNode("outputSupervisionMaxTerminalVoltage", channel + 1, &outputSupervisionMaxTerminalVoltage[channel])) ||
366  (!getIndexNode("outputSupervisionMaxCurrent", channel + 1, &outputSupervisionMaxCurrent[channel])) ||
367 // (!getIndexNode("outputSupervisionMaxTemperature", channel + 1, &outputSupervisionMaxTemperature[channel])) ||
368  (!getIndexNode("outputConfigMaxSenseVoltage", channel + 1, &outputConfigMaxSenseVoltage[channel])) ||
369  (!getIndexNode("outputConfigMaxTerminalVoltage", channel + 1, &outputConfigMaxTerminalVoltage[channel])) ||
370  (!getIndexNode("outputSupervisionMaxPower", channel + 1, &outputSupervisionMaxPower[channel])) ||
371  (!getIndexNode("outputConfigMaxCurrent", channel + 1, &outputConfigMaxCurrent[channel])) ||
372  (!getIndexNode("outputTripTimeMaxCurrent", channel + 1, &outputTripTimeMaxCurrent[channel]))
373  ) {
374  return false;
375  }
376  }
377  }
378 
379  for (int sensor = 0; sensor < MaxSensors; ++sensor)
380  if (
381  (!getIndexNode("sensorTemperature", sensor + 1, &sensorTemperature[sensor])) ||
382  (!getIndexNode("sensorWarningThreshold", sensor + 1, &sensorWarningThreshold[sensor])) ||
383  (!getIndexNode("sensorFailureThreshold", sensor + 1, &sensorFailureThreshold[sensor]))
384  ) {
385  return false;
386  }
387 
388  for (int name = 0; name < MaxCommunities; ++name)
389  if (!getIndexNode("snmpCommunityName", name + 1, &snmpCommunityName[name]))
390  return false;
391 
392  for (int fan = 0; fan < MaxFans; ++fan)
393  if (!getIndexNode("fanSpeed", fan + 1, &fanSpeed[fan]))
394  return false;
395 
396  for (int aux = 0; aux < MaxPsAuxSupplies; ++aux) {
397  if (
398  (!getIndexNode("psAuxiliaryMeasurementVoltage", aux + 1, &psAuxVoltage[aux])) ||
399  (!getIndexNode("psAuxiliaryMeasurementCurrent", aux + 1, &psAuxCurrent[aux]))
400  ) {
401  return false;
402  }
403  }
404 
405  snmp_log(LOG_DEBUG, "*** Initialise SNMP done ***\n");
406  SOCK_STARTUP; // only in main thread
407 
408  return true;
409 }
410 
414 void snmpCleanup(void)
415 {
416  SOCK_CLEANUP;
417 }
418 
428 void snmpSetReadCommunityName(const char * const readCommunityName)
429 {
430  m_readCommunity = strdup(readCommunityName);
431 }
432 
442 void snmpSetWriteCommunityName(const char * const writeCommunityName)
443 {
444  m_writeCommunity = strdup(writeCommunityName);
445 }
446 
456 HSNMP snmpOpen(const char * const ipAddress)
457 {
458  HSNMP session;
459  struct snmp_session snmpSession;
460  snmp_sess_init(&snmpSession); // structure defaults
461  snmpSession.version = SNMP_VERSION_2c;
462  snmpSession.peername = strdup(ipAddress);
463  snmpSession.community = (u_char *)strdup(m_readCommunity);
464  snmpSession.community_len = strlen(m_readCommunity);
465 
466  snmpSession.timeout = 300000; // timeout (us)
467  snmpSession.retries = 2; // retries
468 
469  if (!(session = snmp_sess_open(&snmpSession))) {
470  int liberr, syserr;
471  char *errstr;
472  snmp_error(&snmpSession, &liberr, &syserr, &errstr);
473  snmp_log(LOG_ERR, "Open SNMP session for host \"%s\": %s\n", ipAddress, errstr);
474  free(errstr);
475  return 0;
476  }
477 
478  snmp_log(LOG_INFO, "SNMP session for host \"%s\" opened\n", ipAddress);
479  return session;
480 }
481 
486 void snmpClose(HSNMP session)
487 {
488  if (!session)
489  return;
490 
491  if (!snmp_sess_close(session))
492  snmp_log(LOG_ERR, "Close SNMP session: ERROR\n");
493  else
494  snmp_log(LOG_INFO, "SNMP session closed\n");
495 }
496 
502 char *snmpGetLastError(void)
503 {
504  return snmpLastErrorBuffer;
505 }
506 
507 // System Information Functions
508 
518 char *getSysDescr(HSNMP session)
519 {
520  return snmpGetString(session, sysDescr);
521 }
522 
533 int getMainSwitch(HSNMP session)
534 {
535  return snmpGetInt(session, sysMainSwitch);
536 }
537 
546 int setMainSwitch(HSNMP session, int value)
547 {
548  return snmpSetInt(session, sysMainSwitch, value);
549 }
550 
556 int getMainStatus(HSNMP session)
557 {
558  return snmpGetInt(session, sysStatus);
559 }
560 
566 int getVmeReset(HSNMP session)
567 {
568  return snmpGetInt(session, sysVmeSysReset);
569 }
570 
576 int setVmeReset(HSNMP session)
577 {
578  return snmpSetInt(session, sysVmeSysReset, 1);
579 }
580 
587 {
588  return snmpGetInt(session, ipStaticAddress);
589 }
590 
597 int setIpStaticAddress(HSNMP session, int value)
598 {
599  return snmpSetInt(session, ipStaticAddress, value);
600 }
601 
609 char *getPsSerialNumber(HSNMP session)
610 {
611  return snmpGetString(session, psSerialNumber);
612 }
613 
614 // System Count Functions
615 
621 int getOutputNumber(HSNMP session)
622 {
623  return snmpGetInt(session, outputNumber);
624 }
625 
631 int getOutputGroups(HSNMP session)
632 {
633  return snmpGetInt(session, groupsNumber);
634 }
635 
636 // Output Channel Information
637 
644 int getOutputGroup(HSNMP session, int channel)
645 {
646  if (channel < 0 || channel >= MaxChannelsPerCrate)
647  return 0;
648 
649  return snmpGetInt(session, outputGroup[channel]);
650 }
651 
659 int getChannelStatus(HSNMP session, int channel)
660 {
661  return getOutputStatus(session, channel);
662 }
663 
671 int getOutputStatus(HSNMP session, int channel)
672 {
673  if (channel < 0 || channel >= MaxChannelsPerCrate)
674  return 0;
675 
676  return snmpGetInt(session, outputStatus[channel]);
677 }
678 
686 double getOutputSenseMeasurement(HSNMP session, int channel)
687 {
688  if (channel < 0 || channel >= MaxChannelsPerCrate)
689  return 0;
690 
691  return snmpGetDouble(session, outputMeasurementSenseVoltage[channel]);
692 }
693 
700 double getOutputTerminalMeasurement(HSNMP session, int channel)
701 {
702  if (channel < 0 || channel >= MaxChannelsPerCrate)
703  return 0;
704 
705  return snmpGetDouble(session, outputMeasurementTerminalVoltage[channel]);
706 }
707 
714 double getCurrentMeasurement(HSNMP session, int channel)
715 {
716  if (channel < 0 || channel >= MaxChannelsPerCrate)
717  return 0;
718 
719  return snmpGetDouble(session, outputMeasurementCurrent[channel]);
720 }
721 
730 int getTemperatureMeasurement(HSNMP session, int channel)
731 {
732  if (channel < 0 || channel >= MaxChannelsPerCrate)
733  return 0;
734 
735  return snmpGetInt(session, outputMeasurementTemperature[channel]);
736 }
737 
747 int setChannelSwitch(HSNMP session, int channel, int value)
748 {
749  return setOutputSwitch(session, channel, value);
750 }
751 
761 int setOutputSwitch(HSNMP session, int channel, int value)
762 {
763  if (channel < 0 || channel >= MaxChannelsPerCrate)
764  return 0;
765 
766  return snmpSetInt(session, outputSwitch[channel], value);
767 }
768 
777 int getChannelSwitch(HSNMP session, int channel)
778 {
779  return getOutputSwitch(session, channel);
780 }
781 
790 int getOutputSwitch(HSNMP session, int channel)
791 {
792  if (channel < 0 || channel >= MaxChannelsPerCrate)
793  return 0;
794 
795  return snmpGetInt(session, outputSwitch[channel]);
796 }
797 
804 int setHighVoltageGroupsSwitch(HSNMP session, int value)
805 {
806  return snmpSetInt(session, highVoltageGroupsSwitch, value);
807 }
808 
815 {
816  return snmpGetInt(session, highVoltageGroupsSwitch);
817 }
818 
825 int setLowVoltageGroupsSwitch(HSNMP session, int value)
826 {
827  return snmpSetInt(session, lowVoltageGroupsSwitch, value);
828 }
829 
836 {
837  return snmpGetInt(session, lowVoltageGroupsSwitch);
838 }
839 
846 double getOutputVoltage(HSNMP session, int channel)
847 {
848  if (channel < 0 || channel >= MaxChannelsPerCrate)
849  return 0;
850 
851  return snmpGetDouble(session, outputVoltage[channel]);
852 }
853 
861 double setOutputVoltage(HSNMP session, int channel, double value)
862 {
863  if (channel < 0 || channel >= MaxChannelsPerCrate)
864  return 0;
865 
866  return snmpSetDouble(session, outputVoltage[channel], value);
867 }
868 
875 double getOutputCurrent(HSNMP session, int channel)
876 {
877  if (channel < 0 || channel >= MaxChannelsPerCrate)
878  return 0;
879 
880  return snmpGetDouble(session, outputCurrent[channel]);
881 }
882 
890 double setOutputCurrent(HSNMP session, int channel, double value)
891 {
892  if (channel < 0 || channel >= MaxChannelsPerCrate)
893  return 0;
894 
895  return snmpSetDouble(session, outputCurrent[channel], value);
896 }
897 
907 double getOutputRiseRate(HSNMP session, int channel)
908 {
909  if (channel < 0 || channel >= MaxChannelsPerCrate)
910  return 0;
911 
912  return snmpGetDouble(session, outputVoltageRiseRate[channel]);
913 }
914 
925 double setOutputRiseRate(HSNMP session, int channel, double value)
926 {
927  if (channel < 0 || channel >= MaxChannelsPerCrate)
928  return 0;
929 
930  return snmpSetDouble(session, outputVoltageRiseRate[channel], value);
931 }
932 
942 double getOutputFallRate(HSNMP session, int channel)
943 {
944  if (channel < 0 || channel >= MaxChannelsPerCrate)
945  return 0;
946 
947  return snmpGetDouble(session, outputVoltageFallRate[channel]);
948 }
949 
960 double setOutputFallRate(HSNMP session, int channel, double value)
961 {
962  if (channel < 0 || channel >= MaxChannelsPerCrate)
963  return 0;
964 
965  return snmpSetDouble(session, outputVoltageFallRate[channel], value);
966 }
967 
977 double getOutputCurrentRiseRate(HSNMP session, int channel)
978 {
979  if (channel < 0 || channel >= MaxChannelsPerCrate)
980  return 0;
981 
982  return snmpGetDouble(session, outputCurrentRiseRate[channel]);
983 }
984 
995 double setOutputCurrentRiseRate(HSNMP session, int channel, double value)
996 {
997  if (channel < 0 || channel >= MaxChannelsPerCrate)
998  return 0;
999 
1000  return snmpSetDouble(session, outputCurrentRiseRate[channel], value);
1001 }
1002 
1012 double getOutputCurrentFallRate(HSNMP session, int channel)
1013 {
1014  if (channel < 0 || channel >= MaxChannelsPerCrate)
1015  return 0;
1016 
1017  return snmpGetDouble(session, outputCurrentFallRate[channel]);
1018 }
1019 
1030 double setOutputCurrentFallRate(HSNMP session, int channel, double value)
1031 {
1032  if (channel < 0 || channel >= MaxChannelsPerCrate)
1033  return 0;
1034 
1035  return snmpSetDouble(session, outputCurrentFallRate[channel], value);
1036 }
1037 
1045 int getOutputSupervisionBehavior(HSNMP session, int channel)
1046 {
1047  if (channel < 0 || channel >= MaxChannelsPerCrate)
1048  return 0;
1049 
1050  return snmpGetInt(session, outputSupervisionBehavior[channel]);
1051 }
1052 
1082 int setOutputSupervisionBehavior(HSNMP session, int channel, int value)
1083 {
1084  if (channel < 0 || channel >= MaxChannelsPerCrate)
1085  return 0;
1086 
1087  return snmpSetInt(session, outputSupervisionBehavior[channel], value );
1088 }
1089 
1096 double getOutputSupervisionMinSenseVoltage(HSNMP session, int channel)
1097 {
1098  if (channel < 0 || channel >= MaxChannelsPerCrate)
1099  return 0;
1100 
1101  return snmpGetDouble(session, outputSupervisionMinSenseVoltage[channel]);
1102 }
1103 
1111 double setOutputSupervisionMinSenseVoltage(HSNMP session, int channel, double value)
1112 {
1113  if (channel < 0 || channel >= MaxChannelsPerCrate)
1114  return 0;
1115 
1116  return snmpSetDouble(session, outputSupervisionMinSenseVoltage[channel], value);
1117 }
1118 
1125 double getOutputSupervisionMaxSenseVoltage(HSNMP session, int channel)
1126 {
1127  if (channel < 0 || channel >= MaxChannelsPerCrate)
1128  return 0;
1129 
1130  return snmpGetDouble(session, outputSupervisionMaxSenseVoltage[channel]);
1131 }
1132 
1140 double setOutputSupervisionMaxSenseVoltage(HSNMP session, int channel, double value)
1141 {
1142  if (channel < 0 || channel >= MaxChannelsPerCrate)
1143  return 0;
1144 
1145  return snmpSetDouble(session, outputSupervisionMaxSenseVoltage[channel], value);
1146 }
1147 
1155 double getOutputSupervisionMaxTerminalVoltage(HSNMP session, int channel)
1156 {
1157  if (channel < 0 || channel >= MaxChannelsPerCrate)
1158  return 0;
1159 
1160  return snmpGetDouble(session, outputSupervisionMaxTerminalVoltage[channel]);
1161 }
1162 
1171 double setOutputSupervisionMaxTerminalVoltage(HSNMP session, int channel, double value)
1172 {
1173  if (channel < 0 || channel >= MaxChannelsPerCrate)
1174  return 0;
1175 
1176  return snmpSetDouble(session, outputSupervisionMaxTerminalVoltage[channel], value);
1177 }
1178 
1186 double getOutputSupervisionMaxCurrent(HSNMP session, int channel)
1187 {
1188  if (channel < 0 || channel >= MaxChannelsPerCrate)
1189  return 0;
1190 
1191  return snmpGetDouble(session, outputSupervisionMaxCurrent[channel]);
1192 }
1193 
1202 double setOutputSupervisionMaxCurrent(HSNMP session, int channel, double value)
1203 {
1204  if (channel < 0 || channel >= MaxChannelsPerCrate)
1205  return 0;
1206 
1207  return snmpSetDouble(session, outputSupervisionMaxCurrent[channel], value );
1208 }
1209 
1217 {
1218  if (channel < 0 || channel >= MaxChannelsPerCrate)
1219  return 0;
1220 
1221  return snmpGetInt(session, outputSupervisionMaxTemperature[channel]);
1222 }
1223 
1230 double getOutputConfigMaxSenseVoltage(HSNMP session, int channel)
1231 {
1232  if (channel < 0 || channel >= MaxChannelsPerCrate)
1233  return 0;
1234 
1235  return snmpGetDouble(session, outputConfigMaxSenseVoltage[channel]);
1236 }
1237 
1244 double getOutputConfigMaxTerminalVoltage(HSNMP session, int channel)
1245 {
1246  if (channel < 0 || channel >= MaxChannelsPerCrate)
1247  return 0;
1248 
1249  return snmpGetDouble(session, outputConfigMaxTerminalVoltage[channel]);
1250 }
1251 
1258 double getOutputConfigMaxCurrent(HSNMP session, int channel)
1259 {
1260  if (channel < 0 || channel >= MaxChannelsPerCrate)
1261  return 0;
1262 
1263  return snmpGetDouble(session, outputConfigMaxCurrent[channel]);
1264 }
1265 
1272 double getOutputSupervisionMaxPower(HSNMP session, int channel)
1273 {
1274  if (channel < 0 || channel >= MaxChannelsPerCrate)
1275  return 0;
1276 
1277  return snmpGetDouble(session, outputSupervisionMaxPower[channel]);
1278 }
1279 
1286 int getOutputTripTimeMaxCurrent(HSNMP session, int channel)
1287 {
1288  if (channel < 0 || channel >= MaxChannelsPerCrate)
1289  return 0;
1290 
1291  return snmpGetInt(session, outputTripTimeMaxCurrent[channel]);
1292 }
1293 
1301 int setOutputTripTimeMaxCurrent(HSNMP session, int channel, int delay)
1302 {
1303  if (channel < 0 || channel >= MaxChannelsPerCrate)
1304  return 0;
1305 
1306  return snmpSetInt(session, outputTripTimeMaxCurrent[channel], delay);
1307 }
1308 
1309 // Sensor Information functions
1310 
1312 {
1313  return snmpGetInt(session, sensorNumber);
1314 }
1315 
1316 int getSensorTemp(HSNMP session, int sensor)
1317 {
1318  if (sensor < 0 || sensor > MaxSensors)
1319  return 0;
1320 
1321  return snmpGetInt(session, sensorTemperature[sensor]);
1322 }
1323 
1324 int getSensorWarningTemperature(HSNMP session, int sensor)
1325 {
1326  if (sensor < 0 || sensor > MaxSensors)
1327  return 0;
1328 
1329  return snmpGetInt(session, sensorWarningThreshold[sensor]);
1330 }
1331 
1332 int setSensorWarningTemperature(HSNMP session, int sensor, int value)
1333 {
1334  if (sensor < 0 || sensor > MaxSensors)
1335  return 0;
1336 
1337  return snmpSetInt(session, sensorWarningThreshold[sensor], value);
1338 }
1339 
1340 int getSensorFailureTemperature(HSNMP session, int sensor)
1341 {
1342  if (sensor < 0 || sensor > MaxSensors)
1343  return 0;
1344 
1345  return snmpGetInt(session, sensorFailureThreshold[sensor]);
1346 }
1347 
1348 int setSensorFailureTemperature(HSNMP session, int sensor, int value)
1349 {
1350  if (sensor < 0 || sensor > MaxSensors)
1351  return 0;
1352 
1353  return snmpSetInt(session, sensorFailureThreshold[sensor], value);
1354 }
1355 
1356 // Power Supply specific Functions.
1357 
1364 {
1365  return snmpGetInt(session, psOperatingTime);
1366 }
1367 
1368 double getPsAuxVoltage(HSNMP session, int auxIndex)
1369 {
1370  if ( (auxIndex < 0) || (auxIndex >= MaxPsAuxSupplies) )
1371  return 0.0;
1372 
1373  return snmpGetDouble(session, psAuxVoltage[auxIndex]);
1374 }
1375 
1376 double getPsAuxCurrent(HSNMP session, int auxIndex)
1377 {
1378  if ( (auxIndex < 0) || (auxIndex >= MaxPsAuxSupplies) )
1379  return 0.0;
1380 
1381  return snmpGetDouble(session, psAuxCurrent[auxIndex]);
1382 }
1383 
1384 // Fan Tray Functions
1385 
1387 {
1388  return snmpGetInt(session, fanOperatingTime);
1389 }
1390 
1392 {
1393  return snmpGetInt(session, fanAirTemperature);
1394 }
1395 
1397 {
1398  return snmpGetInt(session, fanSwitchOffDelay);
1399 }
1400 
1401 int setFanSwitchOffDelay(HSNMP session, int value)
1402 {
1403  return snmpSetInt(session, fanSwitchOffDelay, value);
1404 }
1405 
1412 {
1413  return snmpGetInt(session, fanNominalSpeed);
1414 }
1415 
1422 int setFanNominalSpeed(HSNMP session, int value)
1423 {
1424  return snmpSetInt(session, fanNominalSpeed, value );
1425 }
1426 
1428 {
1429  return snmpGetInt(session, fanNumberOfFans);
1430 }
1431 
1432 int getFanSpeed(HSNMP session, int fan)
1433 {
1434  if (fan < 0 || fan > MaxFans)
1435  return 0;
1436 
1437  return snmpGetInt(session, fanSpeed[fan]);
1438 }
1439 
1455 char *getModuleDescription(HSNMP session, int slot)
1456 {
1457  if (slot < 0 || slot >= MaxSlotsPerCrate)
1458  return 0;
1459 
1460  return snmpGetString(session, moduleDescription[slot]);
1461 }
1462 
1470 double getModuleSupply24(HSNMP session, int slot)
1471 {
1472  if (slot < 0 || slot >= MaxSlotsPerCrate)
1473  return 0.0;
1474 
1475  return snmpGetDouble(session, moduleSupply[0][slot]);
1476 }
1477 
1485 double getModuleSupply5(HSNMP session, int slot)
1486 {
1487  if (slot < 0 || slot >= MaxSlotsPerCrate)
1488  return 0.0;
1489 
1490  return snmpGetDouble(session, moduleSupply[1][slot]);
1491 }
1492 
1503 double getModuleAuxTemperature(HSNMP session, int slot, int index)
1504 {
1505  if (slot < 0 || slot >= MaxSlotsPerCrate)
1506  return 0.0;
1507 
1508  if (index < 0 || index >= MaxModuleAuxTemperatures)
1509  return 0.0;
1510 
1511  return snmpGetDouble(session, moduleAuxiliaryMeasurementTemperature[index][slot]);
1512 }
1513 
1522 double getModuleHardwareLimitVoltage(HSNMP session, int slot)
1523 {
1524  if (slot < 0 || slot >= MaxSlotsPerCrate)
1525  return 0.0;
1526 
1527  return snmpGetDouble(session, moduleHardwareLimitVoltage[slot]);
1528 }
1529 
1538 double getModuleHardwareLimitCurrent(HSNMP session, int slot)
1539 {
1540  if (slot < 0 || slot >= MaxSlotsPerCrate)
1541  return 0.0;
1542 
1543  return snmpGetDouble(session, moduleHardwareLimitCurrent[slot]);
1544 }
1545 
1555 double getModuleRampSpeedVoltage(HSNMP session, int slot)
1556 {
1557  if (slot < 0 || slot >= MaxSlotsPerCrate)
1558  return 0.0;
1559 
1560  return snmpGetDouble(session, moduleRampSpeedVoltage[slot]);
1561 }
1562 
1575 double setModuleRampSpeedVoltage(HSNMP session, int slot, double value)
1576 {
1577  if (slot < 0 || slot >= MaxSlotsPerCrate)
1578  return 0.0;
1579 
1580  return snmpSetDouble(session, moduleRampSpeedVoltage[slot], value);
1581 }
1582 
1594 double getModuleRampSpeedCurrent(HSNMP session, int slot)
1595 {
1596  if (slot < 0 || slot >= MaxSlotsPerCrate)
1597  return 0.0;
1598 
1599  return snmpGetDouble(session, moduleRampSpeedCurrent[slot]);
1600 }
1601 
1614 double setModuleRampSpeedCurrent(HSNMP session, int slot, double value)
1615 {
1616  if (slot < 0 || slot >= MaxSlotsPerCrate)
1617  return 0.0;
1618 
1619  return snmpSetDouble(session, moduleRampSpeedCurrent[slot], value);
1620 }
1621 
1630 int getModuleStatus(HSNMP session, int slot)
1631 {
1632  if (slot < 0 || slot >= MaxSlotsPerCrate)
1633  return 0;
1634 
1635  return snmpGetInt(session, moduleStatus[slot]);
1636 }
1637 
1646 int getModuleEventStatus(HSNMP session, int slot)
1647 {
1648  if (slot < 0 || slot >= MaxSlotsPerCrate)
1649  return 0;
1650 
1651  return snmpGetInt(session, moduleEventStatus[slot]);
1652 }
1653 
1663 int setModuleDoClear(HSNMP session, int slot)
1664 {
1665  if (slot < 0 || slot >= MaxSlotsPerCrate)
1666  return 0;
1667 
1668  return snmpSetInt(session, moduleDoClear[slot], 1);
1669 }
1670 
1671 // The rest of the functions are utility functions that actually do the SNMP calls
1672 
1673 static void logErrors(HSNMP session, struct snmp_pdu *response,
1674  const SnmpObject &object, int status, const char *functionName)
1675 {
1676  // FAILURE: print what went wrong!
1677  if (status == STAT_SUCCESS)
1678  snmp_log(LOG_ERR, "%s(%s): Error in packet. Reason: %s\n",
1679  functionName, object.desc, snmp_errstring(response->errstat));
1680  else
1681  snmp_sess_perror("snmpget", snmp_sess_session(session));
1682 }
1683 
1684 static int getIntegerVariable(struct variable_list *vars)
1685 {
1686  if (vars->type == ASN_BIT_STR || vars->type == ASN_OCTET_STR) {
1687  int value = 0;
1688  for (size_t i = 0; i < vars->val_len && i < sizeof(int); ++i)
1689  value |= (vars->val.bitstring[i] << (i * 8));
1690  return value;
1691  } if (vars->type == ASN_OPAQUE_FLOAT)
1692  return (int)*vars->val.floatVal;
1693  else if (vars->type == ASN_OPAQUE_DOUBLE)
1694  return (int)*vars->val.doubleVal;
1695  else if (vars->type == ASN_INTEGER)
1696  return *vars->val.integer;
1697  else if (vars->type == ASN_OCTET_STR)
1698  return *vars->val.integer;
1699  else if (vars->type == ASN_IPADDRESS)
1700  return *vars->val.integer;
1701 
1702  return 0;
1703 }
1704 
1705 static double getDoubleVariable(struct variable_list *vars)
1706 {
1707  if (vars->type == ASN_OPAQUE_FLOAT)
1708  return *vars->val.floatVal;
1709  else if (vars->type == ASN_OPAQUE_DOUBLE)
1710  return *vars->val.doubleVal;
1711  else if (vars->type == ASN_INTEGER)
1712  return (double)*vars->val.integer;
1713 
1714  return 0.0;
1715 }
1716 
1717 static snmp_pdu *prepareSetRequestPdu(void)
1718 {
1719  struct snmp_pdu *pdu = snmp_pdu_create(SNMP_MSG_SET);
1720  pdu->community = (u_char *)strdup(m_writeCommunity);
1721  pdu->community_len = strlen(m_writeCommunity);
1722 
1723  return pdu;
1724 }
1725 
1726 static snmp_pdu *prepareGetRequestPdu()
1727 {
1728  struct snmp_pdu *pdu = snmp_pdu_create(SNMP_MSG_GET);
1729 
1730  return pdu;
1731 }
1732 
1733 static int snmpGetInt(HSNMP session, const SnmpObject &object)
1734 {
1735  int value = 0;
1736 
1737  struct snmp_pdu *pdu = prepareGetRequestPdu();
1738 
1739  snmp_add_null_var(pdu, object.id, object.len); // generate request data
1740 
1741  struct snmp_pdu *response;
1742  int status = snmp_sess_synch_response(session, pdu, &response);
1743 
1744  if (status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR) {
1745  value = getIntegerVariable(response->variables);
1746  } else {
1747  logErrors(session, response, object, status, "snmpGetInt");
1748  return 0;
1749  }
1750 
1751  snmp_free_pdu(response);
1752  return value;
1753 }
1754 
1755 static int snmpSetInt(HSNMP session, const SnmpObject &object, int value)
1756 {
1757  struct snmp_pdu *pdu = prepareSetRequestPdu();
1758 
1759  if (snmp_oid_compare(object.id, object.len, ipStaticAddress.id, ipStaticAddress.len) == 0)
1760  snmp_pdu_add_variable(pdu, object.id, object.len, ASN_IPADDRESS, (u_char *)&value, sizeof(value));
1761  else
1762  snmp_pdu_add_variable(pdu, object.id, object.len, ASN_INTEGER, (u_char *)&value, sizeof(value));
1763 
1764  int result = value;
1765  struct snmp_pdu *response;
1766  int status = snmp_sess_synch_response(session, pdu, &response);
1767 
1768  if (status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR) {
1769  result = getIntegerVariable(response->variables);
1770  } else {
1771  logErrors(session, response, object, status, "snmpSetInt");
1772  return 0;
1773  }
1774 
1775  snmp_free_pdu(response);
1776  return result;
1777 }
1778 
1779 static double snmpGetDouble(HSNMP session, const SnmpObject &object)
1780 {
1781  double value = 0.0;
1782 
1783  struct snmp_pdu *pdu = prepareGetRequestPdu();
1784 
1785  snmp_add_null_var(pdu, object.id, object.len); // generate request data
1786 
1787  struct snmp_pdu *response;
1788  int status = snmp_sess_synch_response(session, pdu, &response);
1789 
1790  if (status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR) {
1791  value = getDoubleVariable(response->variables);
1792  } else {
1793  logErrors(session, response, object, status, "snmpGetDouble");
1794  return 0;
1795  }
1796 
1797  snmp_free_pdu(response);
1798  return value;
1799 }
1800 
1801 static double snmpSetDouble(HSNMP session, const SnmpObject &object, double value)
1802 {
1803  struct snmp_pdu *pdu = prepareSetRequestPdu();
1804 
1805  float v = (float)value;
1806  snmp_pdu_add_variable(pdu, object.id, object.len, ASN_OPAQUE_FLOAT, (u_char *)&v, sizeof(v));
1807 
1808  double result = v;
1809 
1810  struct snmp_pdu *response;
1811  int status = snmp_sess_synch_response(session, pdu, &response);
1812 
1813  if (status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR) {
1814  result = getDoubleVariable(response->variables);
1815  } else {
1816  logErrors(session, response, object, status, "snmpSetDouble");
1817  return 0;
1818  }
1819 
1820  snmp_free_pdu(response);
1821  return result;
1822 }
1823 
1824 static char *snmpGetString(HSNMP session, const SnmpObject &object)
1825 {
1826  struct snmp_pdu *pdu = prepareGetRequestPdu();
1827 
1828  snmp_add_null_var(pdu, object.id, object.len); // generate request data
1829 
1830  struct snmp_pdu *response;
1831  int status = snmp_sess_synch_response(session, pdu, &response);
1832 
1833  memset(snmpStringBuffer, 0, sizeof(snmpStringBuffer));
1834 
1835  if (status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR) {
1836  struct variable_list *vars = response->variables;
1837  if (vars->type == ASN_OCTET_STR) {
1838  size_t len = sizeof(snmpStringBuffer) - 1;
1839  if (len > vars->val_len)
1840  len = vars->val_len;
1841 
1842  memcpy(snmpStringBuffer, vars->val.string, len);
1843  snmpStringBuffer[len] = 0;
1844  }
1845  } else {
1846  logErrors(session, response, object, status, "snmpGetString");
1847  return 0;
1848  }
1849 
1850  snmp_free_pdu(response);
1851  return snmpStringBuffer;
1852 }
1853 
1854 static SnmpIntegerBuffer *snmpGetMultipleInteger(HSNMP session, const SnmpObject *objects, int size)
1855 {
1856  struct snmp_pdu *pdu = prepareGetRequestPdu();
1857 
1858  if (size > MaxChannelsPerSlot)
1859  size = MaxChannelsPerSlot;
1860 
1861  memset(&snmpIntegerBuffer, 0, sizeof(snmpIntegerBuffer));
1862 
1863  for (int i = 0; i < size; ++i)
1864  snmp_add_null_var(pdu, objects[i].id, objects[i].len); // generate request data
1865 
1866  struct snmp_pdu *response;
1867  int status = snmp_sess_synch_response(session, pdu, &response);
1868 
1869  if (status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR) {
1870  struct variable_list *vars;
1871  for (vars = response->variables; vars; vars = vars->next_variable)
1872  snmpIntegerBuffer.value[snmpIntegerBuffer.size++] = getIntegerVariable(vars);
1873  } else {
1874  logErrors(session, response, objects[0], status, "snmpGetMultipleInteger");
1875  return &snmpIntegerBuffer;
1876  }
1877 
1878  snmp_free_pdu(response);
1879  return &snmpIntegerBuffer;
1880 }
1881 
1882 static SnmpIntegerBuffer *snmpSetMultipleInteger(HSNMP session, const SnmpObject *objects, SnmpIntegerBuffer *values)
1883 {
1884  struct snmp_pdu *pdu = prepareSetRequestPdu();
1885 
1886  int size = values->size;
1887  if (size > MaxChannelsPerSlot)
1888  size = MaxChannelsPerSlot;
1889 
1890  for (int i = 0; i < size; ++i) {
1891  int v = values->value[i];
1892  snmp_pdu_add_variable(pdu, objects[i].id, objects[i].len, ASN_INTEGER, (u_char *)&v, sizeof(v));
1893  }
1894 
1895  memset(&snmpIntegerBuffer, 0, sizeof(snmpIntegerBuffer));
1896 
1897  struct snmp_pdu *response;
1898  int status = snmp_sess_synch_response(session, pdu, &response);
1899 
1900  if (status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR) {
1901  struct variable_list *vars;
1902  for (vars = response->variables; vars; vars = vars->next_variable)
1903  snmpIntegerBuffer.value[snmpIntegerBuffer.size++] = getIntegerVariable(vars);
1904  } else {
1905  logErrors(session, response, objects[0], status, "snmpSetMultipleInteger");
1906  return &snmpIntegerBuffer;
1907  }
1908 
1909  snmp_free_pdu(response);
1910  return &snmpIntegerBuffer;
1911 }
1912 
1913 static SnmpDoubleBuffer *snmpGetMultipleDouble(HSNMP session, const SnmpObject *objects, int size)
1914 {
1915  struct snmp_pdu *pdu = prepareGetRequestPdu();
1916 
1917  if (size > MaxChannelsPerSlot)
1918  size = MaxChannelsPerSlot;
1919 
1920  memset(&snmpDoubleBuffer, 0, sizeof(snmpDoubleBuffer));
1921 
1922  for (int i = 0; i < size; ++i)
1923  snmp_add_null_var(pdu, objects[i].id, objects[i].len); // generate request data
1924 
1925  struct snmp_pdu *response;
1926  int status = snmp_sess_synch_response(session, pdu, &response);
1927 
1928  if (status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR) {
1929  struct variable_list *vars;
1930  for (vars = response->variables; vars; vars = vars->next_variable)
1931  snmpDoubleBuffer.value[snmpDoubleBuffer.size++] = getDoubleVariable(vars);
1932  } else {
1933  logErrors(session, response, objects[0], status, "snmpGetMultipleDouble");
1934  return &snmpDoubleBuffer;
1935  }
1936 
1937  snmp_free_pdu(response);
1938 
1939  return &snmpDoubleBuffer;
1940 }
1941 
1942 static SnmpDoubleBuffer *snmpSetMultipleDouble(HSNMP session, const SnmpObject *objects, SnmpDoubleBuffer *values)
1943 {
1944  struct snmp_pdu *pdu = prepareSetRequestPdu();
1945 
1946  int size = values->size;
1947  if (size > MaxChannelsPerSlot)
1948  size = MaxChannelsPerSlot;
1949 
1950  for (int i = 0; i < size; ++i) {
1951  float v = (float)values->value[i];
1952  snmp_pdu_add_variable(pdu, objects[i].id, objects[i].len, ASN_OPAQUE_FLOAT, (u_char *)&v, sizeof(v));
1953  }
1954 
1955  memset(&snmpDoubleBuffer, 0, sizeof(snmpDoubleBuffer));
1956 
1957  struct snmp_pdu *response;
1958  int status = snmp_sess_synch_response(session, pdu, &response);
1959 
1960  if (status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR) {
1961  struct variable_list *vars;
1962  for (vars = response->variables; vars; vars = vars->next_variable)
1963  snmpDoubleBuffer.value[snmpDoubleBuffer.size++] = getDoubleVariable(vars);
1964  } else {
1965  logErrors(session, response, objects[0], status, "snmpSetMultipleDouble");
1966  return &snmpDoubleBuffer;
1967  }
1968 
1969  snmp_free_pdu(response);
1970  return &snmpDoubleBuffer;
1971 }
1972 
1986 {
1987  return getMultipleOutputStatuses(session, start, size);
1988 }
1989 
2001 SnmpIntegerBuffer *getMultipleOutputStatuses(HSNMP session, int start, int size)
2002 {
2003  if (start < 0 || size < 0 || start + size > MaxChannelsPerCrate) {
2004  memset(&snmpIntegerBuffer, 0, sizeof(snmpIntegerBuffer));
2005  return &snmpIntegerBuffer;
2006  }
2007 
2008  return snmpGetMultipleInteger(session, &outputStatus[start], size);
2009 }
2010 
2021 SnmpIntegerBuffer *getMultipleOutputSwitches(HSNMP session, int start, int size)
2022 {
2023  if (start < 0 || size < 0 || start + size > MaxChannelsPerCrate) {
2024  memset(&snmpIntegerBuffer, 0, sizeof(snmpIntegerBuffer));
2025  return &snmpIntegerBuffer;
2026  }
2027 
2028  return snmpGetMultipleInteger(session, &outputSwitch[start], size);
2029 }
2030 
2040 {
2041  if (start < 0 || values->size < 0 || start + values->size > MaxChannelsPerCrate) {
2042  memset(&snmpIntegerBuffer, 0, sizeof(snmpIntegerBuffer));
2043  return &snmpIntegerBuffer;
2044  }
2045 
2046  return snmpSetMultipleInteger(session, &outputSwitch[start], values);
2047 }
2048 
2059 SnmpDoubleBuffer *getMultipleOutputVoltages(HSNMP session, int start, int size)
2060 {
2061  if (start < 0 || size < 0 || start + size > MaxChannelsPerCrate) {
2062  memset(&snmpDoubleBuffer, 0, sizeof(snmpDoubleBuffer));
2063  return &snmpDoubleBuffer;
2064  }
2065 
2066  return snmpGetMultipleDouble(session, &outputVoltage[start], size);
2067 }
2068 
2078 {
2079  if (start < 0 || values->size < 0 || start + values->size > MaxChannelsPerCrate) {
2080  memset(&snmpDoubleBuffer, 0, sizeof(snmpDoubleBuffer));
2081  return &snmpDoubleBuffer;
2082  }
2083 
2084  return snmpSetMultipleDouble(session, &outputVoltage[start], values);
2085 }
2086 
2098 {
2099  return getMultipleOutputMeasurementTerminalVoltages(session, start, size);
2100 }
2101 
2114 {
2115  if (start < 0 || size < 0 || start + size > MaxChannelsPerCrate) {
2116  memset(&snmpDoubleBuffer, 0, sizeof(snmpDoubleBuffer));
2117  return &snmpDoubleBuffer;
2118  }
2119 
2120  return snmpGetMultipleDouble(session, &outputMeasurementTerminalVoltage[start], size);
2121 }
2122 
2132 {
2133  if (start < 0 || size < 0 || start + size > MaxChannelsPerCrate) {
2134  memset(&snmpDoubleBuffer, 0, sizeof(snmpDoubleBuffer));
2135  return &snmpDoubleBuffer;
2136  }
2137 
2138  return snmpGetMultipleDouble(session, &outputConfigMaxTerminalVoltage[start], size);
2139 }
2140 
2149 SnmpDoubleBuffer *getMultipleOutputCurrents(HSNMP session, int start, int size)
2150 {
2151  if (start < 0 || size < 0 || start + size > MaxChannelsPerCrate) {
2152  memset(&snmpDoubleBuffer, 0, sizeof(snmpDoubleBuffer));
2153  return &snmpDoubleBuffer;
2154  }
2155 
2156  return snmpGetMultipleDouble(session, &outputCurrent[start], size);
2157 }
2158 
2168 {
2169  if (start < 0 || values->size < 0 || start + values->size > MaxChannelsPerCrate) {
2170  memset(&snmpDoubleBuffer, 0, sizeof(snmpDoubleBuffer));
2171  return &snmpDoubleBuffer;
2172  }
2173 
2174  return snmpSetMultipleDouble(session, &outputCurrent[start], values);
2175 }
2176 
2190 {
2191  return getMultipleOutputMeasurementCurrents(session, start, size);
2192 }
2193 
2206 {
2207  if (start < 0 || size < 0 || start + size > MaxChannelsPerCrate) {
2208  memset(&snmpDoubleBuffer, 0, sizeof(snmpDoubleBuffer));
2209  return &snmpDoubleBuffer;
2210  }
2211 
2212  return snmpGetMultipleDouble(session, &outputMeasurementCurrent[start], size);
2213 }
2214 
2224 {
2225  if (start < 0 || size < 0 || start + size > MaxChannelsPerCrate) {
2226  memset(&snmpDoubleBuffer, 0, sizeof(snmpDoubleBuffer));
2227  return &snmpDoubleBuffer;
2228  }
2229 
2230  return snmpGetMultipleDouble(session, &outputConfigMaxCurrent[start], size);
2231 }
2232 
2242 {
2243  if (start < 0 || size < 0 || start + size > MaxChannelsPerCrate) {
2244  memset(&snmpIntegerBuffer, 0, sizeof(snmpIntegerBuffer));
2245  return &snmpIntegerBuffer;
2246  }
2247 
2248  return snmpGetMultipleInteger(session, &outputTripTimeMaxCurrent[start], size);
2249 }
2250 
2260 {
2261  if (start < 0 || values->size < 0 || start + values->size > MaxChannelsPerCrate) {
2262  memset(&snmpIntegerBuffer, 0, sizeof(snmpIntegerBuffer));
2263  return &snmpIntegerBuffer;
2264  }
2265 
2266  return snmpSetMultipleInteger(session, &outputTripTimeMaxCurrent[start], values);
2267 }
2268 
2278 {
2279  if (start < 0 || size < 0 || start + size > MaxChannelsPerCrate) {
2280  memset(&snmpIntegerBuffer, 0, sizeof(snmpIntegerBuffer));
2281  return &snmpIntegerBuffer;
2282  }
2283 
2284  return snmpGetMultipleInteger(session, &outputSupervisionBehavior[start], size);
2285 }
2286 
2296 {
2297  if (start < 0 || values->size < 0 || start + values->size > MaxChannelsPerCrate) {
2298  memset(&snmpIntegerBuffer, 0, sizeof(snmpIntegerBuffer));
2299  return &snmpIntegerBuffer;
2300  }
2301 
2302  return snmpSetMultipleInteger(session, &outputSupervisionBehavior[start], values);
2303 }