Subversion Repositories f9daq

Rev

Rev 154 | Blame | Compare with Previous | Last modification | View Log | RSS feed

  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 <windows.h>
  13. #include "toolbox.h"
  14. #include <ansi_c.h>
  15. #include "WIENER_SNMP.h"
  16.  
  17. #define VER_FILEVERSION             1,1,1,0
  18. #define VER_FILEVERSION_STR         "1.1.1.0\0"
  19.  
  20. #ifdef _MSC_VER
  21. #define strdup _strdup
  22. #define vsnprintf vsprintf_s
  23. #define strPrintf sprintf_s
  24. #else
  25. #define strdup StrDup
  26. #define strPrintf snprintf
  27. #endif
  28.  
  29. #ifndef UNREFERENCED_PARAMETER
  30. #define UNREFERENCED_PARAMETER(P) (void)(P)
  31. #endif
  32.  
  33. #define false 0;
  34. #define true  1;
  35.  
  36.  
  37. static const char WienerMibFileName[] = "WIENER-CRATE-MIB";
  38. static const char DefaultReadCommunity[] = "public";  ///< default community name for read operations
  39. static const char DefaultWriteCommunity[] = "guru";   ///< default community name for write operation
  40.  
  41. static char *m_readCommunity = (char *)DefaultReadCommunity;
  42. static char *m_writeCommunity = (char *)DefaultWriteCommunity;
  43.  
  44. /**
  45.  * @brief The SnmpObject class is used internally to resolve OIDs and for the SNMP calls.
  46.  */
  47. //class SnmpObject {
  48. //public:
  49. typedef struct {
  50.         oid    id[MAX_OID_LEN]; ///< The resolved SNMP OID
  51.         size_t len;             ///< The resolved OIDs length in byte
  52.         char   desc[100];       ///< The OIDs textual representation, e.g. "sysDescr.0"
  53. } SnmpObject;
  54. //typedef struct snmp_object SnmpObject;
  55.  
  56. static SnmpObject moduleIndex[MaxSlotsPerCrate];
  57. static SnmpObject moduleDescription[MaxSlotsPerCrate];
  58. static SnmpObject moduleSupply[MaxModuleAuxSupplies][MaxSlotsPerCrate];
  59. static SnmpObject moduleHardwareLimitVoltage[MaxSlotsPerCrate];
  60. static SnmpObject moduleHardwareLimitCurrent[MaxSlotsPerCrate];
  61. static SnmpObject moduleRampSpeedVoltage[MaxSlotsPerCrate];
  62. static SnmpObject moduleRampSpeedCurrent[MaxSlotsPerCrate];
  63. static SnmpObject moduleStatus[MaxSlotsPerCrate];
  64. static SnmpObject moduleEventStatus[MaxSlotsPerCrate];
  65. static SnmpObject moduleDoClear[MaxSlotsPerCrate];
  66. static SnmpObject moduleAuxiliaryMeasurementTemperature[MaxModuleAuxTemperatures][MaxSlotsPerCrate];
  67.  
  68. static SnmpObject sysDescr;
  69. static SnmpObject sysMainSwitch;
  70. static SnmpObject sysStatus;
  71. static SnmpObject sysVmeSysReset;
  72. static SnmpObject outputNumber;
  73. static SnmpObject groupsNumber;
  74. static SnmpObject highVoltageGroupsSwitch;
  75. static SnmpObject lowVoltageGroupsSwitch;
  76. static SnmpObject ipStaticAddress;
  77.  
  78. static SnmpObject outputName[MaxChannelsPerCrate];
  79. static SnmpObject outputIndex[MaxChannelsPerCrate];
  80. static SnmpObject outputGroup[MaxChannelsPerCrate];
  81. static SnmpObject outputStatus[MaxChannelsPerCrate];
  82. static SnmpObject outputMeasurementSenseVoltage[MaxChannelsPerCrate];
  83. static SnmpObject outputMeasurementTerminalVoltage[MaxChannelsPerCrate];
  84. static SnmpObject outputMeasurementCurrent[MaxChannelsPerCrate];
  85. static SnmpObject outputMeasurementTemperature[MaxChannelsPerCrate];
  86. static SnmpObject outputSwitch[MaxChannelsPerCrate];
  87. static SnmpObject outputVoltage[MaxChannelsPerCrate];
  88. static SnmpObject outputCurrent[MaxChannelsPerCrate];
  89. static SnmpObject outputVoltageRiseRate[MaxChannelsPerCrate];
  90. static SnmpObject outputVoltageFallRate[MaxChannelsPerCrate];
  91. static SnmpObject outputCurrentRiseRate[MaxChannelsPerCrate];
  92. static SnmpObject outputCurrentFallRate[MaxChannelsPerCrate];
  93. static SnmpObject outputSupervisionBehavior[MaxChannelsPerCrate];
  94. static SnmpObject outputSupervisionMinSenseVoltage[MaxChannelsPerCrate];
  95. static SnmpObject outputSupervisionMaxSenseVoltage[MaxChannelsPerCrate];
  96. static SnmpObject outputSupervisionMaxTerminalVoltage[MaxChannelsPerCrate];
  97. static SnmpObject outputSupervisionMaxCurrent[MaxChannelsPerCrate];
  98. static SnmpObject outputSupervisionMaxTemperature[MaxChannelsPerCrate];
  99. static SnmpObject outputConfigMaxSenseVoltage[MaxChannelsPerCrate];
  100. static SnmpObject outputConfigMaxTerminalVoltage[MaxChannelsPerCrate];
  101. static SnmpObject outputConfigMaxCurrent[MaxChannelsPerCrate];
  102. static SnmpObject outputSupervisionMaxPower[MaxChannelsPerCrate];
  103. static SnmpObject outputTripTimeMaxCurrent[MaxChannelsPerCrate];
  104.  
  105. static SnmpObject sensorNumber;
  106. static SnmpObject sensorTemperature[MaxSensors];
  107. static SnmpObject sensorWarningThreshold[MaxSensors];
  108. static SnmpObject sensorFailureThreshold[MaxSensors];
  109.  
  110. //static SnmpObject psFirmwareVersion;
  111. static SnmpObject psSerialNumber;
  112. static SnmpObject psOperatingTime;
  113. static SnmpObject psDirectAccess;
  114. static SnmpObject fanNumberOfFans;
  115. static SnmpObject fanOperatingTime;
  116. //static SnmpObject fanFirmwareVersion;
  117. static SnmpObject fanSerialNumber;
  118. static SnmpObject fanAirTemperature;
  119. static SnmpObject fanSwitchOffDelay;
  120. static SnmpObject fanNominalSpeed;
  121. static SnmpObject fanSpeed[MaxFans];
  122.  
  123. static SnmpObject psAuxVoltage[MaxPsAuxSupplies];
  124. static SnmpObject psAuxCurrent[MaxPsAuxSupplies];
  125.  
  126. static SnmpObject snmpCommunityName[MaxCommunities];
  127.  
  128. //static double snmpSetDouble(HSNMP session, const SnmpObject &object, double value);
  129. static double snmpSetDouble(HSNMP session, const SnmpObject *object, double value);
  130. static double snmpGetDouble(HSNMP session, const SnmpObject *object);
  131. static int    snmpSetInt(HSNMP session, const SnmpObject *object, int value);
  132. static int    snmpGetInt(HSNMP session, const SnmpObject *object);
  133. static char  *snmpGetString(HSNMP session, const SnmpObject *object);
  134.  
  135. char snmpStringBuffer[1024];
  136. char snmpLastErrorBuffer[1024];
  137.  
  138. SnmpDoubleBuffer snmpDoubleBuffer;
  139. SnmpIntegerBuffer snmpIntegerBuffer;
  140.  
  141. #ifdef _MSC_VER
  142.  
  143. BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
  144. {
  145.         UNREFERENCED_PARAMETER(hModule);
  146.         UNREFERENCED_PARAMETER(ul_reason_for_call);
  147.         UNREFERENCED_PARAMETER(lpReserved);
  148.  
  149.         return TRUE;
  150. }
  151.  
  152. #endif
  153.  
  154. /**
  155.  * @brief Simple logging function with printf-like usage.
  156.  * @internal
  157.  * @param priority
  158.  * @param format
  159.  */
  160. static void sysLog(int priority, const char *format, ...)
  161. {
  162.         UNREFERENCED_PARAMETER(priority);
  163.  
  164.         va_list vaPrintf;
  165.         va_start(vaPrintf, format);
  166.         vprintf(format, vaPrintf);
  167.         putchar('\n');
  168.  
  169.         // store errors in snmpLastErrorBuffer, which can be read by snmpGetLastError()
  170.         if (priority == LOG_ERR)
  171.                 vsnprintf(snmpLastErrorBuffer, sizeof(snmpLastErrorBuffer), format, vaPrintf);
  172.  
  173.         va_end(vaPrintf);
  174. }
  175.  
  176. // Helper functions
  177.  
  178. /**
  179.  * @brief Resolves the OID from the textual SNMP description
  180.  * and stores the OID in *object.
  181.  * @internal
  182.  * @param node e.g. "sysMainSwitch"
  183.  * @param object the resolved OID
  184.  * @return true on success, false otherwise
  185.  */
  186. //static int getNode(const char * const node, SnmpObject *object)
  187. static int getNode(const char * const node, SnmpObject *object)
  188. {
  189.         object->len = MAX_OID_LEN;
  190.         if (!get_node(node, object->id, &object->len)) {
  191.                 snmp_log(LOG_ERR, "OID %s not found!\n", node);
  192.                 return false;
  193.         }
  194.  
  195. #ifdef _MSC_VER
  196.         strcpy_s(object->desc, sizeof(object->desc), node);
  197. #else
  198.         strncpy(object->desc, node, sizeof(object->desc));
  199. #endif
  200.  
  201.         return true;
  202. }
  203.  
  204. /**
  205.  * @brief Resolves the OID from the textual SNMP description
  206.  * with appended index and stores the OID in *object.
  207.  * @internal
  208.  * @param nodeBase e.g. "outputSwitch"
  209.  * @param index e.g. 100
  210.  * @param object the resolved OID
  211.  * @return true on success, false otherwise
  212.  */
  213. static int getIndexNode(const char * const nodeBase, int index, SnmpObject *object)
  214. {
  215.         char node[100];
  216.  
  217.         strPrintf(node, sizeof(node), "%s.%i", nodeBase, index);
  218.  
  219.         return getNode(node, object);
  220. }
  221.  
  222. /**
  223.  * @brief Activates logging on stderr console.
  224.  * @since 1.1
  225.  * @note This is the default setting.
  226.  */
  227. void snmpSetStdErrLog(void)
  228. {
  229.         snmp_enable_stderrlog();
  230. }
  231.  
  232. /**
  233.  * @brief Activates logging to the file filename.
  234.  * @since 1.1
  235.  * @param fileName The full path to the file where all log
  236.  * information should go to.
  237.  * @note If the specified file already exists,
  238.  * new log information is appended.
  239.  */
  240. void snmpSetFileLog(const char * const fileName)
  241. {
  242.         snmp_enable_filelog(fileName, 1);
  243. }
  244.  
  245. /**
  246.  * @brief Returns the library four digit version number as unsigned int value.
  247.  *
  248.  * This allows to check for a specific version number.
  249.  * @since 1.1
  250.  * @return The version number as unsigned long value, e.g. 0x01010000
  251.  */
  252. unsigned int snmpGetVersion(void)
  253. {
  254.         const uint32_t version[] = { VER_FILEVERSION };
  255.  
  256.         return (version[0] << 24) + (version[1] << 16) + (version[2] << 8) + version[3];
  257. }
  258.  
  259. /**
  260.  * @brief Returns the library four digit version number as null-terminated string.
  261.  *
  262.  * The digits are separated by dots.
  263.  * @since 1.1
  264.  * @return The version number, e.g. "1.1.0.3"
  265.  */
  266. char *snmpGetVersionString(void)
  267. {
  268.         return VER_FILEVERSION_STR;
  269. }
  270.  
  271. /**
  272.  * @brief Setup the default conditions for logging and SNMP passwords.
  273.  * @internal
  274.  */
  275. static void setDefaultSettings(void)
  276. {
  277.         snmpSetStdErrLog();
  278.  
  279.         m_readCommunity = (char *)DefaultReadCommunity;
  280.         m_writeCommunity = (char *)DefaultWriteCommunity;
  281.  
  282.         memset(snmpLastErrorBuffer, 0, sizeof(snmpLastErrorBuffer));
  283. }
  284.  
  285. /**
  286.  * @brief SNMP Initialization.
  287.  *
  288.  * Resolves all needed OIDs from the MIB file and prepares the SNMP communication.
  289.  * The actual connection to a MPOD crate is done with snmpOpen().
  290.  * @return true on success, false otherwise (e.g. an OID could not be resolved)
  291.  */
  292. int snmpInit(void)
  293. {
  294.         setDefaultSettings();
  295.  
  296.         snmp_log(LOG_DEBUG, "*** Initialise SNMP ***\n");
  297.  
  298.         init_snmp("WIENER_SNMP_DLL");
  299.         init_mib();                                                             // init MIB processing
  300.         if (!read_module(WienerMibFileName)) {          // read specific mibs
  301.                 snmp_log(LOG_ERR, "Unable to load SNMP MIB file \"%s\"\n", WienerMibFileName);
  302.                 return false;
  303.         }
  304.         snmp_log(LOG_DEBUG, "*** Translate OIDs ***\n");
  305.  
  306.         // Translate System OIDS
  307.         getNode("sysDescr.0", &sysDescr); // FIXME: doesn't work atm in Linux
  308.  
  309.         if (
  310.                 (!getNode("sysMainSwitch.0",      &sysMainSwitch)) ||
  311.                 (!getNode("sysStatus.0",          &sysStatus)) ||
  312.                 (!getNode("sysVmeSysReset.0",     &sysVmeSysReset)) ||
  313.                 (!getNode("outputNumber.0",       &outputNumber)) ||
  314.                 (!getNode("groupsNumber.0",       &groupsNumber)) ||
  315.                 (!getNode("groupsSwitch.64",      &highVoltageGroupsSwitch)) ||
  316.                 (!getNode("groupsSwitch.128",     &lowVoltageGroupsSwitch)) ||
  317.                 (!getNode("ipStaticAddress.0",    &ipStaticAddress)) ||
  318. //              (!getNode("psFirmwareVersion.0",  &psFirmwareVersion)) ||
  319.                 (!getNode("psSerialNumber.0",     &psSerialNumber)) ||
  320.                 (!getNode("psOperatingTime.0",    &psOperatingTime)) ||
  321.                 (!getNode("psDirectAccess.0",     &psDirectAccess)) ||
  322.                 (!getNode("sensorNumber.0",       &sensorNumber)) ||
  323. //              (!getNode("fanFirmwareVersion.0", &fanFirmwareVersion)) ||
  324.                 (!getNode("fanSerialNumber.0",    &fanSerialNumber)) ||
  325.                 (!getNode("fanOperatingTime.0",   &fanOperatingTime)) ||
  326.                 (!getNode("fanAirTemperature.0",  &fanAirTemperature))||
  327.                 (!getNode("fanSwitchOffDelay.0",  &fanSwitchOffDelay)) ||
  328.                 (!getNode("fanNominalSpeed.0",    &fanNominalSpeed)) ||
  329.                 (!getNode("fanNumberOfFans.0",    &fanNumberOfFans))
  330.         ) {
  331.                 return false;
  332.         }
  333.  
  334.         // Translate module and channel information OIDs
  335.         for (int slot = 0; slot < MaxSlotsPerCrate; ++slot) {
  336.  
  337.                 if (
  338.                         (!getIndexNode("moduleIndex", slot + 1, &moduleIndex[slot])) ||
  339.                         (!getIndexNode("moduleDescription", slot + 1, &moduleDescription[slot])) ||
  340.                         (!getIndexNode("moduleAuxiliaryMeasurementVoltage0", slot + 1, &moduleSupply[0][slot])) ||
  341.                         (!getIndexNode("moduleAuxiliaryMeasurementVoltage1", slot + 1, &moduleSupply[1][slot])) ||
  342.                         (!getIndexNode("moduleAuxiliaryMeasurementTemperature0", slot + 1, &moduleAuxiliaryMeasurementTemperature[0][slot])) ||
  343.                         (!getIndexNode("moduleAuxiliaryMeasurementTemperature1", slot + 1, &moduleAuxiliaryMeasurementTemperature[1][slot])) ||
  344.                         (!getIndexNode("moduleAuxiliaryMeasurementTemperature2", slot + 1, &moduleAuxiliaryMeasurementTemperature[2][slot])) ||
  345.                         (!getIndexNode("moduleAuxiliaryMeasurementTemperature3", slot + 1, &moduleAuxiliaryMeasurementTemperature[3][slot])) ||
  346.                         (!getIndexNode("moduleHardwareLimitVoltage", slot + 1, &moduleHardwareLimitVoltage[slot])) ||
  347.                         (!getIndexNode("moduleHardwareLimitCurrent", slot + 1, &moduleHardwareLimitCurrent[slot])) ||
  348.                         (!getIndexNode("moduleRampSpeedVoltage", slot + 1, &moduleRampSpeedVoltage[slot])) ||
  349.                         (!getIndexNode("moduleRampSpeedCurrent", slot + 1, &moduleRampSpeedCurrent[slot])) ||
  350.                         (!getIndexNode("moduleStatus", slot + 1, &moduleStatus[slot])) ||
  351.                         (!getIndexNode("moduleEventStatus", slot + 1, &moduleEventStatus[slot])) ||
  352.                         (!getIndexNode("moduleDoClear", slot + 1, &moduleDoClear[slot]))
  353.                 ) {
  354.                         return false;
  355.                 }
  356.  
  357.                 int base = MaxChannelsPerSlot * slot; // array index
  358.  
  359.                 for (int channel = base; channel < base + MaxChannelsPerSlot; ++channel) {
  360.                         if (
  361.                                 (!getIndexNode("outputName", channel + 1, &outputName[channel])) ||
  362.                                 (!getIndexNode("outputIndex", channel + 1, &outputIndex[channel])) ||
  363.                                 (!getIndexNode("outputGroup", channel + 1, &outputGroup[channel])) ||
  364.                                 (!getIndexNode("outputStatus", channel + 1, &outputStatus[channel])) ||
  365.                                 (!getIndexNode("outputMeasurementSenseVoltage", channel + 1, &outputMeasurementSenseVoltage[channel])) ||
  366.                                 (!getIndexNode("outputMeasurementTerminalVoltage", channel + 1, &outputMeasurementTerminalVoltage[channel])) ||
  367.                                 (!getIndexNode("outputMeasurementCurrent", channel + 1, &outputMeasurementCurrent[channel])) ||
  368.                                 (!getIndexNode("outputMeasurementTemperature", channel + 1, &outputMeasurementTemperature[channel])) ||
  369.                                 (!getIndexNode("outputSwitch", channel + 1, &outputSwitch[channel])) ||
  370.                                 (!getIndexNode("outputVoltage", channel + 1, &outputVoltage[channel])) ||
  371.                                 (!getIndexNode("outputCurrent", channel + 1, &outputCurrent[channel])) ||
  372.                                 (!getIndexNode("outputVoltageRiseRate", channel + 1, &outputVoltageRiseRate[channel])) ||
  373.                                 (!getIndexNode("outputVoltageFallRate", channel + 1, &outputVoltageFallRate[channel])) ||
  374.                                 (!getIndexNode("outputCurrentRiseRate", channel + 1, &outputCurrentRiseRate[channel])) ||
  375.                                 (!getIndexNode("outputCurrentFallRate", channel + 1, &outputCurrentFallRate[channel])) ||
  376.                                 (!getIndexNode("outputSupervisionBehavior", channel + 1, &outputSupervisionBehavior[channel])) ||
  377.                                 (!getIndexNode("outputSupervisionMinSenseVoltage", channel + 1, &outputSupervisionMinSenseVoltage[channel])) ||
  378.                                 (!getIndexNode("outputSupervisionMaxSenseVoltage", channel + 1, &outputSupervisionMaxSenseVoltage[channel])) ||
  379.                                 (!getIndexNode("outputSupervisionMaxTerminalVoltage", channel + 1, &outputSupervisionMaxTerminalVoltage[channel])) ||
  380.                                 (!getIndexNode("outputSupervisionMaxCurrent", channel + 1, &outputSupervisionMaxCurrent[channel])) ||
  381. //                              (!getIndexNode("outputSupervisionMaxTemperature", channel + 1, &outputSupervisionMaxTemperature[channel])) ||
  382.                                 (!getIndexNode("outputConfigMaxSenseVoltage", channel + 1, &outputConfigMaxSenseVoltage[channel])) ||
  383.                                 (!getIndexNode("outputConfigMaxTerminalVoltage", channel + 1, &outputConfigMaxTerminalVoltage[channel])) ||
  384.                                 (!getIndexNode("outputSupervisionMaxPower", channel + 1, &outputSupervisionMaxPower[channel])) ||
  385.                                 (!getIndexNode("outputConfigMaxCurrent", channel + 1, &outputConfigMaxCurrent[channel])) ||
  386.                                 (!getIndexNode("outputTripTimeMaxCurrent", channel + 1, &outputTripTimeMaxCurrent[channel]))
  387.                         ) {
  388.                                 return false;
  389.                         }
  390.                 }
  391.         }
  392.  
  393.         for (int sensor = 0; sensor < MaxSensors; ++sensor)
  394.                 if (
  395.                         (!getIndexNode("sensorTemperature", sensor + 1, &sensorTemperature[sensor])) ||
  396.                         (!getIndexNode("sensorWarningThreshold", sensor + 1, &sensorWarningThreshold[sensor])) ||
  397.                         (!getIndexNode("sensorFailureThreshold", sensor + 1, &sensorFailureThreshold[sensor]))
  398.                 ) {
  399.                         return false;
  400.                 }
  401.  
  402.         for (int name = 0; name < MaxCommunities; ++name)
  403.                 if (!getIndexNode("snmpCommunityName", name + 1, &snmpCommunityName[name]))
  404.                         return false;
  405.  
  406.         for (int fan = 0; fan < MaxFans; ++fan)
  407.                 if (!getIndexNode("fanSpeed", fan + 1, &fanSpeed[fan]))
  408.                         return false;
  409.  
  410.         for (int aux = 0; aux < MaxPsAuxSupplies; ++aux) {
  411.                 if (
  412.                         (!getIndexNode("psAuxiliaryMeasurementVoltage", aux + 1, &psAuxVoltage[aux])) ||
  413.                         (!getIndexNode("psAuxiliaryMeasurementCurrent", aux + 1, &psAuxCurrent[aux]))
  414.                 ) {
  415.                         return false;
  416.                 }
  417.         }
  418.  
  419.         snmp_log(LOG_DEBUG, "*** Initialise SNMP done ***\n");
  420.         SOCK_STARTUP;                                                                                   // only in main thread
  421.  
  422.         return true;
  423. }
  424.  
  425. /**
  426.  * @brief Additional cleanup. Should be called after snmpClose.
  427.  */
  428. void snmpCleanup(void)
  429. {
  430.         SOCK_CLEANUP;
  431. }
  432.  
  433. /**
  434.  * @brief Set a new read community name for SNMP access.
  435.  *
  436.  * The read community name has to match the configured read community name in the MPOD.
  437.  * The default read community name is "public".
  438.  * @since 1.1
  439.  * @note This function must be called before snmpOpen().
  440.  * @param readCommunityName the new read community name
  441.  */
  442. void snmpSetReadCommunityName(const char * const readCommunityName)
  443. {
  444.         m_readCommunity = strdup(readCommunityName);
  445. }
  446.  
  447. /**
  448.  * @brief Set a new write community name for SNMP access.
  449.  *
  450.  * The write community name has to match the configured write community name in the MPOD.
  451.  * The default write community name is "guru".
  452.  * @since 1.1
  453.  * @note This function must be called before any write access function.
  454.  * @param writeCommunityName the new write community name
  455.  */
  456. void snmpSetWriteCommunityName(const char * const writeCommunityName)
  457. {
  458.         m_writeCommunity = strdup(writeCommunityName);
  459. }
  460.  
  461. /**
  462.  * @brief Opens a SNMP session to the specified ipAddress.
  463.  *
  464.  * This function also sets the number of retries and the timeout value.
  465.  * @param ipAddress a zero-terminated ASCII string representation
  466.  * of an IPv4 address, e.g. "192.168.17.101"
  467.  * @return a handle to the opened SNMP session, which is a required
  468.  * parameter for any further call.
  469.  */
  470. HSNMP snmpOpen(const char * const ipAddress)
  471. {
  472.         HSNMP session;
  473.         struct snmp_session snmpSession;
  474.         snmp_sess_init(&snmpSession);                  // structure defaults
  475.         snmpSession.version = SNMP_VERSION_2c;
  476.         snmpSession.peername = strdup(ipAddress);
  477.         snmpSession.community = (u_char *)strdup(m_readCommunity);
  478.         snmpSession.community_len = strlen(m_readCommunity);
  479.  
  480.         snmpSession.timeout = 300000;   // timeout (us)
  481.         snmpSession.retries = 2;        // retries
  482.  
  483.         if (!(session = snmp_sess_open(&snmpSession))) {
  484.                 int liberr, syserr;
  485.                 char *errstr;
  486.                 snmp_error(&snmpSession, &liberr, &syserr, &errstr);
  487.                 snmp_log(LOG_ERR, "Open SNMP session for host \"%s\": %s\n", ipAddress, errstr);
  488.                 free(errstr);
  489.                 return 0;
  490.         }
  491.  
  492.         snmp_log(LOG_INFO, "SNMP session for host \"%s\" opened\n", ipAddress);
  493.         return session;
  494. }
  495.  
  496. /**
  497.  * @brief Closes the previously opened session specified by session.
  498.  * @param session The handle returned by snmpOpen()
  499.  */
  500. void snmpClose(HSNMP session)
  501. {
  502.         if (!session)
  503.                 return;
  504.  
  505.         if (!snmp_sess_close(session))
  506.                 snmp_log(LOG_ERR, "Close SNMP session: ERROR\n");
  507.         else
  508.                 snmp_log(LOG_INFO, "SNMP session closed\n");
  509. }
  510.  
  511. /**
  512.  * @brief Returns a pointer to a descriptive string for the last failed SNMP operation.
  513.  * @return a pointer to a zero-terminated error string for the last failed
  514.  * SNMP operation. Note: this pointer is valid until the next string operation.
  515.  */
  516. char *snmpGetLastError(void)
  517. {
  518.         return snmpLastErrorBuffer;
  519. }
  520.  
  521. // System Information Functions
  522.  
  523. /**
  524.  * @brief Returns a pointer to the MPOD controller description string.
  525.  *
  526.  * The pointer is valid until the next call of any string function.
  527.  * @param session The handle returned by snmpOpen()
  528.  * @return the MPOD controller description string, containing the
  529.  * controller serial number and firmware releases, e.g.:
  530.  * "WIENER MPOD (4388090, MPOD 2.1.2098.1, MPODslave 1.09, MPOD-BL 1.50 )"
  531.  */
  532. char *getSysDescr(HSNMP session)
  533. {
  534.         return snmpGetString(session, &sysDescr);
  535. }
  536.  
  537. /**
  538.  * @brief Returns the crate power on/off status.
  539.  *
  540.  * The result is the logical "and" between the hardware main switch
  541.  * and the setMainSwitch function.
  542.  * @param session The handle returned by snmpOpen()
  543.  * @return The current on/off status of the crate:
  544.  * 0: crate is powered off
  545.  * 1: crate is powered on
  546.  */
  547. int getMainSwitch(HSNMP session)
  548. {
  549.         return snmpGetInt(session, &sysMainSwitch);
  550. }
  551.  
  552. /**
  553.  * @brief Sets the crate main switch to 1 = on or 0 = off.
  554.  *
  555.  * If the hardware main switch is set to "0" position, this function always returns 0.
  556.  * @param session The handle returned by snmpOpen()
  557.  * @param value 0 = set off, 1 = set on
  558.  * @return The new on/off status of the crate.
  559.  */
  560. int setMainSwitch(HSNMP session, int value)
  561. {
  562.         return snmpSetInt(session, &sysMainSwitch, value);
  563. }
  564.  
  565. /**
  566.  * @brief Returns a bit field with the status of the complete crate.
  567.  * @param session The handle returned by snmpOpen()
  568.  * @return The complete crate status.
  569.  */
  570. int getMainStatus(HSNMP session)
  571. {
  572.         return snmpGetInt(session, &sysStatus);
  573. }
  574.  
  575. /**
  576.  * @brief Returns the VME system reset status.
  577.  * @param session The handle returned by snmpOpen()
  578.  * @return
  579.  */
  580. int getVmeReset(HSNMP session)
  581. {
  582.         return snmpGetInt(session, &sysVmeSysReset);
  583. }
  584.  
  585. /**
  586.  * @brief Initiate a VME system reset.
  587.  * @param session The handle returned by snmpOpen()
  588.  * @return
  589.  */
  590. int setVmeReset(HSNMP session)
  591. {
  592.         return snmpSetInt(session, &sysVmeSysReset, 1);
  593. }
  594.  
  595. /**
  596.  * @brief Returns the static IP address as 32 bit integer.
  597.  * @param session The handle returned by snmpOpen()
  598.  * @return The static IP address.
  599.  */
  600. int getIpStaticAddress(HSNMP session)
  601. {
  602.         return snmpGetInt(session, &ipStaticAddress);
  603. }
  604.  
  605. /**
  606.  * @brief Sets a new static IP address.
  607.  * @param session The handle returned by snmpOpen()
  608.  * @param value The IP address as 32 bit integer
  609.  * @return
  610.  */
  611. int setIpStaticAddress(HSNMP session, int value)
  612. {
  613.         return snmpSetInt(session, &ipStaticAddress, value);
  614. }
  615.  
  616. /**
  617.  * @brief Returns a pointer to a string containing the MPOD controllers serial number.
  618.  *
  619.  * The pointer is valid until the next call of any string function.
  620.  * @param session The handle returned by snmpOpen()
  621.  * @return The crates serial number, e.g. "4388090".
  622.  */
  623. char *getPsSerialNumber(HSNMP session)
  624. {
  625.         return snmpGetString(session, &psSerialNumber);
  626. }
  627.  
  628. // System Count Functions
  629.  
  630. /**
  631.  * @brief Returns the total number of output channels in the crate.
  632.  * @param session The handle returned by snmpOpen()
  633.  * @return The total number of output channels
  634.  */
  635. int getOutputNumber(HSNMP session)
  636. {
  637.         return snmpGetInt(session, &outputNumber);
  638. }
  639.  
  640. /**
  641.  * @brief getOutputGroups
  642.  * @param session The handle returned by snmpOpen()
  643.  * @return
  644.  */
  645. int getOutputGroups(HSNMP session)
  646. {
  647.         return snmpGetInt(session, &groupsNumber);
  648. }
  649.  
  650. // Output Channel Information
  651.  
  652. /**
  653.  * @brief getOutputGroup
  654.  * @param session The handle returned by snmpOpen()
  655.  * @param channel The requested channel in the range of 0...999
  656.  * @return
  657.  */
  658. int getOutputGroup(HSNMP session, int channel)
  659. {
  660.         if (channel < 0 || channel >= MaxChannelsPerCrate)
  661.                 return 0;
  662.  
  663.         return snmpGetInt(session, &outputGroup[channel]);
  664. }
  665.  
  666. /**
  667.  * @brief Returns the channel outputStatus register.
  668.  * @note This function is deprecated. Use getOutputStatus() instead.
  669.  * @param session The handle returned by snmpOpen()
  670.  * @param channel The requested channel in the range of 0...999
  671.  * @return The channels outputStatus register
  672.  */
  673. int getChannelStatus(HSNMP session, int channel)
  674. {
  675.         return getOutputStatus(session, channel);
  676. }
  677.  
  678. /**
  679.  * @brief Returns the channel outputStatus register.
  680.  * @since 1.1
  681.  * @param session The handle returned by snmpOpen()
  682.  * @param channel The requested channel in the range of 0...999
  683.  * @return The channels outputStatus register
  684.  */
  685. int getOutputStatus(HSNMP session, int channel)
  686. {
  687.         if (channel < 0 || channel >= MaxChannelsPerCrate)
  688.                 return 0;
  689.  
  690.         return snmpGetInt(session, &outputStatus[channel]);
  691. }
  692.  
  693. /**
  694.  * @brief Returns the measured output sense voltage for channel in Volt.
  695.  * @note This is only valid for WIENER LV modules.
  696.  * @param session The handle returned by snmpOpen()
  697.  * @param channel The requested channel in the range of 0...999
  698.  * @return
  699.  */
  700. double getOutputSenseMeasurement(HSNMP session, int channel)
  701. {
  702.         if (channel < 0 || channel >= MaxChannelsPerCrate)
  703.                 return 0;
  704.  
  705.         return snmpGetDouble(session, &outputMeasurementSenseVoltage[channel]);
  706. }
  707.  
  708. /**
  709.  * @brief Returns the measured output terminal voltage for channel in Volt.
  710.  * @param session The handle returned by snmpOpen()
  711.  * @param channel The requested channel in the range of 0...999
  712.  * @return The measured output terminal voltage in Volt.
  713.  */
  714. double getOutputTerminalMeasurement(HSNMP session, int channel)
  715. {
  716.         if (channel < 0 || channel >= MaxChannelsPerCrate)
  717.                 return 0;
  718.  
  719.         return snmpGetDouble(session, &outputMeasurementTerminalVoltage[channel]);
  720. }
  721.  
  722. /**
  723.  * @brief Returns the measured output current for channel in Ampere.
  724.  * @param session The handle returned by snmpOpen()
  725.  * @param channel The requested channel in the range of 0...999
  726.  * @return The measured output measurement current in Ampere.
  727.  */
  728. double getCurrentMeasurement(HSNMP session, int channel)
  729. {
  730.         if (channel < 0 || channel >= MaxChannelsPerCrate)
  731.                 return 0;
  732.  
  733.         return snmpGetDouble(session, &outputMeasurementCurrent[channel]);
  734. }
  735.  
  736. /**
  737.  * @brief Returns the measured temperature for channel in Degree Celsius.
  738.  * @note Only WIENER Low Voltage modules have a channel-wise temperature measurement.
  739.  * For iseg HV modules, use getModuleAuxTemperature().
  740.  * @param session The handle returned by snmpOpen()
  741.  * @param channel The requested channel in the range of 0...999
  742.  * @return The measured output temperature in Degree Celsius.
  743.  */
  744. int getTemperatureMeasurement(HSNMP session, int channel)
  745. {
  746.         if (channel < 0 || channel >= MaxChannelsPerCrate)
  747.                 return 0;
  748.  
  749.         return snmpGetInt(session, &outputMeasurementTemperature[channel]);
  750. }
  751.  
  752. /**
  753.  * @brief Change the state of the channel.
  754.  * @note This function is deprecated. Use setOutputSwitch() instead.
  755.  * @param session The handle returned by snmpOpen()
  756.  * @param channel The channel in the range of 0...999
  757.  * @param value One of the following: off (0), on (1),
  758.  * resetEmergencyOff (2), setEmergencyOff (3), clearEvents (10).
  759.  * @return
  760.  */
  761. int setChannelSwitch(HSNMP session, int channel, int value)
  762. {
  763.         return setOutputSwitch(session, channel, value);
  764. }
  765.  
  766. /**
  767.  * @brief Change the state of the channel.
  768.  * @since 1.1
  769.  * @param session The handle returned by snmpOpen()
  770.  * @param channel The channel in the range of 0...999
  771.  * @param value One of the following: off (0), on (1),
  772.  * resetEmergencyOff (2), setEmergencyOff (3), clearEvents (10).
  773.  * @return
  774.  */
  775. int setOutputSwitch(HSNMP session, int channel, int value)
  776. {
  777.         if (channel < 0 || channel >= MaxChannelsPerCrate)
  778.                 return 0;
  779.  
  780.         return snmpSetInt(session, &outputSwitch[channel], value);
  781. }
  782.  
  783. /**
  784.  * @brief Returns the state of the channel.
  785.  * @note This function is deprecated. Use getOutputSwitch() instead.
  786.  * @param session The handle returned by snmpOpen()
  787.  * @param channel The requested channel in the range of 0...999
  788.  * @return One of the following: off (0), on (1),
  789.  * resetEmergencyOff (2), setEmergencyOff (3), clearEvents (10).
  790.  */
  791. int getChannelSwitch(HSNMP session, int channel)
  792. {
  793.         return getOutputSwitch(session, channel);
  794. }
  795.  
  796. /**
  797.  * @brief Returns the state of the channel.
  798.  * @since 1.1
  799.  * @param session The handle returned by snmpOpen()
  800.  * @param channel The requested channel in the range of 0...999
  801.  * @return One of the following: off (0), on (1),
  802.  * resetEmergencyOff (2), setEmergencyOff (3), clearEvents (10).
  803.  */
  804. int getOutputSwitch(HSNMP session, int channel)
  805. {
  806.         if (channel < 0 || channel >= MaxChannelsPerCrate)
  807.                 return 0;
  808.  
  809.         return snmpGetInt(session, &outputSwitch[channel]);
  810. }
  811.  
  812. /**
  813.  * @brief setHighVoltageGroupsSwitch
  814.  * @param session The handle returned by snmpOpen()
  815.  * @param value
  816.  * @return
  817.  */
  818. int setHighVoltageGroupsSwitch(HSNMP session, int value)
  819. {
  820.         return snmpSetInt(session, &highVoltageGroupsSwitch, value);
  821. }
  822.  
  823. /**
  824.  * @brief getHighVoltageGroupsSwitch
  825.  * @param session The handle returned by snmpOpen()
  826.  * @return
  827.  */
  828. int getHighVoltageGroupsSwitch(HSNMP session)
  829. {
  830.         return snmpGetInt(session, &highVoltageGroupsSwitch);
  831. }
  832.  
  833. /**
  834.  * @brief setLowVoltageGroupsSwitch
  835.  * @param session The handle returned by snmpOpen()
  836.  * @param value
  837.  * @return
  838.  */
  839. int setLowVoltageGroupsSwitch(HSNMP session, int value)
  840. {
  841.         return snmpSetInt(session, &lowVoltageGroupsSwitch, value);
  842. }
  843.  
  844. /**
  845.  * @brief getLowVoltageGroupsSwitch
  846.  * @param session The handle returned by snmpOpen()
  847.  * @return
  848.  */
  849. int getLowVoltageGroupsSwitch(HSNMP session)
  850. {
  851.         return snmpGetInt(session, &lowVoltageGroupsSwitch);
  852. }
  853.  
  854. /**
  855.  * @brief Returns the demanded output voltage for channel.
  856.  * @param session The handle returned by snmpOpen()
  857.  * @param channel The requested channel in the range of 0...999
  858.  * @return The demanded output voltage in Volt.
  859.  */
  860. double getOutputVoltage(HSNMP session, int channel)
  861. {
  862.         if (channel < 0 || channel >= MaxChannelsPerCrate)
  863.                 return 0;
  864.  
  865.         return snmpGetDouble(session, &outputVoltage[channel]);
  866. }
  867.  
  868. /**
  869.  * @brief Sets the demanded output voltage for channel.
  870.  * @param session The handle returned by snmpOpen()
  871.  * @param channel The requested channel in the range of 0...999
  872.  * @param value the demanded output voltage in Volt.
  873.  * @return The demanded output voltage in Volt.
  874.  */
  875. double setOutputVoltage(HSNMP session, int channel, double value)
  876. {
  877.         if (channel < 0 || channel >= MaxChannelsPerCrate)
  878.                 return 0;
  879.  
  880.         return snmpSetDouble(session, &outputVoltage[channel], value);
  881. }
  882.  
  883. /**
  884.  * @brief Returns the demanded maximum output current for channel.
  885.  * @param session The handle returned by snmpOpen()
  886.  * @param channel The requested channel in the range of 0...999
  887.  * @return The demanded output current in Ampere.
  888.  */
  889. double getOutputCurrent(HSNMP session, int channel)
  890. {
  891.         if (channel < 0 || channel >= MaxChannelsPerCrate)
  892.                 return 0;
  893.  
  894.         return snmpGetDouble(session, &outputCurrent[channel]);
  895. }
  896.  
  897. /**
  898.  * @brief Sets the demanded maximum output current for channel.
  899.  * @param session The handle returned by snmpOpen()
  900.  * @param channel The channel in the range of 0...999
  901.  * @param value The demanded ouput current in Ampere
  902.  * @return The demanded maximum output current in Ampere.
  903.  */
  904. double setOutputCurrent(HSNMP session, int channel, double value)
  905. {
  906.         if (channel < 0 || channel >= MaxChannelsPerCrate)
  907.                 return 0;
  908.  
  909.         return snmpSetDouble(session, &outputCurrent[channel], value);
  910. }
  911.  
  912. /**
  913.  * @brief Returns the channel voltage rise rate in Volt/second.
  914.  *
  915.  * @note This function is for WIENER LV only.
  916.  * For iseg HV modules, use getModuleRampSpeedVoltage().
  917.  * @param session The handle returned by snmpOpen()
  918.  * @param channel The requested channel in the range of 0...999
  919.  * @return
  920.  */
  921. double getOutputRiseRate(HSNMP session, int channel)
  922. {
  923.         if (channel < 0 || channel >= MaxChannelsPerCrate)
  924.                 return 0;
  925.  
  926.         return snmpGetDouble(session, &outputVoltageRiseRate[channel]);
  927. }
  928.  
  929. /**
  930.  * @brief Sets the channel voltage rise rate in Volt/second.
  931.  *
  932.  * @note This function is for WIENER LV only.
  933.  * For iseg HV modules, use setModuleRampSpeedVoltage().
  934.  * @param session The handle returned by snmpOpen()
  935.  * @param channel The requested channel in the range of 0...999
  936.  * @param value
  937.  * @return
  938.  */
  939. double setOutputRiseRate(HSNMP session, int channel, double value)
  940. {
  941.         if (channel < 0 || channel >= MaxChannelsPerCrate)
  942.                 return 0;
  943.  
  944.         return snmpSetDouble(session, &outputVoltageRiseRate[channel], value);
  945. }
  946.  
  947. /**
  948.  * @brief Returns the channel voltage fall rate in Volt/second.
  949.  *
  950.  * @note This function is for WIENER LV only.
  951.  * For iseg HV modules, use getModuleRampSpeedVoltage().
  952.  * @param session The handle returned by snmpOpen()
  953.  * @param channel The requested channel in the range of 0...999
  954.  * @return
  955.  */
  956. double getOutputFallRate(HSNMP session, int channel)
  957. {
  958.         if (channel < 0 || channel >= MaxChannelsPerCrate)
  959.                 return 0;
  960.  
  961.         return snmpGetDouble(session, &outputVoltageFallRate[channel]);
  962. }
  963.  
  964. /**
  965.  * @brief Sets the channel voltage fall rate in Volt/second.
  966.  *
  967.  * @note This function is for WIENER LV only.
  968.  * For iseg HV modules, use setModuleRampSpeedVoltage().
  969.  * @param session The handle returned by snmpOpen()
  970.  * @param channel The requested channel in the range of 0...999
  971.  * @param value
  972.  * @return
  973.  */
  974. double setOutputFallRate(HSNMP session, int channel, double value)
  975. {
  976.         if (channel < 0 || channel >= MaxChannelsPerCrate)
  977.                 return 0;
  978.  
  979.         return snmpSetDouble(session, &outputVoltageFallRate[channel], value);
  980. }
  981.  
  982. /**
  983.  * @brief Returns the channel current rise rate in Ampere/second.
  984.  *
  985.  * @note This function is for WIENER LV only.
  986.  * For iseg HV modules, use getModuleRampSpeedCurrent().
  987.  * @param session The handle returned by snmpOpen()
  988.  * @param channel The requested channel in the range of 0...999
  989.  * @return
  990.  */
  991. double getOutputCurrentRiseRate(HSNMP session, int channel)
  992. {
  993.         if (channel < 0 || channel >= MaxChannelsPerCrate)
  994.                 return 0;
  995.  
  996.         return snmpGetDouble(session, &outputCurrentRiseRate[channel]);
  997. }
  998.  
  999. /**
  1000.  * @brief Sets the channel current rise rate in Ampere/second.
  1001.  *
  1002.  * @note This function is for WIENER LV only.
  1003.  * For iseg HV modules, use setModuleRampSpeedCurrent().
  1004.  * @param session The handle returned by snmpOpen()
  1005.  * @param channel The requested channel in the range of 0...999
  1006.  * @param value
  1007.  * @return
  1008.  */
  1009. double setOutputCurrentRiseRate(HSNMP session, int channel, double value)
  1010. {
  1011.         if (channel < 0 || channel >= MaxChannelsPerCrate)
  1012.                 return 0;
  1013.  
  1014.         return snmpSetDouble(session, &outputCurrentRiseRate[channel], value);
  1015. }
  1016.  
  1017. /**
  1018.  * @brief Returns the channel current fall rate in Ampere/second.
  1019.  *
  1020.  * @note This function is for WIENER LV only.
  1021.  * For iseg HV modules, use getModuleRampSpeedCurrent().
  1022.  * @param session The handle returned by snmpOpen()
  1023.  * @param channel The requested channel in the range of 0...999
  1024.  * @return
  1025.  */
  1026. double getOutputCurrentFallRate(HSNMP session, int channel)
  1027. {
  1028.         if (channel < 0 || channel >= MaxChannelsPerCrate)
  1029.                 return 0;
  1030.  
  1031.         return snmpGetDouble(session, &outputCurrentFallRate[channel]);
  1032. }
  1033.  
  1034. /**
  1035.  * @brief Sets the channel current fall rate in Ampere/second.
  1036.  *
  1037.  * @note This function is for WIENER LV only.
  1038.  * For iseg HV modules, use setModuleRampSpeedCurrent().
  1039.  * @param session The handle returned by snmpOpen()
  1040.  * @param channel The requested channel in the range of 0...999
  1041.  * @param value
  1042.  * @return
  1043.  */
  1044. double setOutputCurrentFallRate(HSNMP session, int channel, double value)
  1045. {
  1046.         if (channel < 0 || channel >= MaxChannelsPerCrate)
  1047.                 return 0;
  1048.  
  1049.         return snmpSetDouble(session, &outputCurrentFallRate[channel], value);
  1050. }
  1051.  
  1052. /**
  1053.  * @brief Returns a bit field packed into an integer
  1054.  * which define the behavior of the output channel or power supply after failures.
  1055.  * @param session The handle returned by snmpOpen()
  1056.  * @param channel The requested channel in the range of 0...999
  1057.  * @return
  1058.  */
  1059. int getOutputSupervisionBehavior(HSNMP session, int channel)
  1060. {
  1061.         if (channel < 0 || channel >= MaxChannelsPerCrate)
  1062.                 return 0;
  1063.  
  1064.         return snmpGetInt(session, &outputSupervisionBehavior[channel]);
  1065. }
  1066.  
  1067. /**
  1068.  * @brief Set the behavior of the output channel or power supply after failures.
  1069.  *
  1070.  * For each supervision value, a two-bit field exists.
  1071.  * The enumeration of this value (..L+..H*2) is:
  1072.  *           WIENER LV devices
  1073.  *              0           ignore the failure
  1074.  *              1           switch off this channel
  1075.  *              2           switch off all channels with the same group number
  1076.  *              3           switch off the complete crate.
  1077.  *           iseg HV devices
  1078.  *              0           ignore the failure
  1079.  *              1           switch off this channel by ramp down the voltage
  1080.  *              2           switch off this channel by a emergencyOff
  1081.  *              3           switch off the whole board of the HV module by emergencyOff.
  1082.  *           The position of the bit fields in the integer value are:
  1083.  *              Bit 0, 1:   outputFailureMinSenseVoltage
  1084.  *              Bit 2, 3:   outputFailureMaxSenseVoltage
  1085.  *              Bit 4, 5:   outputFailureMaxTerminalVoltage
  1086.  *              Bit 6, 7:   outputFailureMaxCurrent
  1087.  *              Bit 8, 9:   outputFailureMaxTemperature
  1088.  *              Bit 10, 11: outputFailureMaxPower
  1089.  *              Bit 12, 13: outputFailureInhibit
  1090.  *              Bit 14, 15: outputFailureTimeout
  1091.  * @param session The handle returned by snmpOpen()
  1092.  * @param channel The channel (0...999) for which the behaviour should be set
  1093.  * @param value The 16 bit integer with bits set according the preceding table.
  1094.  * @return
  1095.  */
  1096. int setOutputSupervisionBehavior(HSNMP session, int channel, int value)
  1097. {
  1098.         if (channel < 0 || channel >= MaxChannelsPerCrate)
  1099.                 return 0;
  1100.  
  1101.         return snmpSetInt(session, &outputSupervisionBehavior[channel], value );
  1102. }
  1103.  
  1104. /**
  1105.  * @brief getOutputSupervisionMinSenseVoltage
  1106.  * @param session The handle returned by snmpOpen()
  1107.  * @param channel The requested channel in the range of 0...999
  1108.  * @return
  1109.  */
  1110. double getOutputSupervisionMinSenseVoltage(HSNMP session, int channel)
  1111. {
  1112.         if (channel < 0 || channel >= MaxChannelsPerCrate)
  1113.                 return 0;
  1114.  
  1115.         return snmpGetDouble(session, &outputSupervisionMinSenseVoltage[channel]);
  1116. }
  1117.  
  1118. /**
  1119.  * @brief setOutputSupervisionMinSenseVoltage
  1120.  * @param session The handle returned by snmpOpen()
  1121.  * @param channel
  1122.  * @param value
  1123.  * @return
  1124.  */
  1125. double setOutputSupervisionMinSenseVoltage(HSNMP session, int channel, double value)
  1126. {
  1127.         if (channel < 0 || channel >= MaxChannelsPerCrate)
  1128.                 return 0;
  1129.  
  1130.         return snmpSetDouble(session, &outputSupervisionMinSenseVoltage[channel], value);
  1131. }
  1132.  
  1133. /**
  1134.  * @brief getOutputSupervisionMaxSenseVoltage
  1135.  * @param session The handle returned by snmpOpen()
  1136.  * @param channel The requested channel in the range of 0...999
  1137.  * @return
  1138.  */
  1139. double getOutputSupervisionMaxSenseVoltage(HSNMP session, int channel)
  1140. {
  1141.         if (channel < 0 || channel >= MaxChannelsPerCrate)
  1142.                 return 0;
  1143.  
  1144.         return snmpGetDouble(session, &outputSupervisionMaxSenseVoltage[channel]);
  1145. }
  1146.  
  1147. /**
  1148.  * @brief setOutputSupervisionMaxSenseVoltage
  1149.  * @param session The handle returned by snmpOpen()
  1150.  * @param channel
  1151.  * @param value
  1152.  * @return
  1153.  */
  1154. double setOutputSupervisionMaxSenseVoltage(HSNMP session, int channel, double value)
  1155. {
  1156.         if (channel < 0 || channel >= MaxChannelsPerCrate)
  1157.                 return 0;
  1158.  
  1159.         return snmpSetDouble(session, &outputSupervisionMaxSenseVoltage[channel], value);
  1160. }
  1161.  
  1162. /**
  1163.  * @brief If the measured voltage at the power supply output terminals is above this value,
  1164.  * the power supply performs the function defined by setOutputSupervisionBehavior().
  1165.  * @param session The handle returned by snmpOpen()
  1166.  * @param channel The requested channel in the range of 0...999
  1167.  * @return The maximum terminal voltage in Volt
  1168.  */
  1169. double getOutputSupervisionMaxTerminalVoltage(HSNMP session, int channel)
  1170. {
  1171.         if (channel < 0 || channel >= MaxChannelsPerCrate)
  1172.                 return 0;
  1173.  
  1174.         return snmpGetDouble(session, &outputSupervisionMaxTerminalVoltage[channel]);
  1175. }
  1176.  
  1177. /**
  1178.  * @brief If the measured voltage at the power supply output terminals is above this value,
  1179.  * the power supply performs the function defined by setOutputSupervisionBehavior().
  1180.  * @param session The handle returned by snmpOpen()
  1181.  * @param channel the channel (0...999) to set the max. terminal voltage
  1182.  * @param value The maximum terminal voltage in Volt
  1183.  * @return
  1184.  */
  1185. double setOutputSupervisionMaxTerminalVoltage(HSNMP session, int channel, double value)
  1186. {
  1187.         if (channel < 0 || channel >= MaxChannelsPerCrate)
  1188.                 return 0;
  1189.  
  1190.         return snmpSetDouble(session, &outputSupervisionMaxTerminalVoltage[channel], value);
  1191. }
  1192.  
  1193. /**
  1194.  * @brief If the measured current is above this value, the power supply
  1195.  * performs the function defined by setOutputSupervisionBehavior().
  1196.  * @param session The handle returned by snmpOpen()
  1197.  * @param channel The requested channel in the range of 0...999
  1198.  * @return The maximum output current in Ampere
  1199.  */
  1200. double getOutputSupervisionMaxCurrent(HSNMP session, int channel)
  1201. {
  1202.         if (channel < 0 || channel >= MaxChannelsPerCrate)
  1203.                 return 0;
  1204.  
  1205.         return snmpGetDouble(session, &outputSupervisionMaxCurrent[channel]);
  1206. }
  1207.  
  1208. /**
  1209.  * @brief If the measured current is above this value, the power supply
  1210.  * performs the function defined by setOutputSupervisionBehavior().
  1211.  * @param session The handle returned by snmpOpen()
  1212.  * @param channel The channel (0...999) to set the max. current
  1213.  * @param value The maximum current in Ampere
  1214.  * @return
  1215.  */
  1216. double setOutputSupervisionMaxCurrent(HSNMP session, int channel, double value)
  1217. {
  1218.         if (channel < 0 || channel >= MaxChannelsPerCrate)
  1219.                 return 0;
  1220.  
  1221.         return snmpSetDouble(session, &outputSupervisionMaxCurrent[channel], value );
  1222. }
  1223.  
  1224. /**
  1225.  * @brief getOutputSupervisionMaxTemperature
  1226.  * @param session The handle returned by snmpOpen()
  1227.  * @param channel The requested channel in the range of 0...999
  1228.  * @return The maximum temperature in degree Celsius
  1229.  */
  1230. int getOutputSupervisionMaxTemperature(HSNMP session, int channel)
  1231. {
  1232.         if (channel < 0 || channel >= MaxChannelsPerCrate)
  1233.                 return 0;
  1234.  
  1235.         return snmpGetInt(session, &outputSupervisionMaxTemperature[channel]);
  1236. }
  1237.  
  1238. /**
  1239.  * @brief getOutputConfigMaxSenseVoltage
  1240.  * @param session The handle returned by snmpOpen()
  1241.  * @param channel The requested channel in the range of 0...999
  1242.  * @return
  1243.  */
  1244. double getOutputConfigMaxSenseVoltage(HSNMP session, int channel)
  1245. {
  1246.         if (channel < 0 || channel >= MaxChannelsPerCrate)
  1247.                 return 0;
  1248.  
  1249.         return snmpGetDouble(session, &outputConfigMaxSenseVoltage[channel]);
  1250. }
  1251.  
  1252. /**
  1253.  * @brief getOutputConfigMaxTerminalVoltage
  1254.  * @param session The handle returned by snmpOpen()
  1255.  * @param channel The requested channel in the range of 0...999
  1256.  * @return
  1257.  */
  1258. double getOutputConfigMaxTerminalVoltage(HSNMP session, int channel)
  1259. {
  1260.         if (channel < 0 || channel >= MaxChannelsPerCrate)
  1261.                 return 0;
  1262.  
  1263.         return snmpGetDouble(session, &outputConfigMaxTerminalVoltage[channel]);
  1264. }
  1265.  
  1266. /**
  1267.  * @brief getOutputConfigMaxCurrent
  1268.  * @param session The handle returned by snmpOpen()
  1269.  * @param channel The requested channel in the range of 0...999
  1270.  * @return
  1271.  */
  1272. double getOutputConfigMaxCurrent(HSNMP session, int channel)
  1273. {
  1274.         if (channel < 0 || channel >= MaxChannelsPerCrate)
  1275.                 return 0;
  1276.  
  1277.         return snmpGetDouble(session, &outputConfigMaxCurrent[channel]);
  1278. }
  1279.  
  1280. /**
  1281.  * @brief getOutputSupervisionMaxPower
  1282.  * @param session The handle returned by snmpOpen()
  1283.  * @param channel The requested channel in the range of 0...999
  1284.  * @return
  1285.  */
  1286. double getOutputSupervisionMaxPower(HSNMP session, int channel)
  1287. {
  1288.         if (channel < 0 || channel >= MaxChannelsPerCrate)
  1289.                 return 0;
  1290.  
  1291.         return snmpGetDouble(session, &outputSupervisionMaxPower[channel]);
  1292. }
  1293.  
  1294. /**
  1295.  * @brief Returns the time span for the delayed trip function.
  1296.  * @param session The handle returned by snmpOpen()
  1297.  * @param channel The requested channel in the range of 0...999
  1298.  * @return the trip delay time (0...4000 ms)
  1299.  */
  1300. int getOutputTripTimeMaxCurrent(HSNMP session, int channel)
  1301. {
  1302.         if (channel < 0 || channel >= MaxChannelsPerCrate)
  1303.                 return 0;
  1304.  
  1305.         return snmpGetInt(session, &outputTripTimeMaxCurrent[channel]);
  1306. }
  1307.  
  1308. /**
  1309.  * @brief Defines a span for the delayed trip function.
  1310.  * @param session The handle returned by snmpOpen()
  1311.  * @param channel The channel (0...999) for which to set the delayed trip
  1312.  * @param delay The trip delay time (0...4000 ms)
  1313.  * @return
  1314.  */
  1315. int setOutputTripTimeMaxCurrent(HSNMP session, int channel, int delay)
  1316. {
  1317.         if (channel < 0 || channel >= MaxChannelsPerCrate)
  1318.                 return 0;
  1319.  
  1320.         return snmpSetInt(session, &outputTripTimeMaxCurrent[channel], delay);
  1321. }
  1322.  
  1323. // Sensor Information functions
  1324.  
  1325. int getSensorNumber(HSNMP session)
  1326. {
  1327.         return snmpGetInt(session, &sensorNumber);
  1328. }
  1329.  
  1330. int getSensorTemp(HSNMP session, int sensor)
  1331. {
  1332.         if (sensor < 0 || sensor > MaxSensors)
  1333.                 return 0;
  1334.  
  1335.         return snmpGetInt(session, &sensorTemperature[sensor]);
  1336. }
  1337.  
  1338. int getSensorWarningTemperature(HSNMP session, int sensor)
  1339. {
  1340.         if (sensor < 0 || sensor > MaxSensors)
  1341.                 return 0;
  1342.  
  1343.         return snmpGetInt(session, &sensorWarningThreshold[sensor]);
  1344. }
  1345.  
  1346. int setSensorWarningTemperature(HSNMP session, int sensor, int value)
  1347. {
  1348.         if (sensor < 0 || sensor > MaxSensors)
  1349.                 return 0;
  1350.  
  1351.         return snmpSetInt(session, &sensorWarningThreshold[sensor], value);
  1352. }
  1353.  
  1354. int getSensorFailureTemperature(HSNMP session, int sensor)
  1355. {
  1356.         if (sensor < 0 || sensor > MaxSensors)
  1357.                 return 0;
  1358.  
  1359.         return snmpGetInt(session, &sensorFailureThreshold[sensor]);
  1360. }
  1361.  
  1362. int setSensorFailureTemperature(HSNMP session, int sensor, int value)
  1363. {
  1364.         if (sensor < 0 || sensor > MaxSensors)
  1365.                 return 0;
  1366.  
  1367.         return snmpSetInt(session, &sensorFailureThreshold[sensor], value);
  1368. }
  1369.  
  1370. // Power Supply specific Functions.
  1371.  
  1372. /**
  1373.  * @brief Returns the crates operating time in seconds.
  1374.  * @param session The handle returned by snmpOpen()
  1375.  * @return
  1376.  */
  1377. int getPsOperatingTime(HSNMP session)
  1378. {
  1379.         return snmpGetInt(session, &psOperatingTime);
  1380. }
  1381.  
  1382. double getPsAuxVoltage(HSNMP session, int auxIndex)
  1383. {
  1384.         if ( (auxIndex < 0) || (auxIndex >= MaxPsAuxSupplies) )
  1385.                 return 0.0;
  1386.  
  1387.         return snmpGetDouble(session, &psAuxVoltage[auxIndex]);
  1388. }
  1389.  
  1390. double getPsAuxCurrent(HSNMP session, int auxIndex)
  1391. {
  1392.         if ( (auxIndex < 0) || (auxIndex >= MaxPsAuxSupplies) )
  1393.                 return 0.0;
  1394.  
  1395.         return snmpGetDouble(session, &psAuxCurrent[auxIndex]);
  1396. }
  1397.  
  1398. // Fan Tray Functions
  1399.  
  1400. int getFanOperatingTime(HSNMP session)
  1401. {
  1402.         return snmpGetInt(session, &fanOperatingTime);
  1403. }
  1404.  
  1405. int getFanAirTemperature(HSNMP session)
  1406. {
  1407.         return snmpGetInt(session, &fanAirTemperature);
  1408. }
  1409.  
  1410. int getFanSwitchOffDelay(HSNMP session)
  1411. {
  1412.         return snmpGetInt(session, &fanSwitchOffDelay);
  1413. }
  1414.  
  1415. int setFanSwitchOffDelay(HSNMP session, int value)
  1416. {
  1417.         return snmpSetInt(session, &fanSwitchOffDelay, value);
  1418. }
  1419.  
  1420. /**
  1421.  * @brief Returns the MPODs fan rotation speed in revolutions per minute.
  1422.  * @param session The handle returned by snmpOpen()
  1423.  * @return
  1424.  */
  1425. int getFanNominalSpeed(HSNMP session)
  1426. {
  1427.         return snmpGetInt(session, &fanNominalSpeed);
  1428. }
  1429.  
  1430. /**
  1431.  * @brief Sets the MPODs fan rotation speed in revolutions per minute.
  1432.  * @param session The handle returned by snmpOpen()
  1433.  * @param value 1200..3600. 0 turns off the crates fans.
  1434.  * @return
  1435.  */
  1436. int setFanNominalSpeed(HSNMP session, int value)
  1437. {
  1438.         return snmpSetInt(session, &fanNominalSpeed, value );
  1439. }
  1440.  
  1441. int getFanNumberOfFans(HSNMP session)
  1442. {
  1443.         return snmpGetInt(session, &fanNumberOfFans);
  1444. }
  1445.  
  1446. int getFanSpeed(HSNMP session, int fan)
  1447. {
  1448.         if (fan < 0 || fan > MaxFans)
  1449.                 return 0;
  1450.  
  1451.         return snmpGetInt(session, &fanSpeed[fan]);
  1452. }
  1453.  
  1454. /**
  1455.  * @brief Returns a pointer to the module description string.
  1456.  *
  1457.  * The pointer is valid until the next call of any string function.
  1458.  * @param session The handle returned by snmpOpen()
  1459.  * @param slot The modules slot position in the crate (0...9)
  1460.  * @return A string with the following contents, separated by comma and space:
  1461.  * - The module vendor ("iseg" or "WIENER")
  1462.  * - The module type name
  1463.  * - The channel number
  1464.  * - The module serial number (optional)
  1465.  * - The module firmware release (optional)
  1466.  *
  1467.  * Example: "iseg, E24D1, 24, 715070, 5.14"
  1468.  */
  1469. char *getModuleDescription(HSNMP session, int slot)
  1470. {
  1471.         if (slot < 0 || slot >= MaxSlotsPerCrate)
  1472.                 return 0;
  1473.  
  1474.         return snmpGetString(session, &moduleDescription[slot]);
  1475. }
  1476.  
  1477. /**
  1478.  * @brief Returns the measured value of the modules +24 Volt line.
  1479.  * @note This function is for iseg HV modules only.
  1480.  * @param session The handle returned by snmpOpen()
  1481.  * @param slot the modules slot position in the crate (0...9)
  1482.  * @return the measured +24 Volt line voltage in Volt.
  1483.  */
  1484. double getModuleSupply24(HSNMP session, int slot)
  1485. {
  1486.         if (slot < 0 || slot >= MaxSlotsPerCrate)
  1487.                 return 0.0;
  1488.  
  1489.         return snmpGetDouble(session, &moduleSupply[0][slot]);
  1490. }
  1491.  
  1492. /**
  1493.  * @brief Returns the measured value of the modules +5 Volt line.
  1494.  * @note This function is for iseg HV modules only.
  1495.  * @param session The handle returned by snmpOpen()
  1496.  * @param slot the modules slot position in the crate (0...9)
  1497.  * @return the measured +5 Volt line voltage in Volt.
  1498.  */
  1499. double getModuleSupply5(HSNMP session, int slot)
  1500. {
  1501.         if (slot < 0 || slot >= MaxSlotsPerCrate)
  1502.                 return 0.0;
  1503.  
  1504.         return snmpGetDouble(session, &moduleSupply[1][slot]);
  1505. }
  1506.  
  1507. /**
  1508.  * @brief Returns the measured value of one of the modules temperature sensors.
  1509.  *
  1510.  * @note This function is for iseg HV modules only.
  1511.  * @param session The handle returned by snmpOpen()
  1512.  * @param slot The modules slot position in the crate (0...9)
  1513.  * @param index The temperature sensor index (0...3)
  1514.  * @note Most modules only have one temperature sensor at index 0.
  1515.  * @return
  1516.  */
  1517. double getModuleAuxTemperature(HSNMP session, int slot, int index)
  1518. {
  1519.         if (slot < 0 || slot >= MaxSlotsPerCrate)
  1520.                 return 0.0;
  1521.  
  1522.         if (index < 0 || index >= MaxModuleAuxTemperatures)
  1523.                 return 0.0;
  1524.  
  1525.         return snmpGetDouble(session, &moduleAuxiliaryMeasurementTemperature[index][slot]);
  1526. }
  1527.  
  1528. /**
  1529.  * @brief Returns the modules hardware voltage limit in percent.
  1530.  *
  1531.  * @note This function is for iseg HV modules only.
  1532.  * @param session The handle returned by snmpOpen()
  1533.  * @param slot The modules slot position in the crate (0...9)
  1534.  * @return The modules hardware voltage limit in percent (2...102)
  1535.  */
  1536. double getModuleHardwareLimitVoltage(HSNMP session, int slot)
  1537. {
  1538.         if (slot < 0 || slot >= MaxSlotsPerCrate)
  1539.                 return 0.0;
  1540.  
  1541.         return snmpGetDouble(session, &moduleHardwareLimitVoltage[slot]);
  1542. }
  1543.  
  1544. /**
  1545.  * @brief Returns the modules hardware current limit in percent.
  1546.  *
  1547.  * @note This function is for iseg HV modules only.
  1548.  * @param session The handle returned by snmpOpen()
  1549.  * @param slot The modules slot position in the crate (0...9)
  1550.  * @return The modules hardware current limit in percent (2...102)
  1551.  */
  1552. double getModuleHardwareLimitCurrent(HSNMP session, int slot)
  1553. {
  1554.         if (slot < 0 || slot >= MaxSlotsPerCrate)
  1555.                 return 0.0;
  1556.  
  1557.         return snmpGetDouble(session, &moduleHardwareLimitCurrent[slot]);
  1558. }
  1559.  
  1560. /**
  1561.  * @brief Returns the modules voltage ramp speed in percent.
  1562.  *
  1563.  * @note This function is for iseg HV modules only.
  1564.  * iseg modules have one common ramp speed for all channels.
  1565.  * @param session The handle returned by snmpOpen()
  1566.  * @param slot The modules slot position in the crate (0...9)
  1567.  * @return The modules voltage ramp speed in percent
  1568.  */
  1569. double getModuleRampSpeedVoltage(HSNMP session, int slot)
  1570. {
  1571.         if (slot < 0 || slot >= MaxSlotsPerCrate)
  1572.                 return 0.0;
  1573.  
  1574.         return snmpGetDouble(session, &moduleRampSpeedVoltage[slot]);
  1575. }
  1576.  
  1577. /**
  1578.  * @brief Sets the modules voltage ramp speed in percent.
  1579.  *
  1580.  * @note This function is for iseg HV modules only.
  1581.  *
  1582.  * iseg modules have one common ramp speed for all channels.
  1583.  * @param session The handle returned by snmpOpen()
  1584.  * @param slot the modules slot position in the crate (0...9)
  1585.  * @param value The new voltage ramp speed in percent
  1586.  * @note For most modules, the range is 0.001...20 percent.
  1587.  * @return The new voltage ramp speed in percent
  1588.  */
  1589. double setModuleRampSpeedVoltage(HSNMP session, int slot, double value)
  1590. {
  1591.         if (slot < 0 || slot >= MaxSlotsPerCrate)
  1592.                 return 0.0;
  1593.  
  1594.         return snmpSetDouble(session, &moduleRampSpeedVoltage[slot], value);
  1595. }
  1596.  
  1597. /**
  1598.  * @brief Returns the modules current ramp speed in percent.
  1599.  *
  1600.  * @note This function is for iseg HV modules only.
  1601.  *
  1602.  * iseg modules have one common ramp speed for all channels.
  1603.  * This item is only valid for modules with constant current regulation.
  1604.  * @param session The handle returned by snmpOpen()
  1605.  * @param slot The modules slot position in the crate (0...9)
  1606.  * @return The modules current ramp speed in percent
  1607.  */
  1608. double getModuleRampSpeedCurrent(HSNMP session, int slot)
  1609. {
  1610.         if (slot < 0 || slot >= MaxSlotsPerCrate)
  1611.                 return 0.0;
  1612.  
  1613.         return snmpGetDouble(session, &moduleRampSpeedCurrent[slot]);
  1614. }
  1615.  
  1616. /**
  1617.  * @brief Sets the modules current ramp speed in percent.
  1618.  *
  1619.  * @note This function is for iseg HV modules only.
  1620.  *
  1621.  * iseg modules have one common ramp speed for all channels.
  1622.  * This item is only valid for modules with constant current regulation.
  1623.  * @param session The handle returned by snmpOpen()
  1624.  * @param slot The modules slot position in the crate (0...9)
  1625.  * @param value The new current ramp speed in percent
  1626.  * @return The new current ramp speed in percent
  1627.  */
  1628. double setModuleRampSpeedCurrent(HSNMP session, int slot, double value)
  1629. {
  1630.         if (slot < 0 || slot >= MaxSlotsPerCrate)
  1631.                 return 0.0;
  1632.  
  1633.         return snmpSetDouble(session, &moduleRampSpeedCurrent[slot], value);
  1634. }
  1635.  
  1636. /**
  1637.  * @brief Returns the value of the module status register.
  1638.  *
  1639.  * @note This function is for iseg HV modules only.
  1640.  * @param session The handle returned by snmpOpen()
  1641.  * @param slot The modules slot position in the crate (0...9)
  1642.  * @return The module status register
  1643.  */
  1644. int getModuleStatus(HSNMP session, int slot)
  1645. {
  1646.         if (slot < 0 || slot >= MaxSlotsPerCrate)
  1647.                 return 0;
  1648.  
  1649.         return snmpGetInt(session, &moduleStatus[slot]);
  1650. }
  1651.  
  1652. /**
  1653.  * @brief Returns the value of the module event status register.
  1654.  *
  1655.  * @note This function is for iseg HV modules only.
  1656.  * @param session The handle returned by snmpOpen()
  1657.  * @param slot the modules slot position in the crate (0...9)
  1658.  * @return The module event status register
  1659.  */
  1660. int getModuleEventStatus(HSNMP session, int slot)
  1661. {
  1662.         if (slot < 0 || slot >= MaxSlotsPerCrate)
  1663.                 return 0;
  1664.  
  1665.         return snmpGetInt(session, &moduleEventStatus[slot]);
  1666. }
  1667.  
  1668. /**
  1669.  * @brief Clears all modules events in a specific slot.
  1670.  *
  1671.  * To clear all events in all iseg HV modules, use setHighVoltageGroupsSwitch()
  1672.  * with the parameter clearEvents(10).
  1673.  * @param session The handle returned by snmpOpen()
  1674.  * @param slot The modules slot position in the crate (0...9)
  1675.  * @return
  1676.  */
  1677. int setModuleDoClear(HSNMP session, int slot)
  1678. {
  1679.         if (slot < 0 || slot >= MaxSlotsPerCrate)
  1680.                 return 0;
  1681.  
  1682.         return snmpSetInt(session, &moduleDoClear[slot], 1);
  1683. }
  1684.  
  1685. // The rest of the functions are utility functions that actually do the SNMP calls
  1686.  
  1687. static void logErrors(HSNMP session, struct snmp_pdu *response,
  1688.                                                          const SnmpObject *object, int status, const char *functionName)
  1689. {
  1690.         // FAILURE: print what went wrong!
  1691.         if (status == STAT_SUCCESS)
  1692.                 snmp_log(LOG_ERR, "%s(%s): Error in packet. Reason: %s\n",
  1693.                                 functionName, object->desc, snmp_errstring(response->errstat));
  1694.         else
  1695.                 snmp_sess_perror("snmpget", snmp_sess_session(session));
  1696. }
  1697.  
  1698. static int getIntegerVariable(struct variable_list *vars)
  1699. {
  1700.         if (vars->type == ASN_BIT_STR || vars->type == ASN_OCTET_STR) {
  1701.                 int value = 0;
  1702.                 for (size_t i = 0; i < vars->val_len && i < sizeof(int); ++i)
  1703.                         value |= (vars->val.bitstring[i] << (i * 8));
  1704.                 return value;
  1705.         } if (vars->type == ASN_OPAQUE_FLOAT)
  1706.                 return (int)*vars->val.floatVal;
  1707.         else if (vars->type == ASN_OPAQUE_DOUBLE)
  1708.                 return (int)*vars->val.doubleVal;
  1709.         else if (vars->type == ASN_INTEGER)
  1710.                 return *vars->val.integer;
  1711.         else if (vars->type == ASN_OCTET_STR)
  1712.                 return *vars->val.integer;
  1713.         else if (vars->type == ASN_IPADDRESS)
  1714.                 return *vars->val.integer;
  1715.  
  1716.         return 0;
  1717. }
  1718.  
  1719. static double getDoubleVariable(struct variable_list *vars)
  1720. {
  1721.         if (vars->type == ASN_OPAQUE_FLOAT)
  1722.                 return *vars->val.floatVal;
  1723.         else if (vars->type == ASN_OPAQUE_DOUBLE)
  1724.                 return *vars->val.doubleVal;
  1725.         else if (vars->type == ASN_INTEGER)
  1726.                 return (double)*vars->val.integer;
  1727.  
  1728.         return 0.0;
  1729. }
  1730.  
  1731. static struct snmp_pdu *prepareSetRequestPdu(void)
  1732. {
  1733.         struct snmp_pdu *pdu = snmp_pdu_create(SNMP_MSG_SET);
  1734.         pdu->community = (u_char *)strdup(m_writeCommunity);
  1735.         pdu->community_len = strlen(m_writeCommunity);
  1736.  
  1737.         return pdu;
  1738. }
  1739.  
  1740. static struct snmp_pdu *prepareGetRequestPdu()
  1741. {
  1742.         struct snmp_pdu *pdu = snmp_pdu_create(SNMP_MSG_GET);
  1743.  
  1744.         return pdu;
  1745. }
  1746.  
  1747. static int snmpGetInt(HSNMP session, const SnmpObject *object)
  1748. {
  1749.         int value = 0;
  1750.  
  1751.         struct snmp_pdu *pdu = prepareGetRequestPdu();
  1752.  
  1753.         snmp_add_null_var(pdu, object->id, object->len);   // generate request data
  1754.  
  1755.         struct snmp_pdu *response;
  1756.         int status = snmp_sess_synch_response(session, pdu, &response);
  1757.  
  1758.         if (status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR) {
  1759.                 value = getIntegerVariable(response->variables);
  1760.         } else {
  1761.                 logErrors(session, response, object, status, "snmpGetInt");
  1762.                 return 0;
  1763.         }
  1764.  
  1765.         snmp_free_pdu(response);
  1766.         return value;
  1767. }
  1768.  
  1769. static int snmpSetInt(HSNMP session, const SnmpObject *object, int value)
  1770. {
  1771.         struct snmp_pdu *pdu = prepareSetRequestPdu();
  1772.  
  1773.         if (snmp_oid_compare(object->id, object->len, ipStaticAddress.id, ipStaticAddress.len) == 0)
  1774.                 snmp_pdu_add_variable(pdu, object->id, object->len, ASN_IPADDRESS, (u_char *)&value, sizeof(value));
  1775.         else
  1776.                 snmp_pdu_add_variable(pdu, object->id, object->len, ASN_INTEGER, (u_char *)&value, sizeof(value));
  1777.  
  1778.         int result = value;
  1779.         struct snmp_pdu *response;
  1780.         int status = snmp_sess_synch_response(session, pdu, &response);
  1781.  
  1782.         if (status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR) {
  1783.                 result = getIntegerVariable(response->variables);
  1784.         } else {
  1785.                 logErrors(session, response, object, status, "snmpSetInt");
  1786.                 return 0;
  1787.         }
  1788.  
  1789.         snmp_free_pdu(response);
  1790.         return result;
  1791. }
  1792.  
  1793. static double snmpGetDouble(HSNMP session, const SnmpObject *object)
  1794. {
  1795.         double value = 0.0;
  1796.  
  1797.         struct snmp_pdu *pdu = prepareGetRequestPdu();
  1798.  
  1799.         snmp_add_null_var(pdu, object->id, object->len);   // generate request data
  1800.  
  1801.         struct snmp_pdu *response;
  1802.         int status = snmp_sess_synch_response(session, pdu, &response);
  1803.  
  1804.         if (status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR) {
  1805.                 value = getDoubleVariable(response->variables);
  1806.         } else {
  1807.                 logErrors(session, response, object, status, "snmpGetDouble");
  1808.                 return 0;
  1809.         }
  1810.  
  1811.         snmp_free_pdu(response);
  1812.         return value;
  1813. }
  1814.  
  1815. static double snmpSetDouble(HSNMP session, const SnmpObject *object, double value)
  1816. {
  1817.         struct snmp_pdu *pdu = prepareSetRequestPdu();
  1818.  
  1819.         float v = (float)value;
  1820.         snmp_pdu_add_variable(pdu, object->id, object->len, ASN_OPAQUE_FLOAT, (u_char *)&v, sizeof(v));
  1821.  
  1822.         double result = v;
  1823.  
  1824.         struct snmp_pdu *response;
  1825.         int status = snmp_sess_synch_response(session, pdu, &response);
  1826.  
  1827.         if (status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR) {
  1828.                 result = getDoubleVariable(response->variables);
  1829.         } else {
  1830.                 logErrors(session, response, object, status, "snmpSetDouble");
  1831.                 return 0;
  1832.         }
  1833.  
  1834.         snmp_free_pdu(response);
  1835.         return result;
  1836. }
  1837.  
  1838. static char *snmpGetString(HSNMP session, const SnmpObject *object)
  1839. {
  1840.         struct snmp_pdu *pdu = prepareGetRequestPdu();
  1841.  
  1842.         snmp_add_null_var(pdu, object->id, object->len);   // generate request data
  1843.  
  1844.         struct snmp_pdu *response;
  1845.         int status = snmp_sess_synch_response(session, pdu, &response);
  1846.  
  1847.         memset(snmpStringBuffer, 0, sizeof(snmpStringBuffer));
  1848.  
  1849.         if (status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR) {
  1850.                 struct variable_list *vars = response->variables;
  1851.                 if (vars->type == ASN_OCTET_STR) {
  1852.                         size_t len = sizeof(snmpStringBuffer) - 1;
  1853.                         if (len > vars->val_len)
  1854.                                 len = vars->val_len;
  1855.  
  1856.                         memcpy(snmpStringBuffer, vars->val.string, len);
  1857.                         snmpStringBuffer[len] = 0;
  1858.                 }
  1859.         } else {
  1860.                 logErrors(session, response, object, status, "snmpGetString");
  1861.                 return 0;
  1862.         }
  1863.  
  1864.         snmp_free_pdu(response);
  1865.         return snmpStringBuffer;
  1866. }
  1867.  
  1868. static SnmpIntegerBuffer *snmpGetMultipleInteger(HSNMP session, const SnmpObject *objects, int size)
  1869. {
  1870.         struct snmp_pdu *pdu = prepareGetRequestPdu();
  1871.  
  1872.         if (size > MaxChannelsPerSlot)
  1873.                 size = MaxChannelsPerSlot;
  1874.  
  1875.         memset(&snmpIntegerBuffer, 0, sizeof(snmpIntegerBuffer));
  1876.  
  1877.         for (int i = 0; i < size; ++i)
  1878.                 snmp_add_null_var(pdu, objects[i].id, objects[i].len);   // generate request data
  1879.  
  1880.         struct snmp_pdu *response;
  1881.         int status = snmp_sess_synch_response(session, pdu, &response);
  1882.  
  1883.         if (status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR) {
  1884.                 struct variable_list *vars;
  1885.                 for (vars = response->variables; vars; vars = vars->next_variable)
  1886.                         snmpIntegerBuffer.value[snmpIntegerBuffer.size++] = getIntegerVariable(vars);
  1887.         } else {
  1888.                 logErrors(session, response, &objects[0], status, "snmpGetMultipleInteger");
  1889.                 return &snmpIntegerBuffer;
  1890.         }
  1891.  
  1892.         snmp_free_pdu(response);
  1893.         return &snmpIntegerBuffer;
  1894. }
  1895.  
  1896. static SnmpIntegerBuffer *snmpSetMultipleInteger(HSNMP session, const SnmpObject *objects, SnmpIntegerBuffer *values)
  1897. {
  1898.         struct snmp_pdu *pdu = prepareSetRequestPdu();
  1899.  
  1900.         int size = values->size;
  1901.         if (size > MaxChannelsPerSlot)
  1902.                 size = MaxChannelsPerSlot;
  1903.  
  1904.         for (int i = 0; i < size; ++i) {
  1905.                 int v = values->value[i];
  1906.                 snmp_pdu_add_variable(pdu, objects[i].id, objects[i].len, ASN_INTEGER, (u_char *)&v, sizeof(v));
  1907.         }
  1908.  
  1909.         memset(&snmpIntegerBuffer, 0, sizeof(snmpIntegerBuffer));
  1910.  
  1911.         struct snmp_pdu *response;
  1912.         int status = snmp_sess_synch_response(session, pdu, &response);
  1913.  
  1914.         if (status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR) {
  1915.                 struct variable_list *vars;
  1916.                 for (vars = response->variables; vars; vars = vars->next_variable)
  1917.                         snmpIntegerBuffer.value[snmpIntegerBuffer.size++] = getIntegerVariable(vars);
  1918.         } else {
  1919.                 logErrors(session, response, &objects[0], status, "snmpSetMultipleInteger");
  1920.                 return &snmpIntegerBuffer;
  1921.         }
  1922.  
  1923.         snmp_free_pdu(response);
  1924.         return &snmpIntegerBuffer;
  1925. }
  1926.  
  1927. static SnmpDoubleBuffer *snmpGetMultipleDouble(HSNMP session, const SnmpObject *objects, int size)
  1928. {
  1929.         struct snmp_pdu *pdu = prepareGetRequestPdu();
  1930.  
  1931.         if (size > MaxChannelsPerSlot)
  1932.                 size = MaxChannelsPerSlot;
  1933.  
  1934.         memset(&snmpDoubleBuffer, 0, sizeof(snmpDoubleBuffer));
  1935.  
  1936.         for (int i = 0; i < size; ++i)
  1937.                 snmp_add_null_var(pdu, objects[i].id, objects[i].len);   // generate request data
  1938.  
  1939.         struct snmp_pdu *response;
  1940.         int status = snmp_sess_synch_response(session, pdu, &response);
  1941.  
  1942.         if (status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR) {
  1943.                 struct variable_list *vars;
  1944.                 for (vars = response->variables; vars; vars = vars->next_variable)
  1945.                         snmpDoubleBuffer.value[snmpDoubleBuffer.size++] = getDoubleVariable(vars);
  1946.         } else {
  1947.                 logErrors(session, response, &objects[0], status, "snmpGetMultipleDouble");
  1948.                 return &snmpDoubleBuffer;
  1949.         }
  1950.  
  1951.         snmp_free_pdu(response);
  1952.  
  1953.         return &snmpDoubleBuffer;
  1954. }
  1955.  
  1956. static SnmpDoubleBuffer *snmpSetMultipleDouble(HSNMP session, const SnmpObject *objects, SnmpDoubleBuffer *values)
  1957. {
  1958.         struct snmp_pdu *pdu = prepareSetRequestPdu();
  1959.  
  1960.         int size = values->size;
  1961.         if (size > MaxChannelsPerSlot)
  1962.                 size = MaxChannelsPerSlot;
  1963.  
  1964.         for (int i = 0; i < size; ++i) {
  1965.                 float v = (float)values->value[i];
  1966.                 snmp_pdu_add_variable(pdu, objects[i].id, objects[i].len, ASN_OPAQUE_FLOAT, (u_char *)&v, sizeof(v));
  1967.         }
  1968.  
  1969.         memset(&snmpDoubleBuffer, 0, sizeof(snmpDoubleBuffer));
  1970.  
  1971.         struct snmp_pdu *response;
  1972.         int status = snmp_sess_synch_response(session, pdu, &response);
  1973.  
  1974.         if (status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR) {
  1975.                 struct variable_list *vars;
  1976.                 for (vars = response->variables; vars; vars = vars->next_variable)
  1977.                         snmpDoubleBuffer.value[snmpDoubleBuffer.size++] = getDoubleVariable(vars);
  1978.         } else {
  1979.                 logErrors(session, response, &objects[0], status, "snmpSetMultipleDouble");
  1980.                 return &snmpDoubleBuffer;
  1981.         }
  1982.  
  1983.         snmp_free_pdu(response);
  1984.         return &snmpDoubleBuffer;
  1985. }
  1986.  
  1987. /**
  1988.  * @brief Returns an array with the outputStatus for a consecutive range of channels.
  1989.  *
  1990.  * @note This function is deprecated. Use getMultipleOutputStatuses() instead.
  1991.  * @param session The handle returned by snmpOpen()
  1992.  * @param start The first channel (in the range of 0 to MaxArraySize).
  1993.  * 0 = slot 0, channel 0; 100 = slot 1, channel 0.
  1994.  * @param size The number of requested channels.
  1995.  * @return A pointer to SnmpIntegerBuffer with the requested information.
  1996.  * @note This pointer is only valid until the next call of getMultiple...
  1997.  * or setMultiple... function.
  1998.  */
  1999. SnmpIntegerBuffer *getMultipleChannelStatuses(HSNMP session, int start, int size)
  2000. {
  2001.         return getMultipleOutputStatuses(session, start, size);
  2002. }
  2003.  
  2004. /**
  2005.  * @brief Returns an array with the outputStatus for a consecutive range of channels.
  2006.  * @since 1.1
  2007.  * @param session The handle returned by snmpOpen()
  2008.  * @param start The first channel (in the range of 0 to MaxArraySize).
  2009.  * 0 = slot 0, channel 0; 100 = slot 1, channel 0.
  2010.  * @param size The number of requested channels.
  2011.  * @return A pointer to SnmpIntegerBuffer with the requested information.
  2012.  * @note This pointer is only valid until the next call of getMultiple...
  2013.  * or setMultiple... function.
  2014.  */
  2015. SnmpIntegerBuffer *getMultipleOutputStatuses(HSNMP session, int start, int size)
  2016. {
  2017.         if (start < 0 || size < 0 || start + size > MaxChannelsPerCrate) {
  2018.                 memset(&snmpIntegerBuffer, 0, sizeof(snmpIntegerBuffer));
  2019.                 return &snmpIntegerBuffer;
  2020.         }
  2021.  
  2022.         return snmpGetMultipleInteger(session, &outputStatus[start], size);
  2023. }
  2024.  
  2025. /**
  2026.  * @brief Returns an array with the outputSwitches for a consecutive range of channels.
  2027.  * @param session The handle returned by snmpOpen()
  2028.  * @param start The first channel (in the range of 0 to MaxArraySize).
  2029.  * 0 = slot 0, channel 0; 100 = slot 1, channel 0.
  2030.  * @param size The number of requested channels.
  2031.  * @return A pointer to SnmpIntegerBuffer with the requested information.
  2032.  * @note This pointer is only valid until the next call of getMultiple...
  2033.  * or setMultiple... function.
  2034.  */
  2035. SnmpIntegerBuffer *getMultipleOutputSwitches(HSNMP session, int start, int size)
  2036. {
  2037.         if (start < 0 || size < 0 || start + size > MaxChannelsPerCrate) {
  2038.                 memset(&snmpIntegerBuffer, 0, sizeof(snmpIntegerBuffer));
  2039.                 return &snmpIntegerBuffer;
  2040.         }
  2041.  
  2042.         return snmpGetMultipleInteger(session, &outputSwitch[start], size);
  2043. }
  2044.  
  2045. /**
  2046.  * @brief Sets the outputSwitch for a consecutive range of channels.
  2047.  * @param session The handle returned by snmpOpen()
  2048.  * @param start The first channel (in the range of 0 to MaxArraySize).
  2049.  * 0 = slot 0, channel 0; 100 = slot 1, channel 0.
  2050.  * @param values A pointer to SnmpIntegerBuffer with the list of outputSwitches.
  2051.  * @return
  2052.  */
  2053. SnmpIntegerBuffer *setMultipleOutputSwitches(HSNMP session, int start, SnmpIntegerBuffer *values)
  2054. {
  2055.         if (start < 0 || values->size < 0 || start + values->size > MaxChannelsPerCrate) {
  2056.                 memset(&snmpIntegerBuffer, 0, sizeof(snmpIntegerBuffer));
  2057.                 return &snmpIntegerBuffer;
  2058.         }
  2059.  
  2060.         return snmpSetMultipleInteger(session, &outputSwitch[start], values);
  2061. }
  2062.  
  2063. /**
  2064.  * @brief Returns the actual outputVoltage for a consecutive range of channels.
  2065.  * @param session The handle returned by snmpOpen()
  2066.  * @param start The first channel (in the range of 0 to MaxArraySize).
  2067.  * 0 = slot 0, channel 0; 100 = slot 1, channel 0.
  2068.  * @param size The number of requested channels.
  2069.  * @return A pointer to SnmpDoubleBuffer with the requested information.
  2070.  * @note This pointer is only valid until the next call of getMultiple...
  2071.  * or setMultiple... function.
  2072.  */
  2073. SnmpDoubleBuffer *getMultipleOutputVoltages(HSNMP session, int start, int size)
  2074. {
  2075.         if (start < 0 || size < 0 || start + size > MaxChannelsPerCrate) {
  2076.                 memset(&snmpDoubleBuffer, 0, sizeof(snmpDoubleBuffer));
  2077.                 return &snmpDoubleBuffer;
  2078.         }
  2079.  
  2080.         return snmpGetMultipleDouble(session, &outputVoltage[start], size);
  2081. }
  2082.  
  2083. /**
  2084.  * @brief Sets the demanded outputVoltage for a consecutive range of channels.
  2085.  * @param session The handle returned by snmpOpen()
  2086.  * @param start The first channel (in the range of 0 to MaxArraySize).
  2087.  * 0 = slot 0, channel 0; 100 = slot 1, channel 0.
  2088.  * @param values A pointer to SnmpDoubleBuffer with the list of new outputVoltages
  2089.  * @return
  2090.  */
  2091. SnmpDoubleBuffer *setMultipleOutputVoltages(HSNMP session, int start, SnmpDoubleBuffer *values)
  2092. {
  2093.         if (start < 0 || values->size < 0 || start + values->size > MaxChannelsPerCrate) {
  2094.                 memset(&snmpDoubleBuffer, 0, sizeof(snmpDoubleBuffer));
  2095.                 return &snmpDoubleBuffer;
  2096.         }
  2097.  
  2098.         return snmpSetMultipleDouble(session, &outputVoltage[start], values);
  2099. }
  2100.  
  2101. /**
  2102.  * @brief Returns the measured terminal voltages for a consecutive range of channels.
  2103.  * @param session The handle returned by snmpOpen()
  2104.  * @param start The first channel (in the range of 0 to MaxArraySize).
  2105.  * 0 = slot 0, channel 0; 100 = slot 1, channel 0.
  2106.  * @param size The number of requested channels.
  2107.  * @return A pointer to SnmpDoubleBuffer with the requested information.
  2108.  * @note This pointer is only valid until the next call of getMultiple...
  2109.  * or setMultiple... function.
  2110.  */
  2111. SnmpDoubleBuffer *getMultipleMeasurementTerminalVoltages(HSNMP session, int start, int size)
  2112. {
  2113.         return getMultipleOutputMeasurementTerminalVoltages(session, start, size);
  2114. }
  2115.  
  2116. /**
  2117.  * @brief Returns an array with the measured terminal voltages for a consecutive range of channels.
  2118.  * @since 1.1
  2119.  * @param session The handle returned by snmpOpen()
  2120.  * @param start The first channel (in the range of 0 to MaxArraySize).
  2121.  * 0 = slot 0, channel 0; 100 = slot 1, channel 0.
  2122.  * @param size The number of requested channels.
  2123.  * @return A pointer to SnmpDoubleBuffer with the requested information.
  2124.  * @note This pointer is only valid until the next call of getMultiple...
  2125.  * or setMultiple... function.
  2126.  */
  2127. SnmpDoubleBuffer *getMultipleOutputMeasurementTerminalVoltages(HSNMP session, int start, int size)
  2128. {
  2129.         if (start < 0 || size < 0 || start + size > MaxChannelsPerCrate) {
  2130.                 memset(&snmpDoubleBuffer, 0, sizeof(snmpDoubleBuffer));
  2131.                 return &snmpDoubleBuffer;
  2132.         }
  2133.  
  2134.         return snmpGetMultipleDouble(session, &outputMeasurementTerminalVoltage[start], size);
  2135. }
  2136.  
  2137. /**
  2138.  * @brief getMultipleOutputConfigMaxTerminalVoltages
  2139.  * @param session The handle returned by snmpOpen()
  2140.  * @param start The first channel (in the range of 0 to MaxArraySize).
  2141.  * 0 = slot 0, channel 0; 100 = slot 1, channel 0.
  2142.  * @param size The number of requested channels.
  2143.  * @return
  2144.  */
  2145. SnmpDoubleBuffer *getMultipleOutputConfigMaxTerminalVoltages(HSNMP session, int start, int size)
  2146. {
  2147.         if (start < 0 || size < 0 || start + size > MaxChannelsPerCrate) {
  2148.                 memset(&snmpDoubleBuffer, 0, sizeof(snmpDoubleBuffer));
  2149.                 return &snmpDoubleBuffer;
  2150.         }
  2151.  
  2152.         return snmpGetMultipleDouble(session, &outputConfigMaxTerminalVoltage[start], size);
  2153. }
  2154.  
  2155. /**
  2156.  * @brief Returns an array the demanded output currents for a consecutive range of channels.
  2157.  * @param session The handle returned by snmpOpen()
  2158.  * @param start The first channel (in the range of 0 to MaxArraySize).
  2159.  * 0 = slot 0, channel 0; 100 = slot 1, channel 0.
  2160.  * @param size The number of requested channels.
  2161.  * @return
  2162.  */
  2163. SnmpDoubleBuffer *getMultipleOutputCurrents(HSNMP session, int start, int size)
  2164. {
  2165.         if (start < 0 || size < 0 || start + size > MaxChannelsPerCrate) {
  2166.                 memset(&snmpDoubleBuffer, 0, sizeof(snmpDoubleBuffer));
  2167.                 return &snmpDoubleBuffer;
  2168.         }
  2169.  
  2170.         return snmpGetMultipleDouble(session, &outputCurrent[start], size);
  2171. }
  2172.  
  2173. /**
  2174.  * @brief Sets the demanded output current for a consecutive range of channels.
  2175.  * @param session The handle returned by snmpOpen()
  2176.  * @param start The first channel (in the range of 0 to MaxArraySize).
  2177.  * 0 = slot 0, channel 0; 100 = slot 1, channel 0.
  2178.  * @param values A pointer to SnmpDoubleBuffer with a list of new output currents
  2179.  * @return
  2180.  */
  2181. SnmpDoubleBuffer *setMultipleOutputCurrents(HSNMP session, int start, SnmpDoubleBuffer *values)
  2182. {
  2183.         if (start < 0 || values->size < 0 || start + values->size > MaxChannelsPerCrate) {
  2184.                 memset(&snmpDoubleBuffer, 0, sizeof(snmpDoubleBuffer));
  2185.                 return &snmpDoubleBuffer;
  2186.         }
  2187.  
  2188.         return snmpSetMultipleDouble(session, &outputCurrent[start], values);
  2189. }
  2190.  
  2191. /**
  2192.  * @brief Returns an array with the measured currents for a consecutive range of channels.
  2193.  *
  2194.  * @note This function is deprecated. Use getMultipleOutputMeasurementCurrents() instead.
  2195.  * @param session The handle returned by snmpOpen()
  2196.  * @param start The first channel (in the range of 0 to MaxArraySize).
  2197.  * 0 = slot 0, channel 0; 100 = slot 1, channel 0.
  2198.  * @param size The number of requested channels.
  2199.  * @return A pointer to SnmpDoubleBuffer with the requested information.
  2200.  * @note This pointer is only valid until the next call of getMultiple...
  2201.  * or setMultiple... function.
  2202.  */
  2203. SnmpDoubleBuffer *getMultipleMeasurementCurrents(HSNMP session, int start, int size)
  2204. {
  2205.         return getMultipleOutputMeasurementCurrents(session, start, size);
  2206. }
  2207.  
  2208. /**
  2209.  * @brief Returns an array with the measured currents for a consecutive range of channels.
  2210.  * @since 1.1
  2211.  * @param session The handle returned by snmpOpen()
  2212.  * @param start The first channel (in the range of 0 to MaxArraySize).
  2213.  * 0 = slot 0, channel 0; 100 = slot 1, channel 0.
  2214.  * @param size The number of requested channels.
  2215.  * @return A pointer to SnmpDoubleBuffer with the requested information.
  2216.  * @note This pointer is only valid until the next call of getMultiple...
  2217.  * or setMultiple... function.
  2218.  */
  2219. SnmpDoubleBuffer *getMultipleOutputMeasurementCurrents(HSNMP session, int start, int size)
  2220. {
  2221.         if (start < 0 || size < 0 || start + size > MaxChannelsPerCrate) {
  2222.                 memset(&snmpDoubleBuffer, 0, sizeof(snmpDoubleBuffer));
  2223.                 return &snmpDoubleBuffer;
  2224.         }
  2225.  
  2226.         return snmpGetMultipleDouble(session, &outputMeasurementCurrent[start], size);
  2227. }
  2228.  
  2229. /**
  2230.  * @brief Returns an array with the outputConfigMaxCurrent for a consecutive range of channels.
  2231.  * @param session The handle returned by snmpOpen()
  2232.  * @param start The first channel (in the range of 0 to MaxArraySize).
  2233.  * 0 = slot 0, channel 0; 100 = slot 1, channel 0.
  2234.  * @param size The number of requested channels.
  2235.  * @return
  2236.  */
  2237. SnmpDoubleBuffer *getMultipleOutputConfigMaxCurrents(HSNMP session, int start, int size)
  2238. {
  2239.         if (start < 0 || size < 0 || start + size > MaxChannelsPerCrate) {
  2240.                 memset(&snmpDoubleBuffer, 0, sizeof(snmpDoubleBuffer));
  2241.                 return &snmpDoubleBuffer;
  2242.         }
  2243.  
  2244.         return snmpGetMultipleDouble(session, &outputConfigMaxCurrent[start], size);
  2245. }
  2246.  
  2247. /**
  2248.  * @brief Returns an array with the outputTripTimeMaxCurrent for a consecutive range of channels.
  2249.  * @param session The handle returned by snmpOpen()
  2250.  * @param start The first channel (in the range of 0 to MaxArraySize).
  2251.  * 0 = slot 0, channel 0; 100 = slot 1, channel 0.
  2252.  * @param size The number of requested channels.
  2253.  * @return
  2254.  */
  2255. SnmpIntegerBuffer *getMultipleOutputTripTimeMaxCurrents(HSNMP session, int start, int size)
  2256. {
  2257.         if (start < 0 || size < 0 || start + size > MaxChannelsPerCrate) {
  2258.                 memset(&snmpIntegerBuffer, 0, sizeof(snmpIntegerBuffer));
  2259.                 return &snmpIntegerBuffer;
  2260.         }
  2261.  
  2262.         return snmpGetMultipleInteger(session, &outputTripTimeMaxCurrent[start], size);
  2263. }
  2264.  
  2265. /**
  2266.  * @brief Sets the outputTripTimeMaxCurrent for a consecutive ranges of channels.
  2267.  * @param session The handle returned by snmpOpen()
  2268.  * @param start The first channel (in the range of 0 to MaxArraySize).
  2269.  * 0 = slot 0, channel 0; 100 = slot 1, channel 0.
  2270.  * @param values
  2271.  * @return
  2272.  */
  2273. SnmpIntegerBuffer *setMultipleOutputTripTimeMaxCurrents(HSNMP session, int start, SnmpIntegerBuffer *values)
  2274. {
  2275.         if (start < 0 || values->size < 0 || start + values->size > MaxChannelsPerCrate) {
  2276.                 memset(&snmpIntegerBuffer, 0, sizeof(snmpIntegerBuffer));
  2277.                 return &snmpIntegerBuffer;
  2278.         }
  2279.  
  2280.         return snmpSetMultipleInteger(session, &outputTripTimeMaxCurrent[start], values);
  2281. }
  2282.  
  2283. /**
  2284.  * @brief Returns an array with the outputSupervisionBehavior for a consecutive range of channels.
  2285.  * @param session The handle returned by snmpOpen()
  2286.  * @param start The first channel (in the range of 0 to MaxArraySize).
  2287.  * 0 = slot 0, channel 0; 100 = slot 1, channel 0.
  2288.  * @param size The number of requested channels.
  2289.  * @return
  2290.  */
  2291. SnmpIntegerBuffer *getMultipleOutputSupervisionBehaviors(HSNMP session, int start, int size)
  2292. {
  2293.         if (start < 0 || size < 0 || start + size > MaxChannelsPerCrate) {
  2294.                 memset(&snmpIntegerBuffer, 0, sizeof(snmpIntegerBuffer));
  2295.                 return &snmpIntegerBuffer;
  2296.         }
  2297.  
  2298.         return snmpGetMultipleInteger(session, &outputSupervisionBehavior[start], size);
  2299. }
  2300.  
  2301. /**
  2302.  * @brief Sets the outputSupervisionBehavior for a consecutive range of channels.
  2303.  * @param session The handle returned by snmpOpen()
  2304.  * @param start The first channel (in the range of 0 to MaxArraySize).
  2305.  * 0 = slot 0, channel 0; 100 = slot 1, channel 0.
  2306.  * @param values The new outputSupervisionBehavior for the all channels starting with start.
  2307.  * @return
  2308.  */
  2309. SnmpIntegerBuffer *setMultipleOutputSupervisionBehaviors(HSNMP session, int start, SnmpIntegerBuffer *values)
  2310. {
  2311.         if (start < 0 || values->size < 0 || start + values->size > MaxChannelsPerCrate) {
  2312.                 memset(&snmpIntegerBuffer, 0, sizeof(snmpIntegerBuffer));
  2313.                 return &snmpIntegerBuffer;
  2314.         }
  2315.  
  2316.         return snmpSetMultipleInteger(session, &outputSupervisionBehavior[start], values);
  2317. }
  2318.