IPMISensorGroup.cpp 3.84 KB
Newer Older
1
2
3
//================================================================================
// Name        : IPMISensorGroup.cpp
// Author      : Michael Ott, Micha Mueller
Micha Müller's avatar
Micha Müller committed
4
// Contact     : info@dcdb.it
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// Copyright   : Leibniz Supercomputing Centre
// Description : Source file for IPMI sensor group class.
//================================================================================

//================================================================================
// This file is part of DCDB (DataCenter DataBase)
// Copyright (C) 2017-2019 Leibniz Supercomputing Centre
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
//================================================================================
27
28
29
30
31
32
33
34
35
36
37
38

#include "IPMISensorGroup.h"
#include "IPMIHost.h"

#include <iostream>
#include <exception>
#include <chrono>

IPMISensorGroup::IPMISensorGroup(const std::string& name) :
		SensorGroupTemplate(name) {
}

39
IPMISensorGroup::IPMISensorGroup(const IPMISensorGroup& other) :
40
41
42
    SensorGroupTemplate(other) {

}
43

44
45
IPMISensorGroup::~IPMISensorGroup() {}

46
47
48
49
50
51
IPMISensorGroup& IPMISensorGroup::operator=(const IPMISensorGroup& other) {
  SensorGroupTemplate::operator=(other);

  return *this;
}

52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
uint64_t IPMISensorGroup::readRaw(const std::vector<uint8_t>& rawCmd, uint8_t lsb, uint8_t msb) {
    uint8_t buf[256];
    int len = -1;
    
    try {
	len = _entity->sendRawCmd(&rawCmd[0], rawCmd.size(), (void *) buf, sizeof(buf));
    } catch (const std::exception& e) {
	throw e;
	return 0;
    }
    
    std::stringstream ss;
    if (msb > len) {
	ss << "Error processing IPMI raw data: msb=" << msb << " > len=" << len;
	} else if (lsb > len) {
	    ss << "Error processing IPMI raw data: lsb=" << lsb << " > len=" << len;
	}
	if (ss.gcount() > 0) {
	    throw std::runtime_error(ss.str());
	    return 0;
	}
	
	int64_t val = 0;
	int i;
	if (msb > lsb) {
	    for (i = lsb; i <= msb; i++) {
		val |= ((int64_t) buf[i]) << (msb - i) * 8;
	    }
	} else {
	    for (i = lsb; i >= msb; i--) {
		val |= ((int64_t) buf[i]) << (i-msb) * 8;
	    }
	}
	
	return val;
}

89
90
91
92
void IPMISensorGroup::read() {
	reading_t reading;
	reading.timestamp = getTimestamp();

93
94
95
96
97
98
99
100
	//TODO with SensorGroup refactor we lost the ability to sleep until
	// delayNextRead. Instead we are now checking every time if we can read
	// again. Overhead acceptable? General delayNextReadUntil implementation in
	// SensorGroupTemplate required?
	if (reading.timestamp < _entity->getDelayNextReadUntil()) {
	    return;
	}

101
	for(const auto& s : _sensors) {
102
103
		try {
			if (s->getRecordId() != 0) { /* recordId was set */
104
105
			    std::vector<uint8_t> sdrRecord = s->getSdrRecord();
			    if (sdrRecord.size() == 0) {
106
				_entity->getSdrRecord(s->getRecordId(), sdrRecord);
107
108
				s->setSdrRecord(sdrRecord);
			    }
109
			    reading.value = _entity->readSensorRecord(sdrRecord);
110
			} else { /* use raw command */
111
				reading.value = readRaw(s->getRawCmd(), s->getLsb(), s->getMsb());
112
			}
113
#ifdef DEBUG
Micha Mueller's avatar
Micha Mueller committed
114
			LOG(debug) << _groupName << "::" << s->getName() << " raw reading: \"" << reading.value << "\"";
115
#endif
116
			s->storeReading(reading, s->getFactor());
117
118
		} catch (const std::exception& e) {
			LOG(error) << _groupName << "::" << s->getName() << " could not read value: " << e.what();
119
		    continue;
120
121
122
		}
	}
}