Documentation
¶
Overview ¶
Package ipmi implements in-band communication with BMC using IPMI commands using `/dev/ipmi*` device.
Index ¶
- Constants
- Variables
- func FDClr(fd uintptr, p *unix.FdSet)
- func FDIsSet(fd uintptr, p *unix.FdSet) bool
- func FDSet(fd uintptr, p *unix.FdSet)
- func FDZero(p *unix.FdSet)
- type Client
- type Config
- type ConversionFactors
- type FullSensorRecord
- type Linearisation
- type Lineariser
- type LineariserFunc
- type PowerReading
- type Request
- type Response
- type SensorUnit
- type StringDecoder
- type StringDecoderFunc
- type StringEncoding
Constants ¶
const ( IPMICTL_SET_GETS_EVENTS_CMD = 0x80046910 //nolint:stylecheck IPMICTL_SEND_COMMAND = 0x8028690d //nolint:stylecheck IPMICTL_RECEIVE_MSG_TRUNC = 0xc030690b //nolint:stylecheck IPMI_SYSTEM_INTERFACE_ADDR_TYPE = 0xC //nolint:stylecheck IPMI_BMC_CHANNEL = 0xF //nolint:stylecheck )
IPMI related constants.
const ( IPMI_DCMI = 0xDC //nolint:stylecheck IPMI_DCMI_GETRED = 0x2 //nolint:stylecheck IPMI_NETFN_DCGRP = 0x2C //nolint:stylecheck IPMI_DCMI_ACTIVATED = 0x40 //nolint:stylecheck )
IPMI DCMI related constants.
const ( IPMI_LAN = 0x1 //nolint:stylecheck IPMI_LANP_IP_ADDR = 0x2 //nolint:stylecheck IPMI_NETFN_TRANSPORT = 0xC //nolint:stylecheck )
IPMI DCMI related constants.
const ( IPMI_SENSOR_RECORD_CMD = 0x23 //nolint:stylecheck IPMI_SENSOR_RECORD_NETFN = 0xa //nolint:stylecheck IPMI_SENSOR_READING_CMD = 0x2d //nolint:stylecheck IPMI_SENSOR_READING_NETFN = 0x4 //nolint:stylecheck )
IPMI sensor related constants.
const (
// NFDBits is the amount of bits per mask.
NFDBits = 8 * 8
)
Variables ¶
var ( // ErrNotLinearised is returned if Lineariser() is called on a linear or // non-linear linearisation. Linear sensors' values do not require any // transformation by virtue of the sensor already being linear. If the sensor // is non-linear, the conversion factors returned by Get Sensor Reading // Factors are all that are needed to obtain a real value: by being unique // to the raw sensor reading, there is no need for a separate linearisation // formula. // // Linearise() could return a no-op lineariser, however the current // implementation should never ask for one on a non-linearised sensor, so // instead we return an error to flag up a possible bug. ErrNotLinearised = errors.New( "only linearised sensors have a linearisation formula") )
Functions ¶
Types ¶
type Client ¶ added in v0.11.0
type Client interface {
Do(r *Request) (*Response, error)
Close() error
DCMIPowerReading() (*PowerReading, error)
LanIP() (*string, error)
SensorRecords() ([]*FullSensorRecord, error)
SensorReadings(records []*FullSensorRecord) (map[*FullSensorRecord]float64, error)
}
type ConversionFactors ¶ added in v0.11.0
type ConversionFactors struct {
// M is the constant multiplier. This is a 10-bit 2's complement number on
// the wire.
M int16
// B is the additive offset. This is a 10-bit 2's complement number on the
// wire.
B int16
// BExp is the exponent, controlling the location of the decimal point in B.
// This is also referred to as K1 in the spec, and is a 4-bit 2's complement
// number on the wire.
BExp int8
// RExp is the result exponent, controlling the location of the decimal
// point in the result of the linear formula and hence input to the
// linearisation function. This is also referred to as K2 in the spec, and
// is a 4-bit 2's complement number on the wire.
RExp int8
}
ConversionFactors contains inputs to the linear formula in 30.3 and 36.3 of v1.5 and v2.0 respectively. This struct exists as conversion factors can come from two sources: full sensor records, and the Get Sensor Reading Factors command response. In practice, we get them from the former for linear and linearised sensors, as these have constant factors. We need to obtain them from the Get Sensor Reading Factors command for non-linear sensors, as they vary by reading here. Both FullSensorRecord and GetSensorReadingFactorsRsp embed this type.
Note that we split application of the formula into "conversion" and "linearisation". Conversion happens first, and is the linear formula applied to the raw value. The linearisation step, which is a no-op for linear and non-linear sensors, applies one of the formulae in the specification to the result of the conversion. This struct only deals with conversion; see Lineariser for linearisation.
func (*ConversionFactors) ConvertReading ¶ added in v0.11.0
func (f *ConversionFactors) ConvertReading(raw int16) float64
ConvertReading applies the linear formula to a raw sensor reading, without the linearisation formula. It is independent of unit. This method takes an int16 rather than uint8 as raw values can be in 1 or 2's complement, or unsigned, so it must accept from -128 (lowest 2's complement) to 255 (highest unsigned). The conversion from the raw format to a native int must be done before calling this method.
type FullSensorRecord ¶ added in v0.11.0
type FullSensorRecord struct {
ConversionFactors
// Sensor number that will be used in request to get reading
Number uint8
// BaseUnit gives the primary unit of the sensor's reading, e.g. Celsius or
// Fahrenheit for a temperature sensor.
BaseUnit SensorUnit
// ModifierUnit is contained in the Sensor Units 3 field. Note this is
// distinct from the identically-named 2-bit field in Sensor Units 1. 0x0
// means unused.
ModifierUnit SensorUnit
// Linearisation indicates whether the sensor is linear, linearised or
// non-linear. This controls post-processing after applying the linear
// conversion formula to the raw reading.
Linearisation Linearisation
// Tolerance gives the absolute accuracy of the sensor in +/- half raw
// counts. This is a 6-bit uint on the wire.
Tolerance uint8
// Accuracy gives the sensor accuracy in 0.01% increments when raised to
// AccuracyExp. This is a 10-bit int on the wire.
Accuracy int16
// AccuracyExp is the quantity Accuracy is raised to the power of to give
// the final accuracy.
AccuracyExp uint8
// Identity is a descriptive string for the sensor. This can be up to 16
// bytes long, which translates into 16-32 characters depending on the
// format used. There are no conventions around this, and it is provided for
// informational purposes only. Contrary to the name, attempting to identify
// sensors based on this value is doomed to fail.
Identity string
}
FullSensorRecord is specified in 37.1 and 43.1 of v1.5 and v2.0 respectively. It describes any type of sensor, and is the only record type that can describe a sensor generating analogue (i.e. non-enumerated/discrete) readings, e.g. a temperature sensor. It is specified as 64 bytes. This layer represents the record key and record body sections.
func (*FullSensorRecord) DecodeFromBytes ¶ added in v0.11.0
func (r *FullSensorRecord) DecodeFromBytes(data []uint8) error
type Linearisation ¶ added in v0.11.0
type Linearisation uint8
Linearisation indicates whether a sensor is linear, linearised, or non-linear. Values are specified in the Full Sensor Record wire format table in 37-1 and 43-1 of v1.5 and v2.0 respectively.
Linear sensors are the easiest to deal with. The sensor's raw readings are converted into real readings (e.g. Celsius) with a linear formula. Accuracy and resolution are constant in real terms across the entire range of values produced by the sensor.
Linearised are slightly more challenging. The same linear formula is applied as for linear sensors, however a final "linearisation formula" is applied to obtain the real reading. This transformation is one of 11 defined in the spec, e.g. log or sqrt, and obviously does not have to be linear itself. The tolerance (the spec misuses accuracy as a synonym) of linearised sensors is also constant for all values. This is possible despite the existence of the linearisation formula turning raw values into disproportionate real values, as tolerance is expressed relative to 0. This assumes the sensor's tolerance does not diminish in real, absolute terms at extreme values (positive or negative), as there is no way of representing it (you'd have to resort to declaring it a non-linear sensor). Note that tolerance can only be expressed in half-raw value increments, which is in itself quite coarse. Regarding resolution, this will vary with reading due to the linearisation formula. The recommended way to calculate it is to retrieve and calculate the real values (with the help of Get Sensor Reading Factors as necessary) corresponding to the raw values below and above the actual raw value observed. Subtracting the real reading for the raw value below the observed raw value from the real reading for the observed value gives the negative resolution, and the process is equivalent for the positive resolution using the raw value one above.
All consistency bets are off with non-linear sensors. Not only does resolution vary by reading (calculated in the same was as for linearised sensors), but so does tolerance. Get Sensor Reading Factors must be sent with each raw reading; applying the linear formula using the returned conversion factors yields the real reading, and can the same factors can be plugged into the tolerance and resolution formulae to calculate them.
const ( LinearisationLinear Linearisation = iota LinearisationLn LinearisationLog10 LinearisationLog2 LinearisationE LinearisationExp10 LinearisationExp2 LinearisationInverse LinearisationSqr LinearisationCube LinearisationSqrt LinearisationCubeRt LinearisationNonLinear )
func (Linearisation) Description ¶ added in v0.11.0
func (l Linearisation) Description() string
func (Linearisation) IsLinear ¶ added in v0.11.0
func (l Linearisation) IsLinear() bool
IsLinear returns whether the underlying sensor is linear. Calling Lineariser() will return an error, as there is no linearisation formula (it is effectively a no-op). Only the linear formula in the spec needs be applied to obtain a real reading.
func (Linearisation) IsLinearised ¶ added in v0.11.0
func (l Linearisation) IsLinearised() bool
IsLinearised returns whether the underlying sensor is linearised, meaning the value after conversion needs to be fed through a linearisation formula as a final step before being used. A suitable implementation of this function is returned by the Lineariser() method.
func (Linearisation) IsNonLinear ¶ added in v0.11.0
func (l Linearisation) IsNonLinear() bool
IsNonLinear returns whether the underlying sensor is not consistent enough for the constraints of linear and linearised. As for linear sensors, attempting to retrieve a Lineariser will return an error. Readings from these sensors require Get Sensor Reading Factors to convert them into usable values.
func (Linearisation) Lineariser ¶ added in v0.11.0
func (l Linearisation) Lineariser() (Lineariser, error)
Lineariser returns a suitable Lineariser implementation that will turn the converted raw value produced by the underlying sensor into a usable value. If the sensor is already linear, or non-linear, this will return ErrNotLinearised.
func (Linearisation) String ¶ added in v0.11.0
func (l Linearisation) String() string
type Lineariser ¶ added in v0.11.0
type Lineariser interface {
// Linearise applies a linearisation formula to a converted value, returning
// the final value in the correct unit. This is the last step in the "Sensor
// Reading Conversion Formula" described in section 30.3 of IPMI v1.5 and
// v2.0.
Linearise(v float64) float64
}
Lineariser is implemented by formulae that can linearise a value returned by the Get Sensor Reading command that has gone through the linear formula containing M, B, K1 and K2, used for all sensors.
type LineariserFunc ¶ added in v0.11.0
LineariserFunc is the type of the function in the Lineariser interface. It allows us to create stateless Lineariser implementations from raw functions, including those in the math package.
func (LineariserFunc) Linearise ¶ added in v0.11.0
func (l LineariserFunc) Linearise(f float64) float64
Linearise invokes the wrapped function, passing through the input and result.
type PowerReading ¶
type SensorUnit ¶ added in v0.11.0
type SensorUnit uint8
SensorUnit defines the unit of a sensor. It is specified in 37.17 and 43.17 of v1.5 and v2.0 respectively. It is an 8-bit uint on the wire.
const ( SensorUnitCelsius SensorUnit SensorUnitFahrenheit SensorUnitKelvin SensorUnitVolts SensorUnitAmps SensorUnitWatts SensorUnitJoules SensorUnitCoulombs SensorUnitVoltamperes SensorUnitNits SensorUnitLumen SensorUnitLux SensorUnitCandela SensorUnitKilopascals SensorUnitPoundsPerSquareInch SensorUnitNewtons SensorUnitCubicFeetPerMinute SensorUnitRotationsPerMinute SensorUnitHertz SensorUnitMicroseconds SensorUnitMilliseconds SensorUnitSeconds SensorUnitMinutes SensorUnitHours SensorUnitDays SensorUnitWeeks SensorUnitMils SensorUnitInches SensorUnitFeet SensorUnitCubicInches SensorUnitCubicFeet SensorUnitMillimeters SensorUnitCentimeters SensorUnitMeters SensorUnitCubicCentimeters SensorUnitCubicMeters SensorUnitLiters SensorUnitFluidOunces SensorUnitRadians SensorUnitSteradians SensorUnitRevolutions SensorUnitCycles SensorUnitGravities SensorUnitOunces SensorUnitPounds SensorUnitFeetPounds SensorUnitOunceInches SensorUnitGauss SensorUnitGilberts SensorUnitHenry SensorUnitMillihenry SensorUnitFarad SensorUnitMicrofarad SensorUnitOhms SensorUnitSiemens SensorUnitMoles SensorUnitBecquerel SensorUnitPartsPerMillion SensorUnitDecibels SensorUnitDecibelsAFilter SensorUnitDecibelsCFilter SensorUnitGray SensorUnitSieverts SensorUnitColorTempKelvin SensorUnitBits SensorUnitKilobits SensorUnitMegabits SensorUnitGigabits SensorUnitBytes SensorUnitKilobytes SensorUnitMegabytes SensorUnitGigabytes SensorUnitWords SensorUnitDwords SensorUnitQwords SensorUnitMemoryLines SensorUnitHits SensorUnitMisses SensorUnitRetries SensorUnitResets SensorUnitOverflows SensorUnitUnderruns SensorUnitCollisions SensorUnitPackets SensorUnitMessages SensorUnitCharacters SensorUnitErrors SensorUnitCorrectableErrors SensorUnitUncorrectableErrors SensorUnitFatal SensorUnitGrams )
func (SensorUnit) String ¶ added in v0.11.0
func (s SensorUnit) String() string
func (SensorUnit) Symbol ¶ added in v0.11.0
func (s SensorUnit) Symbol() string
type StringDecoder ¶ added in v0.11.0
type StringDecoder interface {
// Decode parses the first c characters (0 <= c <= 30) in b in the expected
// format (N.B. this could be a varying number of bytes depending on the
// encoding), returning the resulting string and number of bytes consumed,
// or an error if the data is too short or invalid.
//
// c was implemented as an int rather than uint8 to reduce the number of
// conversions required.
Decode(b []byte, c int) (string, int, error)
}
StringDecoder is implemented by things that know how to parse the final ID String field of full and compact SDRs.
type StringDecoderFunc ¶ added in v0.11.0
StringDecoderFunc eases implementation of stateless StringDecoders.
type StringEncoding ¶ added in v0.11.0
type StringEncoding uint8
StringEncoding describes the most significant two bits of the SDR Type/Length Byte, specified in 37.15 and 43.15 of v1.5 and v2.0 respectively.
const ( // StringEncodingUnicode, contrary to the name, typically suggests an // unspecified encoding. IPMItool displays a hex representation of the // underlying bytes, while OpenIPMI interprets it identically to // StringEncoding8BitAsciiLatin1. Given Unicode is only a character set and // the spec does not suggest any encoding, there is no right answer. The // resulting variety of implementations means use of this value by a BMC // should be regarded as a bug. StringEncodingUnicode StringEncoding = iota StringEncodingBCDPlus StringEncodingPacked6BitAscii StringEncoding8BitAsciiLatin1 )
func (StringEncoding) Decoder ¶ added in v0.11.0
func (e StringEncoding) Decoder() (StringDecoder, error)
func (StringEncoding) Description ¶ added in v0.11.0
func (e StringEncoding) Description() string
func (StringEncoding) String ¶ added in v0.11.0
func (e StringEncoding) String() string