Subversion Repositories f9daq

Rev

Rev 151 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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