Subversion Repositories f9daq

Rev

Rev 154 | Rev 156 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

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