Subversion Repositories f9daq

Rev

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