Subversion Repositories f9daq

Rev

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