Subversion Repositories f9daq

Rev

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