diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs new file mode 100644 index 0000000..248a7e3 --- /dev/null +++ b/.git-blame-ignore-revs @@ -0,0 +1,2 @@ +# Whole-tree reformat with mvn formatter:format (#118) +13b1fdb37e3aa7f621d68d93c5118c7932ea7425 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..abf58b0 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,46 @@ +# Java sources +*.java text diff=java +*.kt text diff=kotlin +*.groovy text diff=java +*.scala text diff=java +*.gradle text diff=java +*.gradle.kts text diff=kotlin + +# These files are text and should be normalized (Convert crlf => lf) +*.css text diff=css +*.scss text diff=css +*.sass text +*.df text +*.htm text diff=html +*.html text diff=html +*.js text +*.mjs text +*.cjs text +*.jsp text +*.jspf text +*.jspx text +*.properties text +*.tld text +*.tag text +*.tagx text +*.xml text +*.md text diff=markdown +*.awk text + +# These files are binary and should be left untouched +# (binary is a macro for -text -diff) +*.class binary +*.dll binary +*.ear binary +*.jar binary +*.so binary +*.war binary +*.jks binary + +# Common build-tool wrapper scripts ('.cmd' versions are handled by 'Common.gitattributes') +mvnw text eol=lf +gradlew text eol=lf + +# These are explicitly windows files and should use crlf +*.bat text eol=crlf +*.cmd text eol=crlf diff --git a/AGENTS.md b/AGENTS.md index e7a49bf..6c38205 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -2,7 +2,9 @@ ## Code format -The project has not adopted the MetricsHub Eclipse formatter profile yet (see issue #118). Until it does, match the style of the file you are editing: the `org.metricshub.ipmi.client` packages use tabs, the `org.metricshub.ipmi.core` packages (forked from the Verax IPMI library) use 4 spaces. Do not reformat code you are not otherwise changing. Once `formatter-maven-plugin` is configured, simply run `mvn formatter:format` before committing. +The code is formatted with the MetricsHub Eclipse formatter profile (`metricshub-eclipse-formatter.xml`, byte-identical to jawk's): tabs, 120-column lines. `formatter:validate` runs at the `validate` phase, so unformatted code fails the build. Simply run `mvn formatter:format` before committing, and do not hand-format code. + +Checkstyle (`checkstyle.xml`, byte-identical to jawk's) runs at `verify` with `failOnViolation=true`. Fix violations rather than suppressing them; when a suppression is justified, wrap the code in `// CHECKSTYLE.OFF: ` / `// CHECKSTYLE.ON: ` comments. All Java source files under `src/main/java` must include the proper LGPL-3 license header (the `license-maven-plugin` check covers `main/java/**/*.java` only; tests, Markdown and resources carry no header). When you add a new source file, run `mvn license:update-file-header` before committing (and before building, since the build fails if a source file lacks the header). @@ -24,7 +26,7 @@ Unit tests must not depend on a real BMC. Exercising the RMCP+ session code agai ## Code quality reports -Code quality reports (checkstyle, pmd/cpd, spotbugs) are generated by `mvn verify site` into ./target/checkstyle-result.xml, ./target/pmd.xml, ./target/cpd.xml and ./target/spotbugsXml.xml. They are not yet gated (issues #114, #115, #116, #117 track the clean-up). Do not add new violations: check the reports for the files you changed before committing and submitting your code. On JDK 21+ the SpotBugs plugin version inherited from the parent POM cannot read the JDK class files; run `mvn com.github.spotbugs:spotbugs-maven-plugin:4.10.4.1:spotbugs` instead. +Code quality reports (checkstyle, pmd/cpd, spotbugs) are generated by `mvn verify site` into ./target/checkstyle-result.xml, ./target/pmd.xml, ./target/cpd.xml and ./target/spotbugsXml.xml. Checkstyle is gated (the build fails on any error); PMD/CPD and SpotBugs are not yet gated (issues #114, #115, #116 track the clean-up). Do not add new violations: check the reports for the files you changed before committing and submitting your code. On JDK 21+ the SpotBugs plugin version inherited from the parent POM cannot read the JDK class files; run `mvn com.github.spotbugs:spotbugs-maven-plugin:4.10.4.1:spotbugs` instead. ## Documentation diff --git a/README.md b/README.md index 0b941c7..3f1d6c6 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,10 @@ See **[Project Documentation](https://metricshub.org/ipmi-java)** and the [Javad The IPMI Java Client is a library that communicates with the IPMI host, fetches Field Replaceable Units (FRUs) and Sensors information then reports these information as a text output. +## Upgrading + +Version 1.2.03 makes the `protected` fields of the protocol classes (`AbstractIpmiRunner`, `MessageHandler`, `IpmiLanMessage`, `ConfidentialityAlgorithm`, `IntegrityAlgorithm`) `private`. Subclasses must use the new `protected` accessors instead; see [Upgrading from 1.2.02](https://metricshub.org/ipmi-java/#upgrading-from-1-2-02) for the list. The `IpmiClient` API is unchanged. + ## Build instructions This is a simple Maven project. Build with: @@ -18,6 +22,22 @@ This is a simple Maven project. Build with: mvn verify ``` +## Code format + +The code is formatted with the MetricsHub Eclipse formatter profile ([metricshub-eclipse-formatter.xml](metricshub-eclipse-formatter.xml), shared with the other MetricsHub Java projects), and the build fails on unformatted code. Simply run the below command before committing: + +```bash +mvn formatter:format +``` + +The build also fails on [Checkstyle](checkstyle.xml) violations. A justified violation can be suppressed with `// CHECKSTYLE.OFF: ` and `// CHECKSTYLE.ON: ` comments. + +To ignore the whole-tree reformat commit in `git blame`, run once: + +```bash +git config blame.ignoreRevsFile .git-blame-ignore-revs +``` + ## Release instructions The artifact is deployed to Sonatype's [Maven Central](https://central.sonatype.com/). diff --git a/checkstyle.xml b/checkstyle.xml index bfc0f4e..1d2dc1b 100644 --- a/checkstyle.xml +++ b/checkstyle.xml @@ -1,130 +1,131 @@ - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + --> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/metricshub-eclipse-formatter.xml b/metricshub-eclipse-formatter.xml new file mode 100644 index 0000000..dd97330 --- /dev/null +++ b/metricshub-eclipse-formatter.xml @@ -0,0 +1,401 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pom.xml b/pom.xml index 215c667..e4a343f 100644 --- a/pom.xml +++ b/pom.xml @@ -105,6 +105,49 @@ + + + net.revelc.code.formatter + formatter-maven-plugin + 2.29.0 + + + validate + + validate + + + + + + ${project.build.sourceDirectory} + ${project.build.testSourceDirectory} + + + **/*.java + + metricshub-eclipse-formatter.xml + + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + 3.6.0 + + true + checkstyle.xml + + + + + check + + + + + org.codehaus.mojo diff --git a/src/main/java/org/metricshub/ipmi/client/IpmiClient.java b/src/main/java/org/metricshub/ipmi/client/IpmiClient.java index 593311c..9c56610 100644 --- a/src/main/java/org/metricshub/ipmi/client/IpmiClient.java +++ b/src/main/java/org/metricshub/ipmi/client/IpmiClient.java @@ -38,24 +38,24 @@ /** * This class is the entry point of the IPMI Client library */ -public class IpmiClient { +public final class IpmiClient { - private IpmiClient() { - } + private IpmiClient() {} /** * Run the get Chassis status IPMI request * * @param ipmiConfiguration Wraps the IPMI device hostname and the credentials * @return {@link GetChassisStatusResponseData} instance - * * @throws InterruptedException * @throws ExecutionException * @throws TimeoutException */ public static GetChassisStatusResponseData getChassisStatus(final IpmiClientConfiguration ipmiConfiguration) - throws InterruptedException, ExecutionException, TimeoutException { - try (GetChassisStatusRunner runner = new GetChassisStatusRunner(ipmiConfiguration)){ + throws InterruptedException, + ExecutionException, + TimeoutException { + try (GetChassisStatusRunner runner = new GetChassisStatusRunner(ipmiConfiguration)) { return execute(runner, ipmiConfiguration.getTimeout() * 1000); } } @@ -65,13 +65,14 @@ public static GetChassisStatusResponseData getChassisStatus(final IpmiClientConf * * @param ipmiConfiguration Wraps the IPMI device hostname and the credentials * @return List of {@link Sensor} instances - * * @throws InterruptedException * @throws ExecutionException * @throws TimeoutException */ public static List getSensors(final IpmiClientConfiguration ipmiConfiguration) - throws InterruptedException, ExecutionException, TimeoutException { + throws InterruptedException, + ExecutionException, + TimeoutException { try (GetSensorsRunner runner = new GetSensorsRunner(ipmiConfiguration)) { return execute(runner, ipmiConfiguration.getTimeout() * 1000); } @@ -82,13 +83,14 @@ public static List getSensors(final IpmiClientConfiguration ipmiConfigur * * @param ipmiConfiguration Wraps the IPMI device hostname and the credentials * @return List of {@link Fru} instances - * * @throws InterruptedException * @throws ExecutionException * @throws TimeoutException */ public static List getFrus(final IpmiClientConfiguration ipmiConfiguration) - throws InterruptedException, ExecutionException, TimeoutException { + throws InterruptedException, + ExecutionException, + TimeoutException { try (GetFrusRunner runner = new GetFrusRunner(ipmiConfiguration)) { return execute(runner, ipmiConfiguration.getTimeout() * 1000); } @@ -104,7 +106,9 @@ public static List getFrus(final IpmiClientConfiguration ipmiConfiguration) * @throws InterruptedException */ public static String getChassisStatusAsStringResult(final IpmiClientConfiguration ipmiConfiguration) - throws InterruptedException, ExecutionException, TimeoutException { + throws InterruptedException, + ExecutionException, + TimeoutException { return IpmiResultConverter.convertResult(getChassisStatus(ipmiConfiguration)); } @@ -118,7 +122,9 @@ public static String getChassisStatusAsStringResult(final IpmiClientConfiguratio * @throws InterruptedException */ public static String getFrusAndSensorsAsStringResult(final IpmiClientConfiguration ipmiConfiguration) - throws InterruptedException, ExecutionException, TimeoutException { + throws InterruptedException, + ExecutionException, + TimeoutException { return IpmiResultConverter.convertResult(getFrus(ipmiConfiguration), getSensors(ipmiConfiguration)); } } diff --git a/src/main/java/org/metricshub/ipmi/client/IpmiClientConfiguration.java b/src/main/java/org/metricshub/ipmi/client/IpmiClientConfiguration.java index fad6cbf..57241da 100644 --- a/src/main/java/org/metricshub/ipmi/client/IpmiClientConfiguration.java +++ b/src/main/java/org/metricshub/ipmi/client/IpmiClientConfiguration.java @@ -27,7 +27,6 @@ /** * IPMI configuration including the required credentials that need to be used to establish the * communication with the IPMI interface. - * */ public class IpmiClientConfiguration { @@ -42,13 +41,13 @@ public class IpmiClientConfiguration { /** * Instantiates a new {@link IpmiClientConfiguration} in order to query the IPMI host. - * + * * @param hostname IP Address or host name of the remote IPMI host. * @param username Name used to establish the connection with the host via the IPMI protocol. * @param password Password used to establish the connection with the host via the IPMI protocol. - * @param bmcKey The key that should be provided if the two-key authentication is enabled, null otherwise. + * @param bmcKey The key that should be provided if the two-key authentication is enabled, null otherwise. * @param skipAuth Whether the client should skip authentication - * @param timeout Timeout used for each IPMI request. + * @param timeout Timeout used for each IPMI request. */ public IpmiClientConfiguration(String hostname, String username, char[] password, byte[] bmcKey, boolean skipAuth, long timeout) { @@ -62,14 +61,14 @@ public IpmiClientConfiguration(String hostname, String username, char[] password /** * Instantiates a new {@link IpmiClientConfiguration} in order to query the IPMI host. - * + * * @param hostname IP Address or host name of the remote IPMI host. * @param port UDP port number of the remote IPMI host. * @param username Name used to establish the connection with the host via the IPMI protocol. * @param password Password used to establish the connection with the host via the IPMI protocol. - * @param bmcKey The key that should be provided if the two-key authentication is enabled, null otherwise. + * @param bmcKey The key that should be provided if the two-key authentication is enabled, null otherwise. * @param skipAuth Whether the client should skip authentication - * @param timeout Timeout used for each IPMI request. + * @param timeout Timeout used for each IPMI request. */ public IpmiClientConfiguration(String hostname, int port, String username, char[] password, byte[] bmcKey, boolean skipAuth, long timeout) { @@ -79,15 +78,15 @@ public IpmiClientConfiguration(String hostname, int port, String username, char[ /** * Instantiates a new {@link IpmiClientConfiguration} in order to query the IPMI host. - * - * @param hostname IP Address or host name of the remote IPMI host. - * @param username Name used to establish the connection with the host via the IPMI protocol. - * @param password Password used to establish the connection with the host via the IPMI protocol. - * @param bmcKey The key that should be provided if the two-key authentication is enabled, null otherwise. - * @param skipAuth Whether the client should skip authentication - * @param timeout Timeout used for each IPMI request. + * + * @param hostname IP Address or host name of the remote IPMI host. + * @param username Name used to establish the connection with the host via the IPMI protocol. + * @param password Password used to establish the connection with the host via the IPMI protocol. + * @param bmcKey The key that should be provided if the two-key authentication is enabled, null otherwise. + * @param skipAuth Whether the client should skip authentication + * @param timeout Timeout used for each IPMI request. * @param pingPeriod The period in milliseconds used to send the keep alive messages.
- * Set pingPeriod to 0 to turn off keep-alive messages sent to the remote host. + * Set pingPeriod to 0 to turn off keep-alive messages sent to the remote host. */ public IpmiClientConfiguration(String hostname, String username, char[] password, byte[] bmcKey, boolean skipAuth, long timeout, long pingPeriod) { @@ -97,7 +96,7 @@ public IpmiClientConfiguration(String hostname, String username, char[] password /** * Returns the IP Address or host name of the remote IPMI host. - * + * * @return IP Address or host name of the remote IPMI host. */ public String getHostname() { @@ -106,7 +105,7 @@ public String getHostname() { /** * Sets the IP Address or host name of the remote IPMI host. - * + * * @param hostname IP Address or host name of the remote IPMI host. */ public void setHostname(String hostname) { @@ -115,7 +114,7 @@ public void setHostname(String hostname) { /** * Returns the UDP port number of the remote IPMI host. - * + * * @return UDP port number of the remote IPMI host. */ public int getPort() { @@ -124,7 +123,7 @@ public int getPort() { /** * Sets the UDP port number of the remote IPMI host. - * + * * @param port UDP port number of the remote IPMI host. */ public void setPort(int port) { @@ -134,7 +133,7 @@ public void setPort(int port) { /** * Returns the name used to establish the connection with the host via the IPMI * protocol. - * + * * @return Name used to establish the connection with the host via the IPMI protocol. */ public String getUsername() { @@ -144,9 +143,9 @@ public String getUsername() { /** * Sets the name used to establish the connection with the host via the IPMI * protocol. - * + * * @param username Name used to establish the connection with the host via the - * IPMI protocol. + * IPMI protocol. */ public void setUsername(String username) { this.username = username; @@ -155,7 +154,7 @@ public void setUsername(String username) { /** * Returns the password used to establish the connection with the host via the * IPMI protocol. - * + * * @return Password used to establish the connection with the host via the IPMI protocol. */ public char[] getPassword() { @@ -165,7 +164,7 @@ public char[] getPassword() { /** * Sets the password used to establish the connection with the host via the IPMI * protocol. - * + * * @param password Password used to establish the connection with the host via the IPMI protocol. */ public void setPassword(char[] password) { @@ -175,7 +174,7 @@ public void setPassword(char[] password) { /** * Returns the key that should be provided if the two-key authentication is * enabled, null otherwise. - * + * * @return The key that should be provided if the two-key authentication is * enabled, null otherwise. */ @@ -186,9 +185,9 @@ public byte[] getBmcKey() { /** * Sets the key that should be provided if the two-key authentication is * enabled, null otherwise. - * + * * @param bmcKey The key that should be provided if the two-key authentication - * is enabled, null otherwise. + * is enabled, null otherwise. */ public void setBmcKey(byte[] bmcKey) { this.bmcKey = bmcKey; @@ -196,7 +195,7 @@ public void setBmcKey(byte[] bmcKey) { /** * Returns whether the client should skip authentication. - * + * * @return Whether the client should skip authentication. */ public boolean isSkipAuth() { @@ -205,7 +204,7 @@ public boolean isSkipAuth() { /** * Sets whether the client should skip authentication. - * + * * @param skipAuth Whether the client should skip authentication. */ public void setSkipAuth(boolean skipAuth) { @@ -214,7 +213,7 @@ public void setSkipAuth(boolean skipAuth) { /** * Returns the timeout used for each IPMI request. - * + * * @return The timeout used for each IPMI request. */ public long getTimeout() { @@ -223,7 +222,7 @@ public long getTimeout() { /** * Sets the timeout used for each IPMI request. - * + * * @param timeout The timeout used for each IPMI request. */ public void setTimeout(long timeout) { @@ -232,7 +231,7 @@ public void setTimeout(long timeout) { /** * Returns the period in milliseconds used to send the keep alive messages. - * + * * @return The period in milliseconds used to send the keep alive messages. */ public long getPingPeriod() { @@ -242,7 +241,7 @@ public long getPingPeriod() { /** * Sets the period in milliseconds used to send the keep alive messages.
* Set pingPeriod to 0 to turn off keep-alive messages sent to the remote host. - * + * * @param pingPeriod The period in milliseconds used to send the keep alive messages. */ public void setPingPeriod(long pingPeriod) { diff --git a/src/main/java/org/metricshub/ipmi/client/IpmiResultConverter.java b/src/main/java/org/metricshub/ipmi/client/IpmiResultConverter.java index 2d50027..fb7ed08 100644 --- a/src/main/java/org/metricshub/ipmi/client/IpmiResultConverter.java +++ b/src/main/java/org/metricshub/ipmi/client/IpmiResultConverter.java @@ -49,7 +49,7 @@ import org.metricshub.ipmi.core.coding.commands.sdr.record.FullSensorRecord; import org.metricshub.ipmi.core.coding.commands.sdr.record.SensorUnit; -public class IpmiResultConverter { +public final class IpmiResultConverter { private static final double NO_READING = 255d; @@ -58,33 +58,32 @@ public class IpmiResultConverter { private static final DoubleFunction FAHRENHEIT_TO_CELSIUS_CONVERSION_FUNCTION = v -> (v - 32.0) * 0.5556; private static final DoubleFunction KELVIN_TO_CELSIUS_CONVERSION_FUNCTION = v -> v - 273.15; - private IpmiResultConverter() { - } + private IpmiResultConverter() {} /** * Convert the given List of FRUs and Sensors to a {@link String} result (semicolon-separated values) * - * @param frus The list of Field Replaceable Units (FRU) we wish to format as the following:
- * FRU;$vendor;$model;$serialNumber + * @param frus The list of Field Replaceable Units (FRU) we wish to format as the following:
+ * FRU;$vendor;$model;$serialNumber * @param sensors The list of sensor records (Compact or Full) we wish to format as the following:
- *
    - *
  • States: - * $deviceType;$deviceId;$deviceUniqueId;$vendor;$model;$serialNumber;$sensorName=$state|$sensorName=$state... - *
  • - *
  • Readings: - *
      - *
    • Temperature;$sensorId;$sensorName;$sensorUniqueId;$value;$threshold1;$threshold2
    • - *
    • Voltage;$sensorId;$sensorName;$sensorUniqueId;$value;$threshold1;$threshold2
    • - *
    • Fan;$sensorId;$sensorName;$sensorUniqueId;$value;$threshold1;$threshold2
    • - *
    • Current;$sensorId;$sensorName;$sensorUniqueId;$value
    • - *
    • PowerConsumption;$sensorId;$sensorName;$sensorUniqueId;$value
    • - *
    • Energy;$sensorId;$sensorName;$sensorUniqueId;$value
    • - *
    - *
  • - *
+ *
    + *
  • States: + * $deviceType;$deviceId;$deviceUniqueId;$vendor;$model;$serialNumber;$sensorName=$state|$sensorName=$state... + *
  • + *
  • Readings: + *
      + *
    • Temperature;$sensorId;$sensorName;$sensorUniqueId;$value;$threshold1;$threshold2
    • + *
    • Voltage;$sensorId;$sensorName;$sensorUniqueId;$value;$threshold1;$threshold2
    • + *
    • Fan;$sensorId;$sensorName;$sensorUniqueId;$value;$threshold1;$threshold2
    • + *
    • Current;$sensorId;$sensorName;$sensorUniqueId;$value
    • + *
    • PowerConsumption;$sensorId;$sensorName;$sensorUniqueId;$value
    • + *
    • Energy;$sensorId;$sensorName;$sensorUniqueId;$value
    • + *
    + *
  • + *
* @return String value */ - public static final String convertResult(final List frus, final List sensors) { + public static String convertResult(final List frus, final List sensors) { // FRU id to FRU Device used when processing the sensors Map frusLookup = new HashMap<>(); @@ -98,13 +97,15 @@ public static final String convertResult(final List frus, final List sensorReadings = processSensorReadings(sensors); - return Stream.of(fruRecords, sensorStates, sensorReadings) - .flatMap(Function.identity()) - .collect(Collectors.joining("\n")); + return Stream + .of(fruRecords, sensorStates, sensorReadings) + .flatMap(Function.identity()) + .collect(Collectors.joining("\n")); } /** - * Process the given sensors. Extracts only the full sensors then handle each full sensor to extract the reading value. E.g. PowerConsumption + * Process the given sensors. Extracts only the full sensors then handle each full sensor to extract the reading + * value. E.g. PowerConsumption * * @param sensors The sensor list we wish to process * @return The stream of the sensor readings @@ -112,18 +113,21 @@ public static final String convertResult(final List frus, final List processSensorReadings(final List sensors) { // Parse each full sensor as it should define the reading value and - return sensors.stream() - .filter(Sensor::isFull) - .filter(sensor -> sensor.getData() != null && sensor.getRecord() != null) - .map(IpmiResultConverter::extractFullSensorReadingValue) - .filter(Objects::nonNull); + return sensors + .stream() + .filter(Sensor::isFull) + .filter(sensor -> sensor.getData() != null && sensor.getRecord() != null) + .map(IpmiResultConverter::extractFullSensorReadingValue) + .filter(Objects::nonNull); } /** - * Handle a Full sensor to extract the reading value (temperature, voltage, Fan speed, current, power consumption, energy). + * Handle a Full sensor to extract the reading value (temperature, voltage, Fan speed, current, power consumption, + * energy). * * @param fullSensor The full sensor we wish to process - * @return The sensor reading as semicolon-separated values. E.g. Temperature;0001;Ambient Temp;Front Panel Board 1;22.0;38;41 + * @return The sensor reading as semicolon-separated values. E.g. Temperature;0001;Ambient Temp;Front Panel Board + * 1;22.0;38;41 */ private static String extractFullSensorReadingValue(final Sensor fullSensor) { @@ -178,68 +182,85 @@ private static String extractFullSensorReadingValue(final Sensor fullSensor) { } } - /** * Get the energy row using the given fields. * - * @param sensorId The id of the sensor - * @param sensorName The name of the sensor - * @param value The value to set + * @param sensorId The id of the sensor + * @param sensorName The name of the sensor + * @param value The value to set * @param sensorUniqueId The sensor unique id ($type $deviceId) * @return The energy sensor reading record formatted as Energy;$sensorId;$sensorName;$sensorUniqueId;$value */ - private static String energyRow(final String sensorId, final String sensorName, - final double value, final String sensorUniqueId) { + private static String energyRow( + final String sensorId, + final String sensorName, + final double value, + final String sensorUniqueId) { return String.join(";", "Energy", sensorId, sensorName, sensorUniqueId, String.valueOf(value)); } /** * Get the power consumption row using the given fields. * - * @param sensorId The id of the sensor - * @param sensorName The name of the sensor - * @param value The value to set + * @param sensorId The id of the sensor + * @param sensorName The name of the sensor + * @param value The value to set * @param sensorUniqueId The sensor unique id ($type $deviceId) - * @return The power consumption sensor reading record formatted as: PowerConsumption;$sensorId;$sensorName;$sensorUniqueId;$value + * @return The power consumption sensor reading record formatted as: + * PowerConsumption;$sensorId;$sensorName;$sensorUniqueId;$value */ - private static String powerConsumptionRow(final String sensorId, final String sensorName, - final double value, final String sensorUniqueId) { + private static String powerConsumptionRow( + final String sensorId, + final String sensorName, + final double value, + final String sensorUniqueId) { return String.join(";", "PowerConsumption", sensorId, sensorName, sensorUniqueId, String.valueOf(value)); } /** * Get the current row reading using the given fields. * - * @param sensorId The id of the sensor - * @param sensorName The name of the sensor - * @param value The value to set + * @param sensorId The id of the sensor + * @param sensorName The name of the sensor + * @param value The value to set * @param sensorUniqueId The sensor unique id ($type $deviceId) * @return Current sensor reading record formatted as: Current;$sensorId;$sensorName;$sensorUniqueId;$value */ - private static String currentRow(final String sensorId, final String sensorName, - final double value, final String sensorUniqueId) { + private static String currentRow( + final String sensorId, + final String sensorName, + final double value, + final String sensorUniqueId) { return String.join(";", "Current", sensorId, sensorName, sensorUniqueId, String.valueOf(value)); } /** * Get the fan speed row using the given fields. * - * @param sensor The full sensor record used to extract the threshold 1 and threshold 2. - *
    - *
  1. Threshold 1 is the LowerCriticalThreshold otherwise we get the - * LowerNonRecoverableThreshold.
  2. - *
  3. Threshold 2 is the LowerNonCriticalThreshold
  4. - *
- * @param sensorId The id of the sensor - * @param sensorName The name of the sensor - * @param value The value to set + * @param sensor The full sensor record used to extract the threshold 1 and threshold 2. + *
    + *
  1. Threshold 1 is the LowerCriticalThreshold otherwise we get the + * LowerNonRecoverableThreshold.
  2. + *
  3. Threshold 2 is the LowerNonCriticalThreshold
  4. + *
+ * @param sensorId The id of the sensor + * @param sensorName The name of the sensor + * @param value The value to set * @param sensorUniqueId The sensor unique id ($type $deviceId) - * @return The Fan speed sensor reading record formatted as: Fan;$sensorId;$sensorName;$sensorUniqueId;$value;$threshold1;$threshold2 + * @return The Fan speed sensor reading record formatted as: + * Fan;$sensorId;$sensorName;$sensorUniqueId;$value;$threshold1;$threshold2 */ - private static String fanSpeedRow(final FullSensorRecord sensor, final String sensorId, - final String sensorName, final double value, final String sensorUniqueId) { - - String threshold1 = getAvailableThreshold(IDENTITY_FUNCTION, sensor.getLowerCriticalThreshold(), sensor.getLowerNonRecoverableThreshold()); + private static String fanSpeedRow( + final FullSensorRecord sensor, + final String sensorId, + final String sensorName, + final double value, + final String sensorUniqueId) { + + String threshold1 = getAvailableThreshold( + IDENTITY_FUNCTION, + sensor.getLowerCriticalThreshold(), + sensor.getLowerNonRecoverableThreshold()); String threshold2 = getThresholdValue(IDENTITY_FUNCTION, sensor.getLowerNonCriticalThreshold()); @@ -249,50 +270,76 @@ private static String fanSpeedRow(final FullSensorRecord sensor, final String se /** * Get the voltage row using the given fields. * - * @param sensor The full sensor record used to extract the threshold 1 and threshold 2. - *
    - *
  1. Threshold 1 is the LowerNonCriticalThreshold otherwise we get the - * LowerCriticalThreshold.
  2. - *
  3. Threshold 2 is the UpperNonCriticalThreshold otherwise we get the - * UpperCriticalThreshold, if both thresholds are not available then we get the - * UpperNonRecoverableThreshold
  4. - *
- * @param sensorId The id of the sensor - * @param sensorName The name of the sensor - * @param value The value to set + * @param sensor The full sensor record used to extract the threshold 1 and threshold 2. + *
    + *
  1. Threshold 1 is the LowerNonCriticalThreshold otherwise we get the + * LowerCriticalThreshold.
  2. + *
  3. Threshold 2 is the UpperNonCriticalThreshold otherwise we get the + * UpperCriticalThreshold, if both thresholds are not available then we get the + * UpperNonRecoverableThreshold
  4. + *
+ * @param sensorId The id of the sensor + * @param sensorName The name of the sensor + * @param value The value to set * @param sensorUniqueId The sensor unique id ($type $deviceId) - * @return Voltage sensor reading record formatted as: Voltage;$sensorId;$sensorName;$sensorUniqueId;$value;$threshold1;$threshold2 + * @return Voltage sensor reading record formatted as: + * Voltage;$sensorId;$sensorName;$sensorUniqueId;$value;$threshold1;$threshold2 */ - private static String voltageRow(final FullSensorRecord sensor, final String sensorId, - final String sensorName, final double value, final String sensorUniqueId) { - - String threshold1 = getAvailableThreshold(VOLTAGE_CONVERSION_FUNCTION, sensor.getLowerNonCriticalThreshold(), sensor.getLowerCriticalThreshold(), + private static String voltageRow( + final FullSensorRecord sensor, + final String sensorId, + final String sensorName, + final double value, + final String sensorUniqueId) { + + String threshold1 = getAvailableThreshold( + VOLTAGE_CONVERSION_FUNCTION, + sensor.getLowerNonCriticalThreshold(), + sensor.getLowerCriticalThreshold(), sensor.getLowerNonRecoverableThreshold()); - String threshold2 = getAvailableThreshold(VOLTAGE_CONVERSION_FUNCTION, sensor.getUpperNonCriticalThreshold(), sensor.getUpperCriticalThreshold(), + String threshold2 = getAvailableThreshold( + VOLTAGE_CONVERSION_FUNCTION, + sensor.getUpperNonCriticalThreshold(), + sensor.getUpperCriticalThreshold(), sensor.getUpperNonRecoverableThreshold()); - return String.join(";", "Voltage", sensorId, sensorName, sensorUniqueId, String.valueOf(value * 1000), threshold1, threshold2); + return String + .join( + ";", + "Voltage", + sensorId, + sensorName, + sensorUniqueId, + String.valueOf(value * 1000), + threshold1, + threshold2); } /** * Get the temperature row using the given fields. * - * @param sensor The full sensor record used to extract the threshold 1 and threshold 2. - *
    - *
  1. Threshold 1 is the UpperNonCriticalThreshold.
  2. - *
  3. Threshold 2 is the UpperCriticalThreshold otherwise we get the - * UpperNonRecoverableThreshold
  4. - *
- * @param sensorId The id of the sensor - * @param sensorName The name of the sensor - * @param value The value to set, always converted to Degrees Celsius - * @param unit The unit used to convert Fahrenheit to Celsius or Kelvin to Celsius + * @param sensor The full sensor record used to extract the threshold 1 and threshold 2. + *
    + *
  1. Threshold 1 is the UpperNonCriticalThreshold.
  2. + *
  3. Threshold 2 is the UpperCriticalThreshold otherwise we get the + * UpperNonRecoverableThreshold
  4. + *
+ * @param sensorId The id of the sensor + * @param sensorName The name of the sensor + * @param value The value to set, always converted to Degrees Celsius + * @param unit The unit used to convert Fahrenheit to Celsius or Kelvin to Celsius * @param sensorUniqueId The sensor unique id ($type $deviceId) - * @return Temperature sensor reading record formatted as: Temperature;$sensorId;$sensorName;$sensorUniqueId;$value;$threshold1;$threshold2 + * @return Temperature sensor reading record formatted as: + * Temperature;$sensorId;$sensorName;$sensorUniqueId;$value;$threshold1;$threshold2 */ - private static String temperatureRow(final FullSensorRecord sensor, final String sensorId, - final String sensorName, double value, final SensorUnit unit, final String sensorUniqueId) { + private static String temperatureRow( + final FullSensorRecord sensor, + final String sensorId, + final String sensorName, + double value, + final SensorUnit unit, + final String sensorUniqueId) { DoubleFunction conversionFunction = IDENTITY_FUNCTION; if (SensorUnit.DegreesF.equals(unit)) { @@ -304,21 +351,27 @@ private static String temperatureRow(final FullSensorRecord sensor, final String } String threshold1 = getThresholdValue(conversionFunction, sensor.getUpperNonCriticalThreshold()); - String threshold2 = getAvailableThreshold(conversionFunction, sensor.getUpperCriticalThreshold(), sensor.getUpperNonRecoverableThreshold()); + String threshold2 = getAvailableThreshold( + conversionFunction, + sensor.getUpperCriticalThreshold(), + sensor.getUpperNonRecoverableThreshold()); value = conversionFunction.apply(value); - return String.join(";", "Temperature", sensorId, sensorName, sensorUniqueId, String.valueOf(value), threshold1, threshold2); + return String + .join(";", "Temperature", sensorId, sensorName, sensorUniqueId, String.valueOf(value), threshold1, threshold2); } /** * Process the sensor states * - * @param sensors The sensor list we wish to process - * @param frusLookup The FRUs lookup used to extract vendor, model and serial number + * @param sensors The sensor list we wish to process + * @param frusLookup The FRUs lookup used to extract vendor, model and serial number * @return The stream of sensor records including sensor states */ - private static Stream processSensorStates(final List sensors, final Map frusLookup) { + private static Stream processSensorStates( + final List sensors, + final Map frusLookup) { Map sensorEntries = new LinkedHashMap<>(); @@ -331,11 +384,14 @@ private static Stream processSensorStates(final List sensors, fi * Extract the sensor state and format the result as the following:
* $deviceType;$deviceId;$deviceUniqueId;$vendor;$model;$serialNumber;$sensorName=$state|$sensorName=$state... * - * @param sensor The sensor we wish to extract its states - * @param frusLookup The FRUs lookup that should contain sensor metadata, vendor, model and serial number + * @param sensor The sensor we wish to extract its states + * @param frusLookup The FRUs lookup that should contain sensor metadata, vendor, model and serial number * @param sensorEntries The sensor entries used to append existing device states */ - private static void extractSensorStates(final Sensor sensor, final Map frusLookup, final Map sensorEntries) { + private static void extractSensorStates( + final Sensor sensor, + final Map frusLookup, + final Map sensorEntries) { // Get the sensor states String states = sensor.getStates(); @@ -346,7 +402,10 @@ private static void extractSensorStates(final Sensor sensor, final Map - * FRU;$vendor;$model;$serialNumber - * @param frusLookup The frusLookup used to store the FRUs indexed by the unique identifier in order to easily fetch them at the sensors - * processing step. + * @param frus The list of Field Replaceable Units (FRU) we wish to format as the following:
+ * FRU;$vendor;$model;$serialNumber + * @param frusLookup The frusLookup used to store the FRUs indexed by the unique identifier in order to easily fetch + * them at the sensors + * processing step. * @return The stream of the FRU record including very good, good and poor FRUs */ private static Stream processFrus(final List frus, final Map frusLookup) { @@ -411,7 +471,9 @@ private static Stream processFrus(final List frus, final Map processFrus(final List frus, final Mapnull if the vendor or the model cannot be collected */ private static FruDevice createFruDeviceFromBoardInfo(final LinkedList poorFruList, final Fru fru) { @@ -478,24 +542,29 @@ private static FruDevice createFruDeviceFromBoardInfo(final LinkedList veryGoodFruList, final LinkedList goodFruList, - LinkedList poorFruList, EntityId entityId, ProductInfo productInfo) { + private static FruDevice createFruDeviceFromProductInfo( + final LinkedList veryGoodFruList, + final LinkedList goodFruList, + LinkedList poorFruList, + EntityId entityId, + ProductInfo productInfo) { String vendor = Utils.getValueOrEmpty(productInfo.getManufacturerName()); String model = Utils.getValueOrEmpty(productInfo.getProductName()); @@ -526,8 +595,9 @@ private static FruDevice createFruDeviceFromProductInfo(final LinkedListtrue if the EntityId is a panel */ private static boolean isFruPanel(final EntityId entityId) { - return EntityId.FrontPanelBoard.equals(entityId) || EntityId.BackPanelBoard.equals(entityId) + return EntityId.FrontPanelBoard.equals(entityId) + || EntityId.BackPanelBoard.equals(entityId) || EntityId.ChassisBackPanelBoard.equals(entityId); } /** - * * @param entityId The {@link EntityId} instance defining the type of the device * @return true if the EntityId is the system */ @@ -568,7 +637,8 @@ private static boolean hasValidProductInfo(final ProductInfo productInfo) { /** * @param - * @param fruRecords List of {@link FruRecord} instances containing {@link BoardInfo} and {@link ProductInfo} instances + * @param fruRecords List of {@link FruRecord} instances containing {@link BoardInfo} and {@link ProductInfo} + * instances * @param clazz * @return The first matching instance */ @@ -577,7 +647,8 @@ private static T getInfo(final List fruRecords, return null; } - return fruRecords.stream() + return fruRecords + .stream() .filter(clazz::isInstance) .map(clazz::cast) .findFirst() @@ -589,7 +660,7 @@ private static T getInfo(final List fruRecords, * Get the threshold value as String * * @param conversionFunction The conversion function used to convert the threshold value - * @param threshold The double value returned by the IPMI Full record + * @param threshold The double value returned by the IPMI Full record * @return String value */ private static String getThresholdValue(final DoubleFunction conversionFunction, double threshold) { @@ -598,12 +669,13 @@ private static String getThresholdValue(final DoubleFunction conversionF /** * @param conversionFunction The conversion function used to convert the threshold value - * @param thresholds The array of the threshold values + * @param thresholds The array of the threshold values * @return The first available threshold in thresholds */ private static String getAvailableThreshold(final DoubleFunction conversionFunction, double... thresholds) { - return Arrays.stream(thresholds) + return Arrays + .stream(thresholds) .filter(threshold -> threshold != 0.0) .mapToObj(threshold -> getThresholdValue(conversionFunction, threshold)) .findFirst() diff --git a/src/main/java/org/metricshub/ipmi/client/Utils.java b/src/main/java/org/metricshub/ipmi/client/Utils.java index 3b96e6f..7bb1982 100644 --- a/src/main/java/org/metricshub/ipmi/client/Utils.java +++ b/src/main/java/org/metricshub/ipmi/client/Utils.java @@ -32,7 +32,7 @@ import org.metricshub.ipmi.client.runner.AbstractIpmiRunner; -public class Utils { +public final class Utils { private Utils() {} @@ -78,13 +78,14 @@ public static String getValueOrEmpty(String value) { * @param callable * @param timeout * @return {@link T} result returned by the callable - * * @throws InterruptedException * @throws ExecutionException * @throws TimeoutException */ public static T execute(final AbstractIpmiRunner callable, long timeout) - throws InterruptedException, ExecutionException, TimeoutException { + throws InterruptedException, + ExecutionException, + TimeoutException { final ExecutorService executorService = Executors.newSingleThreadExecutor(); final Future future = executorService.submit(callable); diff --git a/src/main/java/org/metricshub/ipmi/client/model/DeviceDescription.java b/src/main/java/org/metricshub/ipmi/client/model/DeviceDescription.java index 06bed2e..bbd944a 100644 --- a/src/main/java/org/metricshub/ipmi/client/model/DeviceDescription.java +++ b/src/main/java/org/metricshub/ipmi/client/model/DeviceDescription.java @@ -31,10 +31,9 @@ /** * {@link EntityId} mapping to match the IPMIUtil C code. */ -public class DeviceDescription { +public final class DeviceDescription { - private DeviceDescription() { - } + private DeviceDescription() {} private static final Map ENTITY_ID_TO_ENTITY_DESCRIPTION; @@ -105,7 +104,8 @@ private DeviceDescription() { /** * @param entityId The {@link EntityId} key - * @return {@link String} value extracted from the internal lookup matching the output of IPMIUtil and the java verax IPMI lib + * @return {@link String} value extracted from the internal lookup matching the output of IPMIUtil and the java verax + * IPMI lib */ public static String getDeviceType(EntityId entityId) { return entityId != null ? ENTITY_ID_TO_ENTITY_DESCRIPTION.getOrDefault(entityId, entityId.name()) : null; diff --git a/src/main/java/org/metricshub/ipmi/client/model/Fru.java b/src/main/java/org/metricshub/ipmi/client/model/Fru.java index bad8481..f542382 100644 --- a/src/main/java/org/metricshub/ipmi/client/model/Fru.java +++ b/src/main/java/org/metricshub/ipmi/client/model/Fru.java @@ -48,7 +48,6 @@ public Fru(FruDeviceLocatorRecord fruLocator, List fruRecords) { } /** - * * @return Current {@link FruDeviceLocatorRecord} instance */ public FruDeviceLocatorRecord getFruLocator() { @@ -56,7 +55,6 @@ public FruDeviceLocatorRecord getFruLocator() { } /** - * * @return Current {@link FruRecord} instance */ public List getFruRecords() { diff --git a/src/main/java/org/metricshub/ipmi/client/model/FruDevice.java b/src/main/java/org/metricshub/ipmi/client/model/FruDevice.java index 5a932ec..7d77c70 100644 --- a/src/main/java/org/metricshub/ipmi/client/model/FruDevice.java +++ b/src/main/java/org/metricshub/ipmi/client/model/FruDevice.java @@ -51,12 +51,12 @@ public String getSerialNumber() { @Override public String toString() { return new StringBuilder("FRU;") - .append(vendor) - .append(";") - .append(model) - .append(";") - .append(serialNumber) - .toString(); + .append(vendor) + .append(";") + .append(model) + .append(";") + .append(serialNumber) + .toString(); } } diff --git a/src/main/java/org/metricshub/ipmi/client/model/ReadingTypeDescription.java b/src/main/java/org/metricshub/ipmi/client/model/ReadingTypeDescription.java index 0d2a6e2..f906524 100644 --- a/src/main/java/org/metricshub/ipmi/client/model/ReadingTypeDescription.java +++ b/src/main/java/org/metricshub/ipmi/client/model/ReadingTypeDescription.java @@ -22,7 +22,10 @@ * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ */ +// This class is a lookup table over (almost) every ReadingType constant +// CHECKSTYLE.OFF: AvoidStarImport import static org.metricshub.ipmi.core.coding.commands.sdr.record.ReadingType.*; +// CHECKSTYLE.ON: AvoidStarImport import java.util.Collections; import java.util.EnumMap; @@ -33,12 +36,11 @@ /** * {@link ReadingType} mapping to match the IPMIUtil event sensor types (states) */ -public class ReadingTypeDescription { +public final class ReadingTypeDescription { private static final String PREDICTIVE_FAILURE = "Predictive failure"; - private ReadingTypeDescription() { - } + private ReadingTypeDescription() {} private static final Map READING_TYPE_TO_DESCRIPTION; @@ -56,11 +58,13 @@ private ReadingTypeDescription() { map.put(SlotConnectorReadyForDeviceInstallation, "Ready for Device Installation"); map.put(PxeBootRequested, "User requested PXE boot"); map.put(FruActive, "Active"); - map.put(InvalidUsernameOrPassword, "Invalid Username Or Password"); // No correspondence found in ipmiTool code - Update MS_HW_IpmiTool.hdf (Awk) + map.put(InvalidUsernameOrPassword, "Invalid Username Or Password"); // No correspondence found in ipmiTool code - + // Update MS_HW_IpmiTool.hdf (Awk) map.put(SlotConnectorReadyForDeviceRemoval, "Ready for Device Removal"); map.put(AutomaticBootToDiagnostic, "Automatic boot to diagnostic"); map.put(FruDeactivationRequested, "Deactivation Requested"); - map.put(InvalidPasswordDisable, "Invalid Password Disable"); // No correspondence found in ipmiTool code - Update MS_HW_IpmiTool.hdf (Awk) + map.put(InvalidPasswordDisable, "Invalid Password Disable"); // No correspondence found in ipmiTool code - Update + // MS_HW_IpmiTool.hdf (Awk) map.put(EntityPresent, "Device Present"); map.put(SlotPowerOff, "Slot Power is Off"); map.put(SoftwareInitiatedHardReset, "OS initiated hard reset"); @@ -95,13 +99,15 @@ private ReadingTypeDescription() { map.put(ProcessorDisabled, "Disabled"); map.put(ConsistencyOrParityCheckInProgress, "Parity Check In Progress"); map.put(TerminatorPresenceDetected, "Terminator presence detected"); - map.put(SecureModeViolationAttempt, "Secure Mode Violation Attempt"); // No correspondence found in ipmiTool code - Update MS_HW_IpmiTool.hdf (Awk) + map.put(SecureModeViolationAttempt, "Secure Mode Violation Attempt"); // No correspondence found in ipmiTool code - + // Update MS_HW_IpmiTool.hdf (Awk) map.put(OsGracefulStop, "OS graceful stop"); map.put(InCriticalArray, "In Critical Array"); map.put(ProcessorAutomaticallyThrottled, "Throttled"); map.put(PreBootUserPasswordViolation, "Pre-boot password violation - user password"); map.put(OsGracefulShutdown, "OS graceful shutdown"); - map.put(MachineCheckException, "Machine Check Exception"); // No correspondence found in ipmiTool code - Update MS_HW_IpmiTool.hdf (Awk) + map.put(MachineCheckException, "Machine Check Exception"); // No correspondence found in ipmiTool code - Update + // MS_HW_IpmiTool.hdf (Awk) map.put(PreBootSetupPasswordViolation, "Pre-boot password violation - setup password"); map.put(SoftOsShutdown, "PEF initiated soft shutdown"); map.put(PreBootNetworkPasswordViolation, "Pre-boot password violation - network boot password"); @@ -120,7 +126,8 @@ private ReadingTypeDescription() { map.put(MemoryConfigurationError, "Configuration Error"); map.put(SpareMemoryUnit, "Spare"); map.put(MemoryAutomaticallyThrottled, "Throttled"); - map.put(MemoryCriticalOvertemperature, "Critical Overtemperature"); // No correspondence found in ipmiTool code - Update MS_HW_IpmiTool.hdf (Awk) + map.put(MemoryCriticalOvertemperature, "Critical Overtemperature"); // No correspondence found in ipmiTool code - + // Update MS_HW_IpmiTool.hdf (Awk) map.put(SystemReconfigured, "System Reconfigured"); map.put(OemSystemBootEvent, "OEM System boot event"); map.put(ABootCompleted, "A: boot completed"); @@ -188,7 +195,15 @@ private ReadingTypeDescription() { map.put(TransitionToCriticalFromLessSevere, "Transition to Critical from less severe"); map.put(SelAlmostFull, "Log almost full"); map.put(TransitionToNonRecoverableFromLessSevere, "Transition to Non-recoverable from less severe"); - map.put(CorrectableMachineCheckErrorLoggingDisabled, "Correctable Machine Check Error Logging Disabled"); // No correspondence found in ipmiTool code - Update MS_HW_IpmiTool.hdf (Awk) + map.put(CorrectableMachineCheckErrorLoggingDisabled, "Correctable Machine Check Error Logging Disabled"); // No + // correspondence + // found + // in + // ipmiTool + // code - + // Update + // MS_HW_IpmiTool.hdf + // (Awk) map.put(TransitionToNonCriticalFromMoreSevere, "Transition to Non-critical from more severe"); map.put(TransitionToCriticalFromNonRecoverable, "Transition to Critical from Non-recoverable"); map.put(SlotConnectorDeviceRemovalRequest, "Device Removal Request"); @@ -210,7 +225,8 @@ private ReadingTypeDescription() { map.put(SuccessfulSoftwareOrFWChangeDetected, "Firmware or software change success"); map.put(InFailedArray, "In Failed Array"); map.put(RebuildRemapInProgress, "Rebuild In Progress"); - map.put(CorrectableMachineCheckError, "Correctable Machine Check Error"); // No correspondence found in ipmiTool code - Update MS_HW_IpmiTool.hdf (Awk) + map.put(CorrectableMachineCheckError, "Correctable Machine Check Error"); // No correspondence found in ipmiTool + // code - Update MS_HW_IpmiTool.hdf (Awk) map.put(RebuildRemapAborted, "Rebuild Aborted"); map.put(Ierr, "IERR"); map.put(ChipsetSoftPowerControlFailure, "Soft-power control failure"); @@ -234,7 +250,10 @@ private ReadingTypeDescription() { map.put(AcpiS2SleepingProcessorContextLost, "S2: sleeping, processor context lost"); map.put(PowerSupplyFailureDetected, "Failure detected"); map.put(TimerInterrupt, "Timer interrupt"); - map.put(AcpiS3SleepingProcessorContextLostMemoryRetained, "S3: sleeping, processor & hw context lost, memory retained"); + map + .put( + AcpiS3SleepingProcessorContextLostMemoryRetained, + "S3: sleeping, processor & hw context lost, memory retained"); map.put(PowerSupplyPredictiveFailure, PREDICTIVE_FAILURE); map.put(NonRedundant_SufficientResourcesFromInsufficientResources, "Non-Redundant: Sufficient from Insufficient"); map.put(AcpiS4NonVolatileSleep, "S4: non-volatile sleep/suspend-to-disk"); @@ -286,7 +305,8 @@ private ReadingTypeDescription() { /** * @param readingType The {@link ReadingType} key - * @return {@link String} value extracted from the internal lookup matching the output of IPMIUtil and the java verax IPMI lib + * @return {@link String} value extracted from the internal lookup matching the output of IPMIUtil and the java verax + * IPMI lib */ public static String getReadingType(ReadingType readingType) { return READING_TYPE_TO_DESCRIPTION.get(readingType); diff --git a/src/main/java/org/metricshub/ipmi/client/model/Sensor.java b/src/main/java/org/metricshub/ipmi/client/model/Sensor.java index 1e011a0..6419fd8 100644 --- a/src/main/java/org/metricshub/ipmi/client/model/Sensor.java +++ b/src/main/java/org/metricshub/ipmi/client/model/Sensor.java @@ -31,11 +31,14 @@ /** * Wraps Sensor information: *
    - *
  • The Sensor record which can be either {@link CompactSensorRecord} or {@link FullSensorRecord}. Note that the compact sensor record is - * used to discover and collect the state of the devices, where the full sensor record is used to collect the devices reading values, i.e. + *
  • The Sensor record which can be either {@link CompactSensorRecord} or {@link FullSensorRecord}. Note that the + * compact sensor record is + * used to discover and collect the state of the devices, where the full sensor record is used to collect the devices + * reading values, i.e. * temperature, power consumption, voltage, ...etc.
  • *
  • The sensor reading response data wrapping the reading value
  • - *
  • The states of the sensor record formatted as the following: $sensorName=$state|$sensorName=$state|...|$sensorName=$state
  • + *
  • The states of the sensor record formatted as the following: + * $sensorName=$state|$sensorName=$state|...|$sensorName=$state
  • *
*/ public class Sensor { diff --git a/src/main/java/org/metricshub/ipmi/client/model/package-info.java b/src/main/java/org/metricshub/ipmi/client/model/package-info.java index 1396bd3..7c5dbd2 100644 --- a/src/main/java/org/metricshub/ipmi/client/model/package-info.java +++ b/src/main/java/org/metricshub/ipmi/client/model/package-info.java @@ -1,5 +1,6 @@ /** - * Includes the IPMI data model for Field Replaceable Unit (FRU) and Sensor devices to be managed by the {@link org.metricshub.ipmi.client.IpmiResultConverter} class.
+ * Includes the IPMI data model for Field Replaceable Unit (FRU) and Sensor devices to be managed by the + * {@link org.metricshub.ipmi.client.IpmiResultConverter} class.
*/ package org.metricshub.ipmi.client.model; /*- diff --git a/src/main/java/org/metricshub/ipmi/client/runner/AbstractIpmiRunner.java b/src/main/java/org/metricshub/ipmi/client/runner/AbstractIpmiRunner.java index 77ade3f..9be79cc 100644 --- a/src/main/java/org/metricshub/ipmi/client/runner/AbstractIpmiRunner.java +++ b/src/main/java/org/metricshub/ipmi/client/runner/AbstractIpmiRunner.java @@ -55,10 +55,12 @@ public abstract class AbstractIpmiRunner implements AutoCloseable, Callable implements AutoCloseable, Callable implements AutoCloseable, Callable * This method will instantiate the internal fields: - * + * * @throws Exception If an error occurs when starting the session */ protected void startSession() throws Exception { @@ -104,30 +141,40 @@ protected void startSession() throws Exception { if (!ipmiConfiguration.isSkipAuth()) { authenticate(); } else { - handle = connector.createConnection(InetAddress.getByName(ipmiConfiguration.getHostname()), - ipmiConfiguration.getPort(), Connection.getDefaultCipherSuite(), PrivilegeLevel.User); + handle = connector + .createConnection( + InetAddress.getByName(ipmiConfiguration.getHostname()), + ipmiConfiguration.getPort(), + Connection.getDefaultCipherSuite(), + PrivilegeLevel.User); } // Start the session, provide user name and password, and optionally the // BMC key (only if the remote host has two-key authentication enabled, // otherwise this parameter should be null) - connector.openSession(handle, ipmiConfiguration.getUsername(), - String.valueOf(ipmiConfiguration.getPassword()), ipmiConfiguration.getBmcKey()); + connector + .openSession( + handle, + ipmiConfiguration.getUsername(), + String.valueOf(ipmiConfiguration.getPassword()), + ipmiConfiguration.getBmcKey()); } /** * Authenticate IPMI - * + * * @throws Exception If the authentication fails */ - public void authenticate() throws Exception { + public void authenticate() throws Exception { // Create the connection and get the handle, specify IP address of the // remote host. The connection is being registered in ConnectionManager, // the handle will be needed to identify it among other connections // (target IP address isn't enough, since we can handle multiple // connections to the same host) - handle = connector.createConnection(InetAddress.getByName(ipmiConfiguration.getHostname()), - ipmiConfiguration.getPort()); + handle = connector + .createConnection( + InetAddress.getByName(ipmiConfiguration.getHostname()), + ipmiConfiguration.getPort()); // Get available cipher suites list via getAvailableCipherSuites and // pick one of them that will be used further in the session. @@ -140,12 +187,12 @@ public void authenticate() throws Exception { /** * Get the available cipher suite. Get the last available if many cipher suites coexist.
- * + * * @return {@link CipherSuite} instance * @throws Exception when sending message to the managed system fails or suites not found */ protected CipherSuite getAvailableCipherSuite() throws Exception { - + // Get cipher suites supported by the remote host List suites = connector.getAvailableCipherSuites(handle); @@ -182,9 +229,11 @@ public void close() { /** * Using the reservation id, get the {@link SensorRecord} instance by running a GetSdr IPMI request.
- * When the {@link SensorRecord} cannot be fetched using one request we try a second method, see getSensorViaChunks - * - * @param reservationId The reservation identifier that needs to be sent to the BMC so that it handles correctly the request + * When the {@link SensorRecord} cannot be fetched using one request we try a second method, see + * getSensorViaChunks + * + * @param reservationId The reservation identifier that needs to be sent to the BMC so that it handles correctly the + * request * @return {@link SensorRecord} instance * @throws Exception at sendMessage or if the error completion code is CannotRespond or UnspecifiedError */ @@ -193,8 +242,15 @@ protected SensorRecord getSensorData(int reservationId) throws Exception { // BMC capabilities are limited - that means that sometimes the // record size exceeds maximum size of the message. Since we don't // know what is the size of the record, we try to get whole one first - GetSdrResponseData data = (GetSdrResponseData) connector.sendMessage(handle, - new GetSdr(IpmiVersion.V20, handle.getCipherSuite(), AuthenticationType.RMCPPlus, reservationId, nextRecId)); + GetSdrResponseData data = (GetSdrResponseData) connector + .sendMessage( + handle, + new GetSdr( + IpmiVersion.V20, + handle.getCipherSuite(), + AuthenticationType.RMCPPlus, + reservationId, + nextRecId)); // Some BMCs answer with success but return fewer bytes than the // record length declared in the header: fall back to the chunked @@ -214,7 +270,8 @@ protected SensorRecord getSensorData(int reservationId) throws Exception { // The following error codes mean that record is too large to be // sent in one chunk. This means we need to split the data in // smaller parts. - if (e.getCompletionCode() != CompletionCode.CannotRespond && e.getCompletionCode() != CompletionCode.UnspecifiedError) { + if (e.getCompletionCode() != CompletionCode.CannotRespond + && e.getCompletionCode() != CompletionCode.UnspecifiedError) { throw e; } @@ -226,22 +283,38 @@ protected SensorRecord getSensorData(int reservationId) throws Exception { } /** - * Get SDR (sensor data record) by chunks of {@link #CHUNK_SIZE} bytes. We get the full record size from the first request, then + * Get SDR (sensor data record) by chunks of {@link #CHUNK_SIZE} bytes. We get the full record size from the first + * request, then * we query the IPMI interface to get the remaining parts. - * - * @param reservationId The reservation identifier that needs to be sent to the BMC so that it handles correctly the request + * + * @param reservationId The reservation identifier that needs to be sent to the BMC so that it handles correctly the + * request * @return {@link SensorRecord} instance * @throws Exception if one of the sendMessage calls fails */ protected SensorRecord getSensorViaChunks(int reservationId) throws Exception { // First we get the header of the record to find out its size. - GetSdrResponseData data = (GetSdrResponseData) connector.sendMessage(handle, new GetSdr(IpmiVersion.V20, handle.getCipherSuite(), - AuthenticationType.RMCPPlus, reservationId, nextRecId, 0, INITIAL_CHUNK_SIZE)); + GetSdrResponseData data = (GetSdrResponseData) connector + .sendMessage( + handle, + new GetSdr( + IpmiVersion.V20, + handle.getCipherSuite(), + AuthenticationType.RMCPPlus, + reservationId, + nextRecId, + 0, + INITIAL_CHUNK_SIZE)); byte[] header = data.getSensorRecordData(); if (header == null || header.length < HEADER_SIZE) { - LOGGER.warn("Skipping SDR record {} on {}: BMC returned {} byte(s) instead of the {}-byte header", nextRecId, - ipmiConfiguration.getHostname(), header == null ? 0 : header.length, HEADER_SIZE); + LOGGER + .warn( + "Skipping SDR record {} on {}: BMC returned {} byte(s) instead of the {}-byte header", + nextRecId, + ipmiConfiguration.getHostname(), + header == null ? 0 : header.length, + HEADER_SIZE); nextRecId = data.getNextRecordId(); return null; } @@ -265,14 +338,27 @@ protected SensorRecord getSensorViaChunks(int reservationId) throws Exception { bytesToRead = recSize - read; } - GetSdrResponseData part = (GetSdrResponseData) connector.sendMessage(handle, new GetSdr(IpmiVersion.V20, handle.getCipherSuite(), - AuthenticationType.RMCPPlus, reservationId, nextRecId, read, bytesToRead)); + GetSdrResponseData part = (GetSdrResponseData) connector + .sendMessage( + handle, + new GetSdr( + IpmiVersion.V20, + handle.getCipherSuite(), + AuthenticationType.RMCPPlus, + reservationId, + nextRecId, + read, + bytesToRead)); byte[] chunk = part.getSensorRecordData(); int got = chunk == null ? 0 : Math.min(bytesToRead, chunk.length); if (got == 0) { - LOGGER.warn("Skipping SDR record {} on {}: BMC returned no data at offset {}", nextRecId, - ipmiConfiguration.getHostname(), read); + LOGGER + .warn( + "Skipping SDR record {} on {}: BMC returned no data at offset {}", + nextRecId, + ipmiConfiguration.getHostname(), + read); nextRecId = data.getNextRecordId(); return null; } @@ -300,7 +386,12 @@ SensorRecord decodeRecord(byte[] recordData) { try { return SensorRecord.populateSensorRecord(recordData); } catch (RuntimeException e) { - LOGGER.warn("Skipping undecodable SDR record before id {} on {}: {}", nextRecId, ipmiConfiguration.getHostname(), e.getMessage()); + LOGGER + .warn( + "Skipping undecodable SDR record before id {} on {}: {}", + nextRecId, + ipmiConfiguration.getHostname(), + e.getMessage()); return null; } } diff --git a/src/main/java/org/metricshub/ipmi/client/runner/GetChassisStatusRunner.java b/src/main/java/org/metricshub/ipmi/client/runner/GetChassisStatusRunner.java index 3005497..f471f9b 100644 --- a/src/main/java/org/metricshub/ipmi/client/runner/GetChassisStatusRunner.java +++ b/src/main/java/org/metricshub/ipmi/client/runner/GetChassisStatusRunner.java @@ -42,8 +42,10 @@ public GetChassisStatusResponseData call() throws Exception { super.startSession(); // Send the UDP message and read the response - return (GetChassisStatusResponseData) connector.sendMessage(handle, - new GetChassisStatus(IpmiVersion.V20, handle.getCipherSuite(), AuthenticationType.RMCPPlus)); + return (GetChassisStatusResponseData) getConnector() + .sendMessage( + getHandle(), + new GetChassisStatus(IpmiVersion.V20, getHandle().getCipherSuite(), AuthenticationType.RMCPPlus)); } diff --git a/src/main/java/org/metricshub/ipmi/client/runner/GetFrusRunner.java b/src/main/java/org/metricshub/ipmi/client/runner/GetFrusRunner.java index 3b890ba..6260ac3 100644 --- a/src/main/java/org/metricshub/ipmi/client/runner/GetFrusRunner.java +++ b/src/main/java/org/metricshub/ipmi/client/runner/GetFrusRunner.java @@ -59,7 +59,8 @@ public class GetFrusRunner extends AbstractIpmiRunner> { private static final int DEFAULT_FRU_ID = 0; /** - * Size of data transmitted in single ReadFru command. Bigger values will improve performance. If server is returning "Invalid data field in + * Size of data transmitted in single ReadFru command. Bigger values will improve performance. If server is returning + * "Invalid data field in * Request." error during ReadFru command, FRU_READ_PACKET_SIZE should be decreased. */ private static final int FRU_READ_PACKET_SIZE = 16; @@ -79,7 +80,7 @@ public List call() throws Exception { // Id 0 indicates first record in SDR. Next IDs can be retrieved from // records - they are organized in a list and there is no BMC command to // get all of them. - nextRecId = 0; + setNextRecId(0); // Some BMCs allow getting sensor records without reservation, so we try // to do it that way first @@ -90,7 +91,7 @@ public List call() throws Exception { // We get sensor data until we encounter ID = 65535 which means that // this record is the last one. - while (nextRecId < MAX_REPO_RECORD_ID) { + while (getNextRecId() < MAX_REPO_RECORD_ID) { SensorRecord sensorRecord = null; @@ -116,8 +117,11 @@ public List call() throws Exception { // happen many times during getting all sensors, since BMC can't // manage parallel sessions and invalidates old one if new one // appears. - reservationId = ((ReserveSdrRepositoryResponseData) connector.sendMessage(handle, - new ReserveSdrRepository(IpmiVersion.V20, handle.getCipherSuite(), AuthenticationType.RMCPPlus))).getReservationId(); + reservationId = ((ReserveSdrRepositoryResponseData) getConnector() + .sendMessage( + getHandle(), + new ReserveSdrRepository(IpmiVersion.V20, getHandle().getCipherSuite(), AuthenticationType.RMCPPlus))) + .getReservationId(); } } @@ -126,14 +130,19 @@ public List call() throws Exception { } /** - * Process the given sensor record and create the system board FRU record. The new {@link Fru} is added to th FRU list result - * - * @param result List of {@link Fru} instance to append - * @param sensorRecord The sensor record to process + * Process the given sensor record and create the system board FRU record. The new {@link Fru} is added to th FRU list + * result + * + * @param result List of {@link Fru} instance to append + * @param sensorRecord The sensor record to process * @param systemBoardFruRecords The system board Fru records * @throws Exception */ - private void processFruRecord(final List result, final SensorRecord sensorRecord, final List systemBoardFruRecords) throws Exception { + private void processFruRecord( + final List result, + final SensorRecord sensorRecord, + final List systemBoardFruRecords) + throws Exception { try { // Process the FRU record Fru fru = null; @@ -147,38 +156,40 @@ private void processFruRecord(final List result, final SensorRecord sensorR fru = new Fru(fruLocator, fruRecords); } } - } else if (!systemBoardFruRecords.isEmpty() - && !systemBoardFruUpdated - && sensorRecord instanceof CompactSensorRecord - && ((CompactSensorRecord) sensorRecord).getEntityId().equals(EntityId.SystemBoard)) { + } else + if (!systemBoardFruRecords.isEmpty() + && !systemBoardFruUpdated + && sensorRecord instanceof CompactSensorRecord + && ((CompactSensorRecord) sensorRecord).getEntityId().equals(EntityId.SystemBoard)) { - // Since we can only access the SystemBoard components, - // we need to build the FruDeviceLocatorRecord for SystemBoard instance. + // Since we can only access the SystemBoard components, + // we need to build the FruDeviceLocatorRecord for SystemBoard instance. - // OK this can be one of the SystemBoard sensors - CompactSensorRecord compactSensorRecord = (CompactSensorRecord) sensorRecord; + // OK this can be one of the SystemBoard sensors + CompactSensorRecord compactSensorRecord = (CompactSensorRecord) sensorRecord; - BoardInfo boardInfo = systemBoardFruRecords.stream() - .filter(BoardInfo.class::isInstance) - .map(BoardInfo.class::cast) - .findFirst() - .orElse(null); + BoardInfo boardInfo = systemBoardFruRecords + .stream() + .filter(BoardInfo.class::isInstance) + .map(BoardInfo.class::cast) + .findFirst() + .orElse(null); - if (boardInfo != null) { + if (boardInfo != null) { - // Create the Fru locator - FruDeviceLocatorRecord locator = new FruDeviceLocatorRecord(); - locator.setFruEntityId(EntityId.SystemBoard.getCode()); - locator.setFruEntityInstance(compactSensorRecord.getEntityInstanceNumber()); - locator.setName(boardInfo.getBoardProductName() + " " + compactSensorRecord.getEntityInstanceNumber()); + // Create the Fru locator + FruDeviceLocatorRecord locator = new FruDeviceLocatorRecord(); + locator.setFruEntityId(EntityId.SystemBoard.getCode()); + locator.setFruEntityInstance(compactSensorRecord.getEntityInstanceNumber()); + locator.setName(boardInfo.getBoardProductName() + " " + compactSensorRecord.getEntityInstanceNumber()); - fru = new Fru(locator, systemBoardFruRecords); + fru = new Fru(locator, systemBoardFruRecords); - // OK, now we are good! - systemBoardFruUpdated = true; + // OK, now we are good! + systemBoardFruUpdated = true; - } - } + } + } // Add the Fru instance if (fru != null) { @@ -193,7 +204,7 @@ private void processFruRecord(final List result, final SensorRecord sensorR /** * Get the FRU records for the given FRU identifier fruId - * + * * @param fruId The unique identifier of the FRU * @return new List of {@link FruRecord} instances * @throws Exception @@ -202,8 +213,14 @@ private List getFruRecords(int fruId) throws Exception { List fruData = new ArrayList<>(); // get the FRU Inventory Area info - GetFruInventoryAreaInfoResponseData info = (GetFruInventoryAreaInfoResponseData) connector.sendMessage(handle, - new GetFruInventoryAreaInfo(IpmiVersion.V20, handle.getCipherSuite(), AuthenticationType.RMCPPlus, fruId)); + GetFruInventoryAreaInfoResponseData info = (GetFruInventoryAreaInfoResponseData) getConnector() + .sendMessage( + getHandle(), + new GetFruInventoryAreaInfo( + IpmiVersion.V20, + getHandle().getCipherSuite(), + AuthenticationType.RMCPPlus, + fruId)); int size = info.getFruInventoryAreaSize(); BaseUnit unit = info.getFruUnit(); @@ -217,8 +234,17 @@ private List getFruRecords(int fruId) throws Exception { } try { // get single package od FRU data - ReadFruDataResponseData data = (ReadFruDataResponseData) connector.sendMessage(handle, - new ReadFruData(IpmiVersion.V20, handle.getCipherSuite(), AuthenticationType.RMCPPlus, fruId, unit, i, fruReadPacketSize)); + ReadFruDataResponseData data = (ReadFruDataResponseData) getConnector() + .sendMessage( + getHandle(), + new ReadFruData( + IpmiVersion.V20, + getHandle().getCipherSuite(), + AuthenticationType.RMCPPlus, + fruId, + unit, + i, + fruReadPacketSize)); fruData.add(data); @@ -229,8 +255,13 @@ private List getFruRecords(int fruId) throws Exception { try { // after collecting all the data, we can combine and parse it - return ReadFruData.decodeFruData(fruData).stream() - .filter(fruRecord -> fruRecord instanceof BoardInfo || fruRecord instanceof ChassisInfo || fruRecord instanceof ProductInfo) + return ReadFruData + .decodeFruData(fruData) + .stream() + .filter( + fruRecord -> fruRecord instanceof BoardInfo + || fruRecord instanceof ChassisInfo + || fruRecord instanceof ProductInfo) .collect(Collectors.toList()); } catch (Exception e) { diff --git a/src/main/java/org/metricshub/ipmi/client/runner/GetSensorsRunner.java b/src/main/java/org/metricshub/ipmi/client/runner/GetSensorsRunner.java index 5a589bb..82d6dde 100644 --- a/src/main/java/org/metricshub/ipmi/client/runner/GetSensorsRunner.java +++ b/src/main/java/org/metricshub/ipmi/client/runner/GetSensorsRunner.java @@ -66,7 +66,7 @@ public List call() throws Exception { // Id 0 indicates first record in SDR. Next IDs can be retrieved from // records - they are organized in a list and there is no BMC command to // get all of them. - nextRecId = 0; + setNextRecId(0); // Some BMCs allow getting sensor records without reservation, so we try // to do it that way first @@ -75,7 +75,7 @@ public List call() throws Exception { // We get sensor data until we encounter ID = 65535 which means that // this record is the last one. - while (nextRecId < MAX_REPO_RECORD_ID) { + while (getNextRecId() < MAX_REPO_RECORD_ID) { SensorRecord sensorRecord = null; @@ -113,8 +113,11 @@ public List call() throws Exception { // happen many times during getting all sensors, since BMC can't // manage parallel sessions and invalidates old one if new one // appears. - reservationId = ((ReserveSdrRepositoryResponseData) connector.sendMessage(handle, - new ReserveSdrRepository(IpmiVersion.V20, handle.getCipherSuite(), AuthenticationType.RMCPPlus))).getReservationId(); + reservationId = ((ReserveSdrRepositoryResponseData) getConnector() + .sendMessage( + getHandle(), + new ReserveSdrRepository(IpmiVersion.V20, getHandle().getCipherSuite(), AuthenticationType.RMCPPlus))) + .getReservationId(); } } @@ -124,8 +127,8 @@ public List call() throws Exception { /** * Build the states representation formatted as the following deviceName=state1|deviceName=state2|... - * - * @param data The sensor reading data containing the sensor parameter value and the states + * + * @param data The sensor reading data containing the sensor parameter value and the states * @param sensorRecord The sensor record we wish to process {@link CompactSensorRecord} or {@link FullSensorRecord} * @return String value */ @@ -147,8 +150,10 @@ static String buildStates(final GetSensorReadingResponseData data, final SensorR return buildOemState(data.getRaw(), deviceName); } - events = data.getStatesAsserted(compactSensorRecord.getSensorType(), - compactSensorRecord.getEventReadingType()); + events = data + .getStatesAsserted( + compactSensorRecord.getSensorType(), + compactSensorRecord.getEventReadingType()); } else { FullSensorRecord fullSensorRecord = (FullSensorRecord) sensorRecord; @@ -159,8 +164,10 @@ static String buildStates(final GetSensorReadingResponseData data, final SensorR return buildOemState(data.getRaw(), deviceName); } - events = data.getStatesAsserted(fullSensorRecord.getSensorType(), - fullSensorRecord.getEventReadingType()); + events = data + .getStatesAsserted( + fullSensorRecord.getSensorType(), + fullSensorRecord.getEventReadingType()); } return appendReadingTypes(events, deviceName); @@ -172,7 +179,7 @@ static String buildStates(final GetSensorReadingResponseData data, final SensorR /** * Build the state for oem event reading type (0x7f) - * + * * @param raw a byte array of the raw IPMI command data * @param deviceName the name of the device * @return a string value of the state in a format of deviceName"=0x"+raw[3]+raw[2] @@ -187,9 +194,9 @@ static String buildOemState(final byte[] raw, final String deviceName) { /** * Append event reading type values - * + * * @param readingTypes The list of reading type events - * @param deviceName The name of the device + * @param deviceName The name of the device * @return String value formatted as deviceName=state1|deviceName=state2|...deviceName=stateN */ private static String appendReadingTypes(final List readingTypes, final String deviceName) { @@ -206,8 +213,8 @@ private static String appendReadingTypes(final List readingTypes, f /** * Create a state entry format as deviceName=readingTypeDescription - * - * @param deviceName The name of the device + * + * @param deviceName The name of the device * @param readingType The reading type event (asserted state) * @return String value or null if the reading type description is not found */ @@ -218,17 +225,24 @@ private static String createStateEntry(final String deviceName, final ReadingTyp /** * Using the given reading id run the GetSensorReading request to get reading data - * + * * @param recordReadingId the reading identifier of the sensor record * @return {@link GetSensorReadingResponseData} instance * @throws Exception at sendMessage or if the error completion code is not DataNotPresent */ private GetSensorReadingResponseData getSensorRecordReading(final int recordReadingId) throws Exception { try { - // If we have a reading id means the reading data (e.g. temperature) is potentially available so let's perform the re + // If we have a reading id means the reading data (e.g. temperature) is potentially available so let's perform the + // re if (recordReadingId >= 0) { - return (GetSensorReadingResponseData) connector.sendMessage(handle, - new GetSensorReading(IpmiVersion.V20, handle.getCipherSuite(), AuthenticationType.RMCPPlus, recordReadingId)); + return (GetSensorReadingResponseData) getConnector() + .sendMessage( + getHandle(), + new GetSensorReading( + IpmiVersion.V20, + getHandle().getCipherSuite(), + AuthenticationType.RMCPPlus, + recordReadingId)); } } catch (IPMIException e) { @@ -241,7 +255,7 @@ private GetSensorReadingResponseData getSensorRecordReading(final int recordRead /** * Get the reading id which is required by the BMC to answer reading commands. - * + * * @param sensorRecord {@link SensorRecord} instance expected as Full or Compact. * @return The sensor number of the record otherwise -1 if cannot determine the record type. */ diff --git a/src/main/java/org/metricshub/ipmi/core/api/async/ConnectionHandle.java b/src/main/java/org/metricshub/ipmi/core/api/async/ConnectionHandle.java index 6e058be..f3a5480 100644 --- a/src/main/java/org/metricshub/ipmi/core/api/async/ConnectionHandle.java +++ b/src/main/java/org/metricshub/ipmi/core/api/async/ConnectionHandle.java @@ -32,74 +32,74 @@ * Handle to the {@link Connection} */ public class ConnectionHandle { - private int handle; - private CipherSuite cipherSuite; - private PrivilegeLevel privilegeLevel; - private InetAddress remoteAddress; - private int remotePort; - private String user; - private String password; - - public ConnectionHandle(int handle, InetAddress remoteAddress, int remotePort) { - this.handle = handle; - this.remoteAddress = remoteAddress; - this.remotePort = remotePort; - } - - public CipherSuite getCipherSuite() { - return cipherSuite; - } - - public void setCipherSuite(CipherSuite cipherSuite) { - this.cipherSuite = cipherSuite; - } - - public PrivilegeLevel getPrivilegeLevel() { - return privilegeLevel; - } - - public void setPrivilegeLevel(PrivilegeLevel privilegeLevel) { - this.privilegeLevel = privilegeLevel; - } - - public int getHandle() { - return handle; - } - - public InetAddress getRemoteAddress() { - return remoteAddress; - } - - public int getRemotePort() { - return remotePort; - } - - public String getUser() { - return user; - } - - public void setUser(String user) { - this.user = user; - } - - public String getPassword() { - return password; - } - - public void setPassword(String password) { - this.password = password; - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder("ConnectionHandle{"); - sb.append("handle=").append(handle); - sb.append(", cipherSuite=").append(cipherSuite); - sb.append(", privilegeLevel=").append(privilegeLevel); - sb.append(", remoteAddress=").append(remoteAddress); - sb.append(", remotePort=").append(remotePort); - sb.append(", user='").append(user).append('\''); - sb.append('}'); - return sb.toString(); - } + private int handle; + private CipherSuite cipherSuite; + private PrivilegeLevel privilegeLevel; + private InetAddress remoteAddress; + private int remotePort; + private String user; + private String password; + + public ConnectionHandle(int handle, InetAddress remoteAddress, int remotePort) { + this.handle = handle; + this.remoteAddress = remoteAddress; + this.remotePort = remotePort; + } + + public CipherSuite getCipherSuite() { + return cipherSuite; + } + + public void setCipherSuite(CipherSuite cipherSuite) { + this.cipherSuite = cipherSuite; + } + + public PrivilegeLevel getPrivilegeLevel() { + return privilegeLevel; + } + + public void setPrivilegeLevel(PrivilegeLevel privilegeLevel) { + this.privilegeLevel = privilegeLevel; + } + + public int getHandle() { + return handle; + } + + public InetAddress getRemoteAddress() { + return remoteAddress; + } + + public int getRemotePort() { + return remotePort; + } + + public String getUser() { + return user; + } + + public void setUser(String user) { + this.user = user; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("ConnectionHandle{"); + sb.append("handle=").append(handle); + sb.append(", cipherSuite=").append(cipherSuite); + sb.append(", privilegeLevel=").append(privilegeLevel); + sb.append(", remoteAddress=").append(remoteAddress); + sb.append(", remotePort=").append(remotePort); + sb.append(", user='").append(user).append('\''); + sb.append('}'); + return sb.toString(); + } } diff --git a/src/main/java/org/metricshub/ipmi/core/api/async/InboundMessageListener.java b/src/main/java/org/metricshub/ipmi/core/api/async/InboundMessageListener.java index b91f6b6..2c7c7b0 100644 --- a/src/main/java/org/metricshub/ipmi/core/api/async/InboundMessageListener.java +++ b/src/main/java/org/metricshub/ipmi/core/api/async/InboundMessageListener.java @@ -29,23 +29,24 @@ */ public interface InboundMessageListener { - /** - * Checks if given payload is supported by this {@link InboundMessageListener} instance. - * This method should be called prior to invoking {@link InboundMessageListener#notify(IpmiPayload)}. - * - * @param payload - * {@link IpmiPayload} instance to check - * @return true if payload is supported by this object, false otherwise - */ - boolean isPayloadSupported(IpmiPayload payload); + /** + * Checks if given payload is supported by this {@link InboundMessageListener} instance. + * This method should be called prior to invoking {@link InboundMessageListener#notify(IpmiPayload)}. + * + * @param payload + * {@link IpmiPayload} instance to check + * @return true if payload is supported by this object, false otherwise + */ + boolean isPayloadSupported(IpmiPayload payload); - /** - * Notify listener about received inbound message. - * This method should be invoked only with payload for which {@link InboundMessageListener#isPayloadSupported(IpmiPayload)} returned true. - * - * @param payload - * payload extracted from inbound message - */ - void notify(IpmiPayload payload); + /** + * Notify listener about received inbound message. + * This method should be invoked only with payload for which + * {@link InboundMessageListener#isPayloadSupported(IpmiPayload)} returned true. + * + * @param payload + * payload extracted from inbound message + */ + void notify(IpmiPayload payload); } diff --git a/src/main/java/org/metricshub/ipmi/core/api/async/InboundSolMessageListener.java b/src/main/java/org/metricshub/ipmi/core/api/async/InboundSolMessageListener.java index 62bbe93..bff586b 100644 --- a/src/main/java/org/metricshub/ipmi/core/api/async/InboundSolMessageListener.java +++ b/src/main/java/org/metricshub/ipmi/core/api/async/InboundSolMessageListener.java @@ -42,144 +42,153 @@ */ public class InboundSolMessageListener implements InboundMessageListener { - private static final Logger logger = LoggerFactory.getLogger(InboundSolMessageListener.class); - - static final int BUFFER_CAPACITY = 2048; - - private final ByteBuffer buffer = new ByteBuffer(BUFFER_CAPACITY); - private final IpmiConnector connector; - private final ConnectionHandle connectionHandle; - private final List eventListeners; - - private SolInboundMessage waitingMessage; - - public InboundSolMessageListener(IpmiConnector connector, ConnectionHandle connectionHandle, - List eventListeners) { - this.connector = connector; - this.connectionHandle = connectionHandle; - this.eventListeners = eventListeners; - } - - @Override - public boolean isPayloadSupported(IpmiPayload payload) { - return payload instanceof SolInboundMessage; - } - - @Override - public void notify(IpmiPayload payload) { - if (isPayloadSupported(payload)) { - SolInboundMessage solPayload = (SolInboundMessage) payload; - - byte[] characterData = solPayload.getData(); - - if (messageHasCharacterData(characterData)) { - processCharacterData(solPayload, characterData); - } - - Set statuses = solPayload.getStatusField().getStatuses(); - - if (messageHasStatuses(statuses)) { - processStatuses(statuses); - } - } - } - - private void processCharacterData(SolInboundMessage solPayload, byte[] characterData) { - if (noSpaceForDataInBuffer(characterData)) { - sendNack(solPayload); - } else { - buffer.write(characterData); - - sendAck(solPayload, characterData); - } - } - - private void processStatuses(Set statuses) { - for (SolEventListener listener : eventListeners) { - listener.processRequestEvent(statuses); - } - } - - private boolean noSpaceForDataInBuffer(byte[] characterData) { - return characterData.length > buffer.remainingSpace(); - } - - private boolean messageHasCharacterData(byte[] characterData) { - return characterData != null && characterData.length > 0; - } - - private boolean messageHasStatuses(Set statuses) { - return statuses != null && !statuses.isEmpty(); - } - - private void sendNack(SolInboundMessage solPayload) { - if (solPayload.getSequenceNumber() != 0) { - try { - SolCoder solNack = new SolCoder(solPayload.getSequenceNumber(), (byte) 0, - SolAckState.NACK, connectionHandle.getCipherSuite()); - connector.sendOneWayMessage(connectionHandle, solNack); - - synchronized (buffer) { - waitingMessage = solPayload; - } - } catch (Exception e) { - logger.error("Could not send NACK for packet " + solPayload.getSequenceNumber(), e); - } - } - } - - private void sendAck(SolInboundMessage solPayload, byte[] characterData) { - if (solPayload.getSequenceNumber() != 0) { - try { - SolCoder solAck = new SolCoder(solPayload.getSequenceNumber(), (byte) characterData.length, - SolAckState.ACK, connectionHandle.getCipherSuite()); - connector.sendOneWayMessage(connectionHandle, solAck); - - synchronized (buffer) { - waitingMessage = null; - } - } catch (Exception e) { - logger.error("Could not send ACK for packet " + solPayload.getSequenceNumber(), e); - } - } - } - - private void sendResumeAck(SolInboundMessage solPayload) { - try { - SolCoder solResumeAck = new SolCoder(solPayload.getSequenceNumber(), (byte) 0, - SolAckState.ACK, connectionHandle.getCipherSuite()); - connector.sendOneWayMessage(connectionHandle, solResumeAck); - } catch (Exception e) { - logger.error("Could not send Resume ACK for packet " + solPayload.getSequenceNumber(), e); - } - } - - /** - * Attempts to read given number of bytes from this {@link ByteBuffer}. - * If buffer currently contains less bytes than requested, this method reads only available number of bytes. - * - * @param numberOfBytes - * requested number of bytes to read - * @return actual bytes that could be read from this buffer. - */ - public byte[] readBytes(int numberOfBytes) { - byte[] result = buffer.read(numberOfBytes); - - synchronized (buffer) { - if (waitingMessage != null && waitingMessage.getData().length <= buffer.remainingSpace()) { - sendResumeAck(waitingMessage); - } - } - - return result; - } - - /** - * Returns number of incoming bytes that are available to read from the buffer. - * - * @return number of available bytes to read - */ - public int getAvailableBytesCount() { - return buffer.size(); - } + private static final Logger LOGGER = LoggerFactory.getLogger(InboundSolMessageListener.class); + + static final int BUFFER_CAPACITY = 2048; + + private final ByteBuffer buffer = new ByteBuffer(BUFFER_CAPACITY); + private final IpmiConnector connector; + private final ConnectionHandle connectionHandle; + private final List eventListeners; + + private SolInboundMessage waitingMessage; + + public InboundSolMessageListener(IpmiConnector connector, ConnectionHandle connectionHandle, + List eventListeners) { + this.connector = connector; + this.connectionHandle = connectionHandle; + this.eventListeners = eventListeners; + } + + @Override + public boolean isPayloadSupported(IpmiPayload payload) { + return payload instanceof SolInboundMessage; + } + + @Override + public void notify(IpmiPayload payload) { + if (isPayloadSupported(payload)) { + SolInboundMessage solPayload = (SolInboundMessage) payload; + + byte[] characterData = solPayload.getData(); + + if (messageHasCharacterData(characterData)) { + processCharacterData(solPayload, characterData); + } + + Set statuses = solPayload.getStatusField().getStatuses(); + + if (messageHasStatuses(statuses)) { + processStatuses(statuses); + } + } + } + + private void processCharacterData(SolInboundMessage solPayload, byte[] characterData) { + if (noSpaceForDataInBuffer(characterData)) { + sendNack(solPayload); + } else { + buffer.write(characterData); + + sendAck(solPayload, characterData); + } + } + + private void processStatuses(Set statuses) { + for (SolEventListener listener : eventListeners) { + listener.processRequestEvent(statuses); + } + } + + private boolean noSpaceForDataInBuffer(byte[] characterData) { + return characterData.length > buffer.remainingSpace(); + } + + private boolean messageHasCharacterData(byte[] characterData) { + return characterData != null && characterData.length > 0; + } + + private boolean messageHasStatuses(Set statuses) { + return statuses != null && !statuses.isEmpty(); + } + + private void sendNack(SolInboundMessage solPayload) { + if (solPayload.getSequenceNumber() != 0) { + try { + SolCoder solNack = new SolCoder( + solPayload.getSequenceNumber(), + (byte) 0, + SolAckState.NACK, + connectionHandle.getCipherSuite()); + connector.sendOneWayMessage(connectionHandle, solNack); + + synchronized (buffer) { + waitingMessage = solPayload; + } + } catch (Exception e) { + LOGGER.error("Could not send NACK for packet " + solPayload.getSequenceNumber(), e); + } + } + } + + private void sendAck(SolInboundMessage solPayload, byte[] characterData) { + if (solPayload.getSequenceNumber() != 0) { + try { + SolCoder solAck = new SolCoder( + solPayload.getSequenceNumber(), + (byte) characterData.length, + SolAckState.ACK, + connectionHandle.getCipherSuite()); + connector.sendOneWayMessage(connectionHandle, solAck); + + synchronized (buffer) { + waitingMessage = null; + } + } catch (Exception e) { + LOGGER.error("Could not send ACK for packet " + solPayload.getSequenceNumber(), e); + } + } + } + + private void sendResumeAck(SolInboundMessage solPayload) { + try { + SolCoder solResumeAck = new SolCoder( + solPayload.getSequenceNumber(), + (byte) 0, + SolAckState.ACK, + connectionHandle.getCipherSuite()); + connector.sendOneWayMessage(connectionHandle, solResumeAck); + } catch (Exception e) { + LOGGER.error("Could not send Resume ACK for packet " + solPayload.getSequenceNumber(), e); + } + } + + /** + * Attempts to read given number of bytes from this {@link ByteBuffer}. + * If buffer currently contains less bytes than requested, this method reads only available number of bytes. + * + * @param numberOfBytes + * requested number of bytes to read + * @return actual bytes that could be read from this buffer. + */ + public byte[] readBytes(int numberOfBytes) { + byte[] result = buffer.read(numberOfBytes); + + synchronized (buffer) { + if (waitingMessage != null && waitingMessage.getData().length <= buffer.remainingSpace()) { + sendResumeAck(waitingMessage); + } + } + + return result; + } + + /** + * Returns number of incoming bytes that are available to read from the buffer. + * + * @return number of available bytes to read + */ + public int getAvailableBytesCount() { + return buffer.size(); + } } diff --git a/src/main/java/org/metricshub/ipmi/core/api/async/IpmiAsyncConnector.java b/src/main/java/org/metricshub/ipmi/core/api/async/IpmiAsyncConnector.java index 52e13e5..ebd78a2 100644 --- a/src/main/java/org/metricshub/ipmi/core/api/async/IpmiAsyncConnector.java +++ b/src/main/java/org/metricshub/ipmi/core/api/async/IpmiAsyncConnector.java @@ -81,66 +81,66 @@ *
*/ public class IpmiAsyncConnector implements ConnectionListener { - public static final String FAILED_TO_RECEIVE_ANSWER_CAUSE_MESSAGE = "Failed to receive answer, cause:"; - private ConnectionManager connectionManager; - private SessionManager sessionManager; - private int retries; - private final List responseListeners; - private final List inboundMessageListeners; - - private static Logger logger = LoggerFactory.getLogger(IpmiAsyncConnector.class); - - /** - * Starts {@link IpmiAsyncConnector} and initiates the - * {@link ConnectionManager} at the given port. The wildcard IP address will - * be used. - * - * @param port - * - the port that will be used by {@link IpmiAsyncConnector} to - * communicate with the remote hosts. - * @throws IOException - * when properties file was not found - */ - public IpmiAsyncConnector(int port) throws IOException { - responseListeners = new ArrayList(); - inboundMessageListeners = new ArrayList(); - connectionManager = new ConnectionManager(port); - sessionManager = new SessionManager(); - loadProperties(); - } - - /** - * Starts {@link IpmiAsyncConnector} and initiates the - * {@link ConnectionManager} at the given port and IP interface. - * - * @param port - * - the port that will be used by {@link IpmiAsyncConnector} to - * communicate with the remote hosts. - * @param address - * - the IP address that will be used by - * {@link IpmiAsyncConnector} to communicate with the remote - * hosts. - * @throws IOException - * when properties file was not found - */ - public IpmiAsyncConnector(int port, InetAddress address) throws IOException { - responseListeners = new ArrayList(); - inboundMessageListeners = new ArrayList(); - connectionManager = new ConnectionManager(port, address); - sessionManager = new SessionManager(); - loadProperties(); - } + public static final String FAILED_TO_RECEIVE_ANSWER_CAUSE_MESSAGE = "Failed to receive answer, cause:"; + private ConnectionManager connectionManager; + private SessionManager sessionManager; + private int retries; + private final List responseListeners; + private final List inboundMessageListeners; + + private static Logger logger = LoggerFactory.getLogger(IpmiAsyncConnector.class); + + /** + * Starts {@link IpmiAsyncConnector} and initiates the + * {@link ConnectionManager} at the given port. The wildcard IP address will + * be used. + * + * @param port + * - the port that will be used by {@link IpmiAsyncConnector} to + * communicate with the remote hosts. + * @throws IOException + * when properties file was not found + */ + public IpmiAsyncConnector(int port) throws IOException { + responseListeners = new ArrayList(); + inboundMessageListeners = new ArrayList(); + connectionManager = new ConnectionManager(port); + sessionManager = new SessionManager(); + loadProperties(); + } + + /** + * Starts {@link IpmiAsyncConnector} and initiates the + * {@link ConnectionManager} at the given port and IP interface. + * + * @param port + * - the port that will be used by {@link IpmiAsyncConnector} to + * communicate with the remote hosts. + * @param address + * - the IP address that will be used by + * {@link IpmiAsyncConnector} to communicate with the remote + * hosts. + * @throws IOException + * when properties file was not found + */ + public IpmiAsyncConnector(int port, InetAddress address) throws IOException { + responseListeners = new ArrayList(); + inboundMessageListeners = new ArrayList(); + connectionManager = new ConnectionManager(port, address); + sessionManager = new SessionManager(); + loadProperties(); + } /** * Starts {@link IpmiAsyncConnector} and initiates the {@link ConnectionManager} * at the given port and ping period. - * - * @param port the port that will be used by {@link IpmiAsyncConnector} to - * communicate with the remote hosts. + * + * @param port the port that will be used by {@link IpmiAsyncConnector} to + * communicate with the remote hosts. * @param pingPeriod the period between sending keep-alive messages to the - * remote host. + * remote host. * @throws IOException When ConnectionManager cannot be created due to an IO - * error. + * error. */ public IpmiAsyncConnector(int port, long pingPeriod) throws IOException { responseListeners = new ArrayList<>(); @@ -157,396 +157,433 @@ private void loadProperties() { retries = Integer.parseInt(PropertiesManager.getInstance().getProperty("retries")); } - /** - * Creates connection to the remote host. - * - * @param address - * - {@link InetAddress} of the remote host - * @return handle to the connection to the remote host - * @throws IOException - * when properties file was not found - * @throws FileNotFoundException - * when properties file was not found - */ - public ConnectionHandle createConnection(InetAddress address, int port) - throws IOException { - int handle = connectionManager.createConnection(address, port); - connectionManager.getConnection(handle).registerListener(this); - return new ConnectionHandle(handle, address, port); - } - - /** - * Creates connection to the remote host, with pre set {@link CipherSuite} and {@link PrivilegeLevel}, skipping the - * getAvailableCipherSuites and getChannelAuthenticationCapabilities phases. - * @param address - * - {@link InetAddress} of the remote host - * @return handle to the connection to the remote host - * @throws IOException - * when properties file was not found - * @throws FileNotFoundException - * when properties file was not found - */ - public ConnectionHandle createConnection(InetAddress address, int port, CipherSuite cipherSuite, PrivilegeLevel privilegeLevel) - throws IOException { - int handle = connectionManager.createConnection(address, port, true); - connectionManager.getConnection(handle).registerListener(this); - - ConnectionHandle connectionHandle = new ConnectionHandle(handle, address, port); - connectionHandle.setCipherSuite(cipherSuite); - connectionHandle.setPrivilegeLevel(privilegeLevel); - - return connectionHandle; - } - - /** - * Gets {@link CipherSuite}s available for the connection with the remote - * host. - * - * @param connectionHandle - * {@link ConnectionHandle} to the connection created before - * @see #createConnection(InetAddress, int) - * @return list of the {@link CipherSuite}s that are allowed during the - * connection - * @throws Exception - * when sending message to the managed system fails - */ - public List getAvailableCipherSuites( - ConnectionHandle connectionHandle) throws Exception { - int tries = 0; - List result = null; - while (tries <= retries && result == null) { - try { - ++tries; - result = connectionManager - .getAvailableCipherSuites(connectionHandle.getHandle()); - } catch (Exception e) { - logger.warn(FAILED_TO_RECEIVE_ANSWER_CAUSE_MESSAGE, e); - if (tries > retries) { - throw e; - } - } - } - return result; - } - - /** - * Gets the authentication capabilities for the connection with the remote - * host. - * - * @param connectionHandle - * - {@link ConnectionHandle} associated with the host - * @param cipherSuite - * - {@link CipherSuite} that will be used during the connection - * @param requestedPrivilegeLevel - * - {@link PrivilegeLevel} that is requested for the session - * @return - {@link GetChannelAuthenticationCapabilitiesResponseData} - * @throws ConnectionException - * when connection is in the state that does not allow to - * perform this operation. - * @throws Exception - * when sending message to the managed system fails - */ - public GetChannelAuthenticationCapabilitiesResponseData getChannelAuthenticationCapabilities( - ConnectionHandle connectionHandle, CipherSuite cipherSuite, - PrivilegeLevel requestedPrivilegeLevel) throws Exception { - int tries = 0; - GetChannelAuthenticationCapabilitiesResponseData result = null; - while (tries <= retries && result == null) { - try { - ++tries; - result = connectionManager - .getChannelAuthenticationCapabilities( - connectionHandle.getHandle(), cipherSuite, - requestedPrivilegeLevel); - connectionHandle.setCipherSuite(cipherSuite); - connectionHandle.setPrivilegeLevel(requestedPrivilegeLevel); - } catch (Exception e) { - logger.warn(FAILED_TO_RECEIVE_ANSWER_CAUSE_MESSAGE, e); - if (tries > retries) { - throw e; - } - } - } - return result; - } - - /** - * Establishes the session with the remote host. - * - * @param connectionHandle - * - {@link ConnectionHandle} associated with the remote host. - * @param username - * - the username - * @param password - * - password matching the username - * @param bmcKey - * - the key that should be provided if the two-key - * authentication is enabled, null otherwise. - * @throws ConnectionException - * when connection is in the state that does not allow to - * perform this operation. - * @throws Exception - * when sending message to the managed system or initializing - * one of the cipherSuite's algorithms fails - */ - public Session openSession(ConnectionHandle connectionHandle, String username, - String password, byte[] bmcKey) throws Exception { - Session session = null; - int tries = 0; - boolean succeded = false; - - connectionHandle.setUser(username); - connectionHandle.setPassword(password); - - while (tries <= retries && !succeded) { - try { - ++tries; - int sessionId = connectionManager.startSession(connectionHandle.getHandle(), - connectionHandle.getCipherSuite(), - connectionHandle.getPrivilegeLevel(), username, - password, bmcKey); - - session = sessionManager.registerSession(sessionId, connectionHandle); - - succeded = true; - } catch (Exception e) { - logger.warn(FAILED_TO_RECEIVE_ANSWER_CAUSE_MESSAGE, e); - if (tries > retries) { - throw e; - } - } - } - - return session; - } - - /** - * Returns session already bound to given connection handle fulfilling given criteria. - * - * @param remoteAddress - * IP addres of the managed system - * @param remotePort - * UDP port of the managed system - * @param user - * IPMI user for whom the connection is established - * @return session object fulfilling given criteria, or null if no session was registered for such connection. - */ - public Session getExistingSessionForCriteria(InetAddress remoteAddress, int remotePort, String user) { - return sessionManager.getSessionForCriteria(remoteAddress, remotePort, user); - } - - /** - * Closes the session with the remote host if it is currently in open state. - * - * @param connectionHandle - * - {@link ConnectionHandle} associated with the remote host. - * @throws ConnectionException - * when connection is in the state that does not allow to - * perform this operation. - * @throws Exception - * when sending message to the managed system or initializing - * one of the cipherSuite's algorithms fails - */ - public void closeSession(ConnectionHandle connectionHandle) - throws Exception { - if (!connectionManager.getConnection(connectionHandle.getHandle()) - .isSessionValid()) { - return; - } - int tries = 0; - boolean succeded = false; - while (tries <= retries && !succeded) { - try { - ++tries; - connectionManager.getConnection(connectionHandle.getHandle()) - .closeSession(); - sessionManager.unregisterSession(connectionHandle); - succeded = true; - } catch (Exception e) { - logger.warn(FAILED_TO_RECEIVE_ANSWER_CAUSE_MESSAGE, e); - if (tries > retries) { - throw e; - } - } - } - return; - } - - /** - * Sends the IPMI message to the remote host. - * - * @param connectionHandle - * - {@link ConnectionHandle} associated with the remote host. - * @param request - * - {@link PayloadCoder} containing the request to be sent - * @param isOneWay - * - tells whether this message is one way (needs response) or not. - * @return ID of the message that will be also attached to the response to - * pair request with response if queue was not full and message was - * sent, -1 if sending of the message failed. - * - * @throws ConnectionException - * when connection is in the state that does not allow to - * perform this operation. - * @throws Exception - * when sending message to the managed system or initializing - * one of the cipherSuite's algorithms fails - */ - public int sendMessage(ConnectionHandle connectionHandle, - PayloadCoder request, boolean isOneWay) throws Exception { - int tries = 0; - int tag = -1; - while (tries <= retries && tag < 0) { - try { - ++tries; - while (tag < 0) { - tag = connectionManager.getConnection( - connectionHandle.getHandle()).sendMessage( - request, isOneWay); - if (tag < 0) { - Thread.sleep(10); // tag < 0 means that MessageQueue is - // full so we need to wait and retry - } - } - logger.debug("Sending message with tag " + tag + ", try " - + tries); - } catch (IllegalArgumentException e) { - throw e; - } catch (Exception e) { - logger.warn("Failed to send message, cause:", e); - if (tries > retries) { - throw e; - } - } - } - return tag; - } - - /** - * Attempts to retry sending a message. - * - * @param connectionHandle - * - {@link ConnectionHandle} associated with the remote host. - * @param tag - * - tag of the message to retry - * @param messagePayloadType - * - {@link PayloadType} of the message that should be retried - * @return new tag if message was retried, -1 if operation failed - * @throws ConnectionException - * when connection isn't in state where sending commands is - * allowed - */ - public int retry(ConnectionHandle connectionHandle, int tag, PayloadType messagePayloadType) throws ConnectionException { - return connectionManager.getConnection(connectionHandle.getHandle()).retry(tag, messagePayloadType); - } - - /** - * Registers the listener so it will be notified of incoming messages. - * - * @param listener - * {@link IpmiResponseListener} to processResponse - */ - public void registerListener(IpmiResponseListener listener) { - synchronized (responseListeners) { - responseListeners.add(listener); - } - } - - /** - * Unregisters the listener so it will no longer receive notifications of - * received answers. - * - * @param listener - * - the {@link IpmiResponseListener} to unregister - */ - public void unregisterListener(IpmiResponseListener listener) { - synchronized (responseListeners) { - responseListeners.remove(listener); - } - } - - /** - * Registers the listener for incoming messages. - * - * @param listener - * the {@link InboundMessageListener} to register. - */ - public void registerIncomingPayloadListener(InboundMessageListener listener) { - synchronized (inboundMessageListeners) { - inboundMessageListeners.add(listener); - } - } - - /** - * Unregisters the listener so it will no longer receive notifications of received messages. - * - * @param listener - * the {@link InboundMessageListener} to unregister. - */ - public void unregisterIncomingPayloadListener(InboundMessageListener listener) { - synchronized (inboundMessageListeners) { - inboundMessageListeners.remove(listener); - } - } - - @Override - public void processResponse(ResponseData responseData, int handle, int tag, Exception exception) { - IpmiResponse response = null; - Connection connection = connectionManager.getConnection(handle); - - if (responseData == null || exception != null) { - Exception notNullException = exception != null ? exception : new Exception("Empty response"); - - response = new IpmiError(notNullException, tag, new ConnectionHandle( - handle, connection.getRemoteMachineAddress(), connection.getRemoteMachinePort())); - } else { - response = new IpmiResponseData(responseData, tag, - new ConnectionHandle(handle, connection.getRemoteMachineAddress(), connection.getRemoteMachinePort())); - - } - synchronized (responseListeners) { - for (IpmiResponseListener listener : responseListeners) { - if (listener != null) { - listener.notify(response); - } - } - } - } - - @Override - public void processRequest(IpmiPayload payload) { - for (InboundMessageListener listener : inboundMessageListeners) { - if (listener.isPayloadSupported(payload)) { - listener.notify(payload); - } - } - } - - /** - * Closes the connection with the given handle - */ - public void closeConnection(ConnectionHandle handle) { - connectionManager.getConnection(handle.getHandle()).unregisterListener( - this); - connectionManager.closeConnection(handle.getHandle()); - } - - /** - * Finalizes the connector and closes all connections. - */ - public void tearDown() { - connectionManager.close(); - } - - /** - * Changes the timeout value for connection with the given handle. - * @param handle - * - {@link ConnectionHandle} associated with the remote host. - * @param timeout - * - new timeout value in ms - */ - public void setTimeout(ConnectionHandle handle, int timeout) { - connectionManager.getConnection(handle.getHandle()).setTimeout(timeout); - } + /** + * Creates connection to the remote host. + * + * @param address + * - {@link InetAddress} of the remote host + * @return handle to the connection to the remote host + * @throws IOException + * when properties file was not found + * @throws FileNotFoundException + * when properties file was not found + */ + public ConnectionHandle createConnection(InetAddress address, int port) + throws IOException { + int handle = connectionManager.createConnection(address, port); + connectionManager.getConnection(handle).registerListener(this); + return new ConnectionHandle(handle, address, port); + } + + /** + * Creates connection to the remote host, with pre set {@link CipherSuite} and {@link PrivilegeLevel}, skipping the + * getAvailableCipherSuites and getChannelAuthenticationCapabilities phases. + * + * @param address + * - {@link InetAddress} of the remote host + * @return handle to the connection to the remote host + * @throws IOException + * when properties file was not found + * @throws FileNotFoundException + * when properties file was not found + */ + public ConnectionHandle createConnection( + InetAddress address, + int port, + CipherSuite cipherSuite, + PrivilegeLevel privilegeLevel) + throws IOException { + int handle = connectionManager.createConnection(address, port, true); + connectionManager.getConnection(handle).registerListener(this); + + ConnectionHandle connectionHandle = new ConnectionHandle(handle, address, port); + connectionHandle.setCipherSuite(cipherSuite); + connectionHandle.setPrivilegeLevel(privilegeLevel); + + return connectionHandle; + } + + /** + * Gets {@link CipherSuite}s available for the connection with the remote + * host. + * + * @param connectionHandle + * {@link ConnectionHandle} to the connection created before + * @see #createConnection(InetAddress, int) + * @return list of the {@link CipherSuite}s that are allowed during the + * connection + * @throws Exception + * when sending message to the managed system fails + */ + public List getAvailableCipherSuites( + ConnectionHandle connectionHandle) + throws Exception { + int tries = 0; + List result = null; + while (tries <= retries && result == null) { + try { + ++tries; + result = connectionManager + .getAvailableCipherSuites(connectionHandle.getHandle()); + } catch (Exception e) { + logger.warn(FAILED_TO_RECEIVE_ANSWER_CAUSE_MESSAGE, e); + if (tries > retries) { + throw e; + } + } + } + return result; + } + + /** + * Gets the authentication capabilities for the connection with the remote + * host. + * + * @param connectionHandle + * - {@link ConnectionHandle} associated with the host + * @param cipherSuite + * - {@link CipherSuite} that will be used during the connection + * @param requestedPrivilegeLevel + * - {@link PrivilegeLevel} that is requested for the session + * @return - {@link GetChannelAuthenticationCapabilitiesResponseData} + * @throws ConnectionException + * when connection is in the state that does not allow to + * perform this operation. + * @throws Exception + * when sending message to the managed system fails + */ + public GetChannelAuthenticationCapabilitiesResponseData getChannelAuthenticationCapabilities( + ConnectionHandle connectionHandle, + CipherSuite cipherSuite, + PrivilegeLevel requestedPrivilegeLevel) + throws Exception { + int tries = 0; + GetChannelAuthenticationCapabilitiesResponseData result = null; + while (tries <= retries && result == null) { + try { + ++tries; + result = connectionManager + .getChannelAuthenticationCapabilities( + connectionHandle.getHandle(), + cipherSuite, + requestedPrivilegeLevel); + connectionHandle.setCipherSuite(cipherSuite); + connectionHandle.setPrivilegeLevel(requestedPrivilegeLevel); + } catch (Exception e) { + logger.warn(FAILED_TO_RECEIVE_ANSWER_CAUSE_MESSAGE, e); + if (tries > retries) { + throw e; + } + } + } + return result; + } + + /** + * Establishes the session with the remote host. + * + * @param connectionHandle + * - {@link ConnectionHandle} associated with the remote host. + * @param username + * - the username + * @param password + * - password matching the username + * @param bmcKey + * - the key that should be provided if the two-key + * authentication is enabled, null otherwise. + * @throws ConnectionException + * when connection is in the state that does not allow to + * perform this operation. + * @throws Exception + * when sending message to the managed system or initializing + * one of the cipherSuite's algorithms fails + */ + public Session openSession( + ConnectionHandle connectionHandle, + String username, + String password, + byte[] bmcKey) + throws Exception { + Session session = null; + int tries = 0; + boolean succeded = false; + + connectionHandle.setUser(username); + connectionHandle.setPassword(password); + + while (tries <= retries && !succeded) { + try { + ++tries; + int sessionId = connectionManager + .startSession( + connectionHandle.getHandle(), + connectionHandle.getCipherSuite(), + connectionHandle.getPrivilegeLevel(), + username, + password, + bmcKey); + + session = sessionManager.registerSession(sessionId, connectionHandle); + + succeded = true; + } catch (Exception e) { + logger.warn(FAILED_TO_RECEIVE_ANSWER_CAUSE_MESSAGE, e); + if (tries > retries) { + throw e; + } + } + } + + return session; + } + + /** + * Returns session already bound to given connection handle fulfilling given criteria. + * + * @param remoteAddress + * IP addres of the managed system + * @param remotePort + * UDP port of the managed system + * @param user + * IPMI user for whom the connection is established + * @return session object fulfilling given criteria, or null if no session was registered for such connection. + */ + public Session getExistingSessionForCriteria(InetAddress remoteAddress, int remotePort, String user) { + return sessionManager.getSessionForCriteria(remoteAddress, remotePort, user); + } + + /** + * Closes the session with the remote host if it is currently in open state. + * + * @param connectionHandle + * - {@link ConnectionHandle} associated with the remote host. + * @throws ConnectionException + * when connection is in the state that does not allow to + * perform this operation. + * @throws Exception + * when sending message to the managed system or initializing + * one of the cipherSuite's algorithms fails + */ + public void closeSession(ConnectionHandle connectionHandle) + throws Exception { + if (!connectionManager + .getConnection(connectionHandle.getHandle()) + .isSessionValid()) { + return; + } + int tries = 0; + boolean succeded = false; + while (tries <= retries && !succeded) { + try { + ++tries; + connectionManager + .getConnection(connectionHandle.getHandle()) + .closeSession(); + sessionManager.unregisterSession(connectionHandle); + succeded = true; + } catch (Exception e) { + logger.warn(FAILED_TO_RECEIVE_ANSWER_CAUSE_MESSAGE, e); + if (tries > retries) { + throw e; + } + } + } + return; + } + + /** + * Sends the IPMI message to the remote host. + * + * @param connectionHandle + * - {@link ConnectionHandle} associated with the remote host. + * @param request + * - {@link PayloadCoder} containing the request to be sent + * @param isOneWay + * - tells whether this message is one way (needs response) or not. + * @return ID of the message that will be also attached to the response to + * pair request with response if queue was not full and message was + * sent, -1 if sending of the message failed. + * @throws ConnectionException + * when connection is in the state that does not allow to + * perform this operation. + * @throws Exception + * when sending message to the managed system or initializing + * one of the cipherSuite's algorithms fails + */ + public int sendMessage( + ConnectionHandle connectionHandle, + PayloadCoder request, + boolean isOneWay) + throws Exception { + int tries = 0; + int tag = -1; + while (tries <= retries && tag < 0) { + try { + ++tries; + while (tag < 0) { + tag = connectionManager + .getConnection( + connectionHandle.getHandle()) + .sendMessage( + request, + isOneWay); + if (tag < 0) { + Thread.sleep(10); // tag < 0 means that MessageQueue is + // full so we need to wait and retry + } + } + logger + .debug( + "Sending message with tag " + tag + ", try " + + tries); + } catch (IllegalArgumentException e) { + throw e; + } catch (Exception e) { + logger.warn("Failed to send message, cause:", e); + if (tries > retries) { + throw e; + } + } + } + return tag; + } + + /** + * Attempts to retry sending a message. + * + * @param connectionHandle + * - {@link ConnectionHandle} associated with the remote host. + * @param tag + * - tag of the message to retry + * @param messagePayloadType + * - {@link PayloadType} of the message that should be retried + * @return new tag if message was retried, -1 if operation failed + * @throws ConnectionException + * when connection isn't in state where sending commands is + * allowed + */ + public int retry(ConnectionHandle connectionHandle, int tag, PayloadType messagePayloadType) + throws ConnectionException { + return connectionManager.getConnection(connectionHandle.getHandle()).retry(tag, messagePayloadType); + } + + /** + * Registers the listener so it will be notified of incoming messages. + * + * @param listener + * {@link IpmiResponseListener} to processResponse + */ + public void registerListener(IpmiResponseListener listener) { + synchronized (responseListeners) { + responseListeners.add(listener); + } + } + + /** + * Unregisters the listener so it will no longer receive notifications of + * received answers. + * + * @param listener + * - the {@link IpmiResponseListener} to unregister + */ + public void unregisterListener(IpmiResponseListener listener) { + synchronized (responseListeners) { + responseListeners.remove(listener); + } + } + + /** + * Registers the listener for incoming messages. + * + * @param listener + * the {@link InboundMessageListener} to register. + */ + public void registerIncomingPayloadListener(InboundMessageListener listener) { + synchronized (inboundMessageListeners) { + inboundMessageListeners.add(listener); + } + } + + /** + * Unregisters the listener so it will no longer receive notifications of received messages. + * + * @param listener + * the {@link InboundMessageListener} to unregister. + */ + public void unregisterIncomingPayloadListener(InboundMessageListener listener) { + synchronized (inboundMessageListeners) { + inboundMessageListeners.remove(listener); + } + } + + @Override + public void processResponse(ResponseData responseData, int handle, int tag, Exception exception) { + IpmiResponse response = null; + Connection connection = connectionManager.getConnection(handle); + + if (responseData == null || exception != null) { + Exception notNullException = exception != null ? exception : new Exception("Empty response"); + + response = new IpmiError( + notNullException, + tag, + new ConnectionHandle( + handle, + connection.getRemoteMachineAddress(), + connection.getRemoteMachinePort())); + } else { + response = new IpmiResponseData( + responseData, + tag, + new ConnectionHandle(handle, connection.getRemoteMachineAddress(), connection.getRemoteMachinePort())); + + } + synchronized (responseListeners) { + for (IpmiResponseListener listener : responseListeners) { + if (listener != null) { + listener.notify(response); + } + } + } + } + + @Override + public void processRequest(IpmiPayload payload) { + for (InboundMessageListener listener : inboundMessageListeners) { + if (listener.isPayloadSupported(payload)) { + listener.notify(payload); + } + } + } + + /** + * Closes the connection with the given handle + */ + public void closeConnection(ConnectionHandle handle) { + connectionManager + .getConnection(handle.getHandle()) + .unregisterListener( + this); + connectionManager.closeConnection(handle.getHandle()); + } + + /** + * Finalizes the connector and closes all connections. + */ + public void tearDown() { + connectionManager.close(); + } + + /** + * Changes the timeout value for connection with the given handle. + * + * @param handle + * - {@link ConnectionHandle} associated with the remote host. + * @param timeout + * - new timeout value in ms + */ + public void setTimeout(ConnectionHandle handle, int timeout) { + connectionManager.getConnection(handle.getHandle()).setTimeout(timeout); + } } diff --git a/src/main/java/org/metricshub/ipmi/core/api/async/IpmiResponseListener.java b/src/main/java/org/metricshub/ipmi/core/api/async/IpmiResponseListener.java index c1c5361..42af29a 100644 --- a/src/main/java/org/metricshub/ipmi/core/api/async/IpmiResponseListener.java +++ b/src/main/java/org/metricshub/ipmi/core/api/async/IpmiResponseListener.java @@ -31,13 +31,15 @@ */ public interface IpmiResponseListener { - /** - * Notifies listener of action that occurred. - * - * @param response - *
  • - {@link IpmiResponse} being notified
  • - *
  • - {@link IpmiResponseData} if answer for request arrived,
  • - *
  • - {@link IpmiError} if delivery failed.
- */ - void notify(IpmiResponse response); + /** + * Notifies listener of action that occurred. + * + * @param response + *
    + *
  • - {@link IpmiResponse} being notified
  • + *
  • - {@link IpmiResponseData} if answer for request arrived,
  • + *
  • - {@link IpmiError} if delivery failed.
  • + *
+ */ + void notify(IpmiResponse response); } diff --git a/src/main/java/org/metricshub/ipmi/core/api/async/messages/IpmiError.java b/src/main/java/org/metricshub/ipmi/core/api/async/messages/IpmiError.java index 44ba91d..10641e1 100644 --- a/src/main/java/org/metricshub/ipmi/core/api/async/messages/IpmiError.java +++ b/src/main/java/org/metricshub/ipmi/core/api/async/messages/IpmiError.java @@ -28,17 +28,17 @@ * Class that wraps exception that was cause of not receiving message. */ public class IpmiError extends IpmiResponse { - private Exception exception; + private Exception exception; - /** - * @return {@link Exception} that caused message delivery to fail. - */ - public Exception getException() { - return exception; - } + /** + * @return {@link Exception} that caused message delivery to fail. + */ + public Exception getException() { + return exception; + } - public IpmiError(Exception exception, int tag, ConnectionHandle handle) { - super(tag, handle); - this.exception = exception; - } + public IpmiError(Exception exception, int tag, ConnectionHandle handle) { + super(tag, handle); + this.exception = exception; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/api/async/messages/IpmiResponse.java b/src/main/java/org/metricshub/ipmi/core/api/async/messages/IpmiResponse.java index 6d30e58..b284bb3 100644 --- a/src/main/java/org/metricshub/ipmi/core/api/async/messages/IpmiResponse.java +++ b/src/main/java/org/metricshub/ipmi/core/api/async/messages/IpmiResponse.java @@ -31,27 +31,27 @@ * Interface for response messages delivered to {@link IpmiResponseListener}s */ public abstract class IpmiResponse { - private int tag; - private ConnectionHandle handle; + private int tag; + private ConnectionHandle handle; - /** - * {@link ConnectionHandle} to the message that was an origin of the - * response Handle contains only the id of the connection, not the - * {@link CipherSuite} and {@link PrivilegeLevel} used in that connection. - */ - public ConnectionHandle getHandle() { - return handle; - } + /** + * {@link ConnectionHandle} to the message that was an origin of the + * response Handle contains only the id of the connection, not the + * {@link CipherSuite} and {@link PrivilegeLevel} used in that connection. + */ + public ConnectionHandle getHandle() { + return handle; + } - /** - * Tag of the message that is associated with the {@link IpmiResponse} - */ - public int getTag() { - return tag; - } + /** + * Tag of the message that is associated with the {@link IpmiResponse} + */ + public int getTag() { + return tag; + } - public IpmiResponse(int tag, ConnectionHandle handle) { - this.tag = tag; - this.handle = handle; - } + public IpmiResponse(int tag, ConnectionHandle handle) { + this.tag = tag; + this.handle = handle; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/api/async/messages/IpmiResponseData.java b/src/main/java/org/metricshub/ipmi/core/api/async/messages/IpmiResponseData.java index 050f297..7948f99 100644 --- a/src/main/java/org/metricshub/ipmi/core/api/async/messages/IpmiResponseData.java +++ b/src/main/java/org/metricshub/ipmi/core/api/async/messages/IpmiResponseData.java @@ -29,17 +29,17 @@ * Class that wraps {@link ResponseData} that was received successfully. */ public class IpmiResponseData extends IpmiResponse { - private ResponseData responseData; + private ResponseData responseData; - /** - * @return {@link ResponseData} received successfully. - */ - public ResponseData getResponseData() { - return responseData; - } + /** + * @return {@link ResponseData} received successfully. + */ + public ResponseData getResponseData() { + return responseData; + } - public IpmiResponseData(ResponseData data, int tag, ConnectionHandle handle) { - super(tag, handle); - responseData = data; - } + public IpmiResponseData(ResponseData data, int tag, ConnectionHandle handle) { + super(tag, handle); + responseData = data; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/api/async/messages/package-info.java b/src/main/java/org/metricshub/ipmi/core/api/async/messages/package-info.java index 7687c63..09e3af4 100644 --- a/src/main/java/org/metricshub/ipmi/core/api/async/messages/package-info.java +++ b/src/main/java/org/metricshub/ipmi/core/api/async/messages/package-info.java @@ -1,5 +1,5 @@ /** - * The package containing asynchronous API message classes. + * The package containing asynchronous API message classes. */ package org.metricshub.ipmi.core.api.async.messages; /*- diff --git a/src/main/java/org/metricshub/ipmi/core/api/async/package-info.java b/src/main/java/org/metricshub/ipmi/core/api/async/package-info.java index 44d32d3..f745cd0 100644 --- a/src/main/java/org/metricshub/ipmi/core/api/async/package-info.java +++ b/src/main/java/org/metricshub/ipmi/core/api/async/package-info.java @@ -1,6 +1,6 @@ /** * The asynchronous API. - * + * * @see org.metricshub.ipmi.core.api.async.IpmiAsyncConnector */ package org.metricshub.ipmi.core.api.async; diff --git a/src/main/java/org/metricshub/ipmi/core/api/sol/CipherSuiteSelectionHandler.java b/src/main/java/org/metricshub/ipmi/core/api/sol/CipherSuiteSelectionHandler.java index 616f6e5..0ad23e6 100644 --- a/src/main/java/org/metricshub/ipmi/core/api/sol/CipherSuiteSelectionHandler.java +++ b/src/main/java/org/metricshub/ipmi/core/api/sol/CipherSuiteSelectionHandler.java @@ -27,17 +27,18 @@ import java.util.List; /** - * Interface for {@link CipherSuite} selection handler to choose among available {@link CipherSuite}s returned by the server. + * Interface for {@link CipherSuite} selection handler to choose among available {@link CipherSuite}s returned by the + * server. */ public interface CipherSuiteSelectionHandler { - /** - * Chooses one {@link CipherSuite} among list of available {@link CipherSuite}s, to be used during IPMI connection. - * - * @param availableCipherSuites - * {@link CipherSuite}s returned by the server as avaialble to use. - * @return chosen cipher suite - */ - CipherSuite choose(List availableCipherSuites); + /** + * Chooses one {@link CipherSuite} among list of available {@link CipherSuite}s, to be used during IPMI connection. + * + * @param availableCipherSuites + * {@link CipherSuite}s returned by the server as avaialble to use. + * @return chosen cipher suite + */ + CipherSuite choose(List availableCipherSuites); } diff --git a/src/main/java/org/metricshub/ipmi/core/api/sol/SOLException.java b/src/main/java/org/metricshub/ipmi/core/api/sol/SOLException.java index 0171461..0cd98a9 100644 --- a/src/main/java/org/metricshub/ipmi/core/api/sol/SOLException.java +++ b/src/main/java/org/metricshub/ipmi/core/api/sol/SOLException.java @@ -30,10 +30,10 @@ public class SOLException extends Exception { private static final long serialVersionUID = 1L; public SOLException(String message) { - super(message); - } + super(message); + } - public SOLException(String message, Throwable cause) { - super(message, cause); - } + public SOLException(String message, Throwable cause) { + super(message, cause); + } } diff --git a/src/main/java/org/metricshub/ipmi/core/api/sol/SerialOverLan.java b/src/main/java/org/metricshub/ipmi/core/api/sol/SerialOverLan.java index a183fb7..cce09f3 100644 --- a/src/main/java/org/metricshub/ipmi/core/api/sol/SerialOverLan.java +++ b/src/main/java/org/metricshub/ipmi/core/api/sol/SerialOverLan.java @@ -67,651 +67,709 @@ */ public class SerialOverLan implements Closeable { - private static final Logger logger = LoggerFactory.getLogger(SerialOverLan.class); - - private final IpmiConnector connector; - private final Session session; - private final InboundSolMessageListener inboundMessageListener; - private final List eventListeners; - - private boolean isSessionInternal; - private int payloadInstance; - private int maxPayloadSize; - private boolean closed; - - /** - * Creates connection with IPMI using given {@link IpmiConnector}, connected to remote machine on given address and port, - * and opens a new {@link Session} for SOL communication. - * This constructor should be used only when you have no other connection opened on this port. - * - * @param connector - * {@link IpmiConnector} that will be used for communication - * @param remoteHost - * IP address of the remote server - * @param remotePort - * UDP port number of the remote server - * @param user - * IPMI user name - * @param password - * IPMI password - * @param cipherSuiteSelectionHandler - * {@link CipherSuiteSelectionHandler} that will allow to select {@link CipherSuite} among available ones. - * - * @throws SOLException when any problem occur during establishing session or activating SOL payload. - */ - public SerialOverLan(IpmiConnector connector, String remoteHost, int remotePort, String user, String password, - CipherSuiteSelectionHandler cipherSuiteSelectionHandler) throws SOLException, SessionException { - this(connector, SessionManager.establishSession(connector, remoteHost, remotePort, user, password, cipherSuiteSelectionHandler)); - - this.isSessionInternal = true; - } - - /** - * Creates connection with IPMI using given {@link IpmiConnector}, connected to remote machine on given address and default IPMI port, - * and opens a new {@link Session} for SOL communication. - * This constructor should be used only when you have no other connection opened on this port. - * - * @param connector - * {@link IpmiConnector} that will be used for communication - * @param remoteHost - * IP address of the remote server - * @param user - * IPMI user name - * @param password - * IPMI password - * @param cipherSuiteSelectionHandler - * {@link CipherSuiteSelectionHandler} that will allow to select {@link CipherSuite} among available ones. - * - * @throws SOLException when any problem occur during establishing session or activating SOL payload. - */ - public SerialOverLan(IpmiConnector connector, String remoteHost, String user, String password, - CipherSuiteSelectionHandler cipherSuiteSelectionHandler) throws SOLException, SessionException { - this(connector, remoteHost, Constants.IPMI_PORT, user, password, cipherSuiteSelectionHandler); - } - - /** - * Tries to open SOL communication on given existing session. When it appears that separate session must be opened - * to handle SOL messages (for example SOL payload must be activated on separate port), the new connection and session - * are automatically established. - * - * @param connector - * {@link IpmiConnector} that will be used for communication - * @param session - * Existing session that should be reused (if possible) for SOL communication. - */ - public SerialOverLan(IpmiConnector connector, Session session) throws SOLException, SessionException { - this.connector = connector; - - int solPayloadPort = activatePayload(connector, session.getConnectionHandle()); - - this.session = resolveSession(connector, session.getConnectionHandle(), session, solPayloadPort); - - this.eventListeners = new LinkedList(); - this.inboundMessageListener = new InboundSolMessageListener(connector, - this.session.getConnectionHandle(), eventListeners); - - connector.registerIncomingMessageListener(inboundMessageListener); - this.closed = false; - } - - /** - * Given potential session object, connection data and port on which SOL should be activated, - * decides what session should be finally used to SOL communication. - * - * @param connector - * {@link IpmiConnector} that will be used for communication - * @param connectionHandle - * {@link ConnectionHandle} representing single connection to managed system. - * @param session - * Existing session that should be reused (if possible) for SOL communication. - * @param solPayloadPort - * UDP port on which managed system listens for SOL communication. - * @return Actual session (existing or newly established), that should be used for SOL communication. - * @throws SOLException - * If any unrecoverable error occurs. - * @throws SessionException - * If new session could not be established. - */ - private Session resolveSession(IpmiConnector connector, ConnectionHandle connectionHandle, Session session, int solPayloadPort) throws SOLException, SessionException { - if (solPayloadPort != connectionHandle.getRemotePort()) { - Session alternativeSession = connector.getExistingSessionForCriteria(connectionHandle.getRemoteAddress(), - solPayloadPort, connectionHandle.getUser()); - - if (alternativeSession == null) { - CipherSuiteSelectionHandler cipherSuiteSelector = new SpecificCipherSuiteSelector(connectionHandle.getCipherSuite()); - - alternativeSession = SessionManager.establishSession(connector, connectionHandle.getRemoteAddress().getHostAddress(), - solPayloadPort, connectionHandle.getUser(), connectionHandle.getPassword(), cipherSuiteSelector); - this.isSessionInternal = true; - - } else { - this.isSessionInternal = false; - } - - activatePayload(connector, alternativeSession.getConnectionHandle()); - - return alternativeSession; - } else { - this.isSessionInternal = false; - return session; - } - } - - /** - * Tries to activate SOL payload in the session associated to given {@link ConnectionHandle}. - * If first activation try fails due to insufficient privileges, raises the session privileges - * to maximum available and tries to activate payload once again. - * - * @param connector - * {@link IpmiConnector} that will be used for communication - * @param connectionHandle - * {@link ConnectionHandle} representing single connection to managed system. - * @return UDP port number on which managed system listenes for SOL messages. - * @throws SOLException - * when any unrecoverable error occurred. - */ - private int activatePayload(IpmiConnector connector, ConnectionHandle connectionHandle) throws SOLException { - try { - this.payloadInstance = getFirstAvailablePayloadInstance(connector, connectionHandle); - - ActivateSolPayload activatePayload = new ActivateSolPayload(connectionHandle.getCipherSuite(), payloadInstance); - ActivateSolPayloadResponseData activatePayloadResponseData = getActivatePayloadResponse(connector, - connectionHandle, activatePayload); - - this.maxPayloadSize = activatePayloadResponseData.getInboundPayloadSize(); - - return activatePayloadResponseData.getPayloadUdpPortNumber(); - - } catch (Exception e) { - throw new SOLException("Cannot activate SOL payload due to exception during activation process", e); - } - } - - private ActivateSolPayloadResponseData getActivatePayloadResponse(IpmiConnector connector, ConnectionHandle connectionHandle, ActivateSolPayload activatePayload) throws Exception { - ActivateSolPayloadResponseData activatePayloadResponseData; - - try { - activatePayloadResponseData = (ActivateSolPayloadResponseData) connector.sendMessage(connectionHandle, - activatePayload); - } catch (IPMIException e) { - if (e.getCompletionCode() == CompletionCode.InsufficentPrivilege) { - raiseSessionPrivileges(connector, connectionHandle); - - activatePayloadResponseData = (ActivateSolPayloadResponseData) connector.sendMessage( - connectionHandle, activatePayload); - } else { - throw e; - } - } - - return activatePayloadResponseData; - } - - /** - * Checks for available SOL payload instances and, if any, returns first available. - * - * @param connector - * {@link IpmiConnector} that will be used for communication - * @param connectionHandle - * {@link ConnectionHandle} representing single connection to managed system. - * @return number of first available SOL payload instance. - * @throws Exception - * If any exception occurred during communication or if no available instances were found. - */ - private int getFirstAvailablePayloadInstance(IpmiConnector connector, ConnectionHandle connectionHandle) throws Exception { - GetPayloadActivationStatus getPayloadActivationStatus = new GetPayloadActivationStatus(connectionHandle.getCipherSuite(), - PayloadType.Sol); - GetPayloadActivationStatusResponseData getActivationResponseData = (GetPayloadActivationStatusResponseData) connector.sendMessage( - connectionHandle, getPayloadActivationStatus); - - if (getActivationResponseData.getInstanceCapacity() <= 0 || getActivationResponseData.getAvailableInstances().isEmpty()) { - throw new SOLException("Cannot activate SOL payload, as there are no available payload instances."); - } - - return TypeConverter.byteToInt(getActivationResponseData.getAvailableInstances().get(0)); - } - - /** - * Sends proper command to managed system in order to raise user privileges in given session to maximum available level. - * - * @param connector - * {@link IpmiConnector} that will be used for communication - * @param connectionHandle - * {@link ConnectionHandle} representing single connection to managed system. - * @throws Exception - * If any exception occurred during communication. - */ - private void raiseSessionPrivileges(IpmiConnector connector, ConnectionHandle connectionHandle) throws Exception { - SetSessionPrivilegeLevel setSessionPrivilegeLevel = new SetSessionPrivilegeLevel(IpmiVersion.V20, - connectionHandle.getCipherSuite(), AuthenticationType.RMCPPlus, PrivilegeLevel.Administrator); - connector.sendMessage(connectionHandle, setSessionPrivilegeLevel); - } - - - /** - * Writes single byte to the port. - * This operation blocks until all data can be sent to remote server and is either accepted or rejected by the server. - * - * @param singleByte - * a byte to write - * @return true if byte was successfully sent and acknowledged by remote server, false otherwise. - */ - public boolean writeByte(byte singleByte) { - return writeBytes(new byte[] {singleByte}); - } - - /** - * Writes bytes array to the port. - * This operation blocks until all data can be sent to remote server and is either accepted or rejected by the server. - * - * @param buffer - * an array of bytes to write - * @return true if all bytes were successfully sent and acknowledged by remote server, false otherwise. - */ - public boolean writeBytes(byte[] buffer) { - boolean result = true; - - int maxBufferSize = maxPayloadSize - SolMessage.PAYLOAD_HEADER_LENGTH; - byte[] remainingBytes = buffer; - int currentIndex = 0; - - while (remainingBytes.length - currentIndex > maxBufferSize) { - byte[] bufferChunk = Arrays.copyOfRange(remainingBytes, currentIndex, maxBufferSize); - currentIndex += maxBufferSize; - - result &= sendMessage(bufferChunk); - - if (!result) { - return false; - } - } - - if (remainingBytes.length - currentIndex > 0) { - remainingBytes = Arrays.copyOfRange(remainingBytes, currentIndex, remainingBytes.length); - result &= sendMessage(remainingBytes); - } - - return result; - } - - /** - * Writes single integer (in range from 0 to 255) to the port. - * This operation blocks until all data can be sent to remote server and is either accepted or rejected by the server. - * - * @param singleInt - * an integer value to write (must be in range from 0 to 255) - * @return true if integer was successfully sent and acknowledged by remote server, false otherwise. - */ - public boolean writeInt(int singleInt) { - return writeBytes(new byte[] {TypeConverter.intToByte(singleInt)}); - } - - /** - * Writes integers (in range from 0 to 255) array to the port. - * This operation blocks until all data can be sent to remote server and is either accepted or rejected by the server. - * - * @param buffer - * an array of integer values to write (each must be in range from 0 to 255) - * @return true if all integers were successfully sent and acknowledged by remote server, false otherwise. - */ - public boolean writeIntArray(int[] buffer) { - byte[] byteBuffer = new byte[buffer.length]; - - for (int i = 0; i < buffer.length; i++) { - byteBuffer[i] = TypeConverter.intToByte(buffer[i]); - } - - return writeBytes(byteBuffer); - } - - /** - * Writes {@link String} to port, using platform's default {@link Charset} when converting {@link String} to byte array. - * This operation blocks until all data can be sent to remote server and is either accepted or rejected by the server. - * - * @param string - * a string to write to the port. - * @return true if whole string was successfully sent and acknowledged by remote server, false otherwise. - */ - public boolean writeString(String string) { - return writeBytes(string.getBytes()); - } - - /** - * Writes {@link String} to port, using given {@link Charset} when converting {@link String} to byte array. - * This operation blocks until all data can be sent to remote server and is either accepted or rejected by the server. - * - * @param string - * a string to write to port - * @param charset - * {@link Charset} that the string is encoded in - * @return true if whole string was successfully sent and acknowledged by remote server, false otherwise. - */ - public boolean writeString(String string, Charset charset) { - return writeBytes(string.getBytes(charset)); - } - - /** - * Read all available bytes from the port. - * Returns immediately, without waiting for data to be available. - * - * @return all bytes that could be read or empty array if no bytes were available. - */ - public byte[] readBytes() { - return readBytes(inboundMessageListener.getAvailableBytesCount()); - } - - /** - * Reads at max given number of bytes from the port. - * Returns immediately, without waiting for data to be available. - * - * @param byteCount - * maximum number of bytes that should be read - * @return byte array containing bytes that could be read, but no more than given byteCount. - * Returns empty array if no bytes were available. - */ - public byte[] readBytes(int byteCount) { - return inboundMessageListener.readBytes(byteCount); - } - - /** - * Reads at max given number of bytes from the port. - * This operation blocks until given number of bytes is available to be read or until given timeout is hit. - * - * @param byteCount - * maximum number of bytes that should be read. - * @param timeout - * maximum time in milliseconds that we want to wait for all available bytes - * @return byte array containing bytes that could be read, but no more than byteCount. - * When the timeout is hit, returns just bytes that were available or empty array if no bytes were available. - */ - public byte[] readBytes(int byteCount, int timeout) { - waitForData(byteCount, timeout); - - return readBytes(byteCount); - } - - /** - * Reads all available bytes from the port as integer (in range from 0 to 255) values array. - * Returns immediately, without waiting for data to be available. - * - * @return all bytes that could be read as int array (each value in range from 0 to 255) or empty array if no data was available. - */ - public int[] readIntArray() { - return readIntArray(inboundMessageListener.getAvailableBytesCount()); - } - - /** - * Reads at max given number of integer values (in range from 0 to 255) from the port. - * Returns immediately, without waiting for data to be available. - * - * @param byteCount - * maximum number of bytes that should be read - * @return integer array containing integer values that could be read, but no more than given byteCount (each value in range from 0 to 255). - * Returns empty array if no data was available. - */ - public int[] readIntArray(int byteCount) { - byte[] bytesArray = readBytes(byteCount); - int[] intArray = new int[bytesArray.length]; - - for (int i = 0; i < bytesArray.length; i++) { - intArray[i] = TypeConverter.byteToInt(bytesArray[i]); - } - - return intArray; - } - - /** - * Reads at max given number of integer values (in range from 0 to 255) from the port. - * This operation blocks until given number of bytes is available to be read or until given timeout is hit. - * - * @param byteCount - * maximum number of bytes that should be read. - * @param timeout - * maximum time in milliseconds that we want to wait for all available data - * @return integer array containing integer values that could be read, but no more than byteCount (each value in range from 0 to 255). - * When the timeout is hit, returns just data that was available or empty array if no data was available. - */ - public int[] readIntArray(int byteCount, int timeout) { - waitForData(byteCount, timeout); - - return readIntArray(byteCount); - } - - /** - * Read all available bytes from the port and converts them to {@link String} using platform's default {@link Charset}. - * Returns immediately, without waiting for data to be available. - * - * @return all bytes that could be read as {@link String}. - */ - public String readString() { - return readString(inboundMessageListener.getAvailableBytesCount()); - } - - /** - * Reads at max given number of bytes from the port, converting them to {@link String} using platform's default {@link Charset}. - * Returns immediately, without waiting for data to be available. - * - * @param byteCount - * maximum number of bytes that should be read - * @return all bytes that could be read as {@link String}, but no more than given byteCount. - */ - public String readString(int byteCount) { - return new String(readBytes(byteCount)); - } - - /** - * Reads at max given number of bytes from the port, converting them to {@link String} using platform's default {@link Charset}. - * This operation blocks until given number of bytes is available to be read or until given timeout is hit. - * - * @param byteCount - * maximum number of bytes that should be read. - * @param timeout - * maximum time in milliseconds that we want to wait for all available bytes - * @return all bytes that could be read as {@link String}, but no more than given byteCount. - * When the timeout is hit, returns just bytes that were available. - */ - public String readString(int byteCount, int timeout) { - waitForData(byteCount, timeout); - - return readString(byteCount); - } - - /** - * Read all available bytes from the port and converts them to {@link String} using given {@link Charset}. - * Returns immediately, without waiting for data to be available. - * - * @param charset - * {@link Charset} that will be used when converting bytes to {@link String} - * - * @return all bytes that could be read as {@link String}. - */ - public String readString(Charset charset) { - return readString(charset, inboundMessageListener.getAvailableBytesCount()); - } - - /** - * Reads at max given number of bytes from the port, converting them to {@link String} using given {@link Charset}. - * Returns immediately, without waiting for data to be available. - * - * @param charset - * {@link Charset} that will be used when converting bytes to {@link String} - * @param byteCount - * maximum number of bytes that should be read - * @return all bytes that could be read as {@link String}, but no more than given byteCount. - */ - public String readString(Charset charset, int byteCount) { - return new String(readBytes(byteCount), charset); - } - - /** - * Reads at max given number of bytes from the port, converting them to {@link String} using given {@link Charset}. - * This operation blocks until given number of bytes is available to be read or until given timeout is hit. - * - * @param charset - * {@link Charset} that will be used when converting bytes to {@link String} - * @param byteCount - * maximum number of bytes that should be read. - * @param timeout - * maximum time in milliseconds that we want to wait for all available bytes - * @return all bytes that could be read as {@link String}, but no more than given byteCount. - * When the timeout is hit, returns just bytes that were available. - */ - public String readString(Charset charset, int byteCount, int timeout) { - waitForData(byteCount, timeout); - - return readString(charset, byteCount); - } - - private void waitForData(int wantedByteCount, int timeout) { - long startTime = System.currentTimeMillis(); - - while (isTooFewBytesAvailable(wantedByteCount) && timeoutNotHit(timeout, startTime)) { - // NOP, just waiting - } - } - - private boolean isTooFewBytesAvailable(int wantedByteCount) { - return inboundMessageListener.getAvailableBytesCount() < wantedByteCount; - } - - private boolean timeoutNotHit(int timeout, long startTime) { - return System.currentTimeMillis() - startTime < timeout; - } - - /** - * Invokes given SOL-specific operations on remote serial port. - * - * @param operations - * a bunch of {@link SolOperation}s that should be invoked - * @return true if operations were successfully sent and acknowledged by remote server, false otherwise. - */ - public boolean invokeOperations(SolOperation... operations) { - Set operationSet = new HashSet(); - - for (SolOperation operation : operations) { - operationSet.add(operation); - } - - return sendMessage(operationSet); - } - - /** - * Registers new {@link SolEventListener} that will be informed about SOL events fired by remote system. - * - * @param listener - * listener to be registered - */ - public void registerEventListener(SolEventListener listener) { - eventListeners.add(listener); - } - - /** - * Unregister given {@link SolEventListener}, preventing it from receiving SOL events from remote server. - * - * @param listener - * listener to be unregistered - */ - public void unregisterEventListener(SolEventListener listener) { - eventListeners.remove(listener); - } - - private boolean sendMessage(byte[] characterData) { - SolCoder payloadCoder = new SolCoder(characterData, session.getConnectionHandle().getCipherSuite()); - - SolResponseData responseData = sendPayload(payloadCoder); - - notifyResponseListeners(characterData, new HashSet(), responseData); - - byte[] remainingCharacterData = characterData; - - while (isNackForMessagePart(responseData, remainingCharacterData.length)) { - remainingCharacterData = Arrays.copyOfRange(remainingCharacterData, - responseData.getAcceptedCharactersNumber(), remainingCharacterData.length); - - SolCoder partialPayloadCoder = new SolCoder(remainingCharacterData, session.getConnectionHandle().getCipherSuite()); - responseData = sendPayload(partialPayloadCoder); - - notifyResponseListeners(remainingCharacterData, new HashSet(), responseData); - } - - return responseData != null && responseData.getAcknowledgeState() == SolAckState.ACK; - } - - private boolean sendMessage(Set operations) { - SolCoder payloadCoder = new SolCoder(operations, session.getConnectionHandle().getCipherSuite()); - - SolResponseData responseData = sendPayload(payloadCoder); - - notifyResponseListeners(new byte[0], operations, responseData); - - return responseData != null && responseData.getAcknowledgeState() == SolAckState.ACK; - } - - private void notifyResponseListeners(byte[] characterData, Set solOperations, SolResponseData responseData) { - if (responseData != null && responseData.getStatuses() != null && !responseData.getStatuses().isEmpty()) { - for (SolEventListener listener : eventListeners) { - listener.processResponseEvent(responseData.getStatuses(), characterData, solOperations); - } - } - } - - private SolResponseData sendPayload(PayloadCoder payloadCoder) { - ConnectionHandle connectionHandle = session.getConnectionHandle(); - - try { - SolResponseData responseData = (SolResponseData) connector.sendMessage(connectionHandle, payloadCoder); - - int actualRetries = 0; - - while (isNackForWholeMessage(responseData) && actualRetries < connector.getRetries()) { - actualRetries++; - - responseData = (SolResponseData) connector.retryMessage(connectionHandle, - responseData.getRequestSequenceNumber(), PayloadType.Sol); - } - - return responseData; - } catch (Exception e) { - logger.error("Error while sending message", e); - return null; - } - } - - @Override - public synchronized void close() throws IOException { - if (!closed) { - try { - ConnectionHandle connectionHandle = session.getConnectionHandle(); - - DeactivatePayload deactivatePayload = new DeactivatePayload(connectionHandle.getCipherSuite(), - PayloadType.Sol, payloadInstance); - - connector.sendMessage(connectionHandle, deactivatePayload); - - if (isSessionInternal) { - connector.closeSession(connectionHandle); - connector.tearDown(); - } - - closed = true; - } catch (Exception e) { - throw new IOException("Error while closing Serial over LAN instance", e); - } - - } - } - - private boolean isNackForWholeMessage(SolResponseData responseData) { - return responseData != null - && responseData.getAcknowledgeState() == SolAckState.NACK - && responseData.getAcceptedCharactersNumber() == 0; - } - - private boolean isNackForMessagePart(SolResponseData responseData, int previousMessageDataLength) { - return responseData != null - && responseData.getAcknowledgeState() == SolAckState.NACK - && responseData.getAcceptedCharactersNumber() > 0 - && responseData.getAcceptedCharactersNumber() < previousMessageDataLength; - } + private static final Logger LOGGER = LoggerFactory.getLogger(SerialOverLan.class); + + private final IpmiConnector connector; + private final Session session; + private final InboundSolMessageListener inboundMessageListener; + private final List eventListeners; + + private boolean isSessionInternal; + private int payloadInstance; + private int maxPayloadSize; + private boolean closed; + + /** + * Creates connection with IPMI using given {@link IpmiConnector}, connected to remote machine on given address and + * port, + * and opens a new {@link Session} for SOL communication. + * This constructor should be used only when you have no other connection opened on this port. + * + * @param connector + * {@link IpmiConnector} that will be used for communication + * @param remoteHost + * IP address of the remote server + * @param remotePort + * UDP port number of the remote server + * @param user + * IPMI user name + * @param password + * IPMI password + * @param cipherSuiteSelectionHandler + * {@link CipherSuiteSelectionHandler} that will allow to select {@link CipherSuite} among available ones. + * @throws SOLException when any problem occur during establishing session or activating SOL payload. + */ + public SerialOverLan(IpmiConnector connector, String remoteHost, int remotePort, String user, String password, + CipherSuiteSelectionHandler cipherSuiteSelectionHandler) throws SOLException, SessionException { + this( + connector, + SessionManager + .establishSession(connector, remoteHost, remotePort, user, password, cipherSuiteSelectionHandler)); + + this.isSessionInternal = true; + } + + /** + * Creates connection with IPMI using given {@link IpmiConnector}, connected to remote machine on given address and + * default IPMI port, + * and opens a new {@link Session} for SOL communication. + * This constructor should be used only when you have no other connection opened on this port. + * + * @param connector + * {@link IpmiConnector} that will be used for communication + * @param remoteHost + * IP address of the remote server + * @param user + * IPMI user name + * @param password + * IPMI password + * @param cipherSuiteSelectionHandler + * {@link CipherSuiteSelectionHandler} that will allow to select {@link CipherSuite} among available ones. + * @throws SOLException when any problem occur during establishing session or activating SOL payload. + */ + public SerialOverLan(IpmiConnector connector, String remoteHost, String user, String password, + CipherSuiteSelectionHandler cipherSuiteSelectionHandler) throws SOLException, SessionException { + this(connector, remoteHost, Constants.IPMI_PORT, user, password, cipherSuiteSelectionHandler); + } + + /** + * Tries to open SOL communication on given existing session. When it appears that separate session must be opened + * to handle SOL messages (for example SOL payload must be activated on separate port), the new connection and session + * are automatically established. + * + * @param connector + * {@link IpmiConnector} that will be used for communication + * @param session + * Existing session that should be reused (if possible) for SOL communication. + */ + public SerialOverLan(IpmiConnector connector, Session session) throws SOLException, SessionException { + this.connector = connector; + + int solPayloadPort = activatePayload(connector, session.getConnectionHandle()); + + this.session = resolveSession(connector, session.getConnectionHandle(), session, solPayloadPort); + + this.eventListeners = new LinkedList(); + this.inboundMessageListener = new InboundSolMessageListener( + connector, + this.session.getConnectionHandle(), + eventListeners); + + connector.registerIncomingMessageListener(inboundMessageListener); + this.closed = false; + } + + /** + * Given potential session object, connection data and port on which SOL should be activated, + * decides what session should be finally used to SOL communication. + * + * @param ipmiConnector + * {@link IpmiConnector} that will be used for communication + * @param connectionHandle + * {@link ConnectionHandle} representing single connection to managed system. + * @param currentSession + * Existing session that should be reused (if possible) for SOL communication. + * @param solPayloadPort + * UDP port on which managed system listens for SOL communication. + * @return Actual session (existing or newly established), that should be used for SOL communication. + * @throws SOLException + * If any unrecoverable error occurs. + * @throws SessionException + * If new session could not be established. + */ + private Session resolveSession( + IpmiConnector ipmiConnector, + ConnectionHandle connectionHandle, + Session currentSession, + int solPayloadPort) + throws SOLException, + SessionException { + if (solPayloadPort != connectionHandle.getRemotePort()) { + Session alternativeSession = ipmiConnector + .getExistingSessionForCriteria( + connectionHandle.getRemoteAddress(), + solPayloadPort, + connectionHandle.getUser()); + + if (alternativeSession == null) { + CipherSuiteSelectionHandler cipherSuiteSelector = new SpecificCipherSuiteSelector( + connectionHandle.getCipherSuite()); + + alternativeSession = SessionManager + .establishSession( + ipmiConnector, + connectionHandle.getRemoteAddress().getHostAddress(), + solPayloadPort, + connectionHandle.getUser(), + connectionHandle.getPassword(), + cipherSuiteSelector); + this.isSessionInternal = true; + + } else { + this.isSessionInternal = false; + } + + activatePayload(ipmiConnector, alternativeSession.getConnectionHandle()); + + return alternativeSession; + } else { + this.isSessionInternal = false; + return currentSession; + } + } + + /** + * Tries to activate SOL payload in the session associated to given {@link ConnectionHandle}. + * If first activation try fails due to insufficient privileges, raises the session privileges + * to maximum available and tries to activate payload once again. + * + * @param ipmiConnector + * {@link IpmiConnector} that will be used for communication + * @param connectionHandle + * {@link ConnectionHandle} representing single connection to managed system. + * @return UDP port number on which managed system listenes for SOL messages. + * @throws SOLException + * when any unrecoverable error occurred. + */ + private int activatePayload(IpmiConnector ipmiConnector, ConnectionHandle connectionHandle) throws SOLException { + try { + this.payloadInstance = getFirstAvailablePayloadInstance(ipmiConnector, connectionHandle); + + ActivateSolPayload activatePayload = new ActivateSolPayload(connectionHandle.getCipherSuite(), payloadInstance); + ActivateSolPayloadResponseData activatePayloadResponseData = getActivatePayloadResponse( + ipmiConnector, + connectionHandle, + activatePayload); + + this.maxPayloadSize = activatePayloadResponseData.getInboundPayloadSize(); + + return activatePayloadResponseData.getPayloadUdpPortNumber(); + + } catch (Exception e) { + throw new SOLException("Cannot activate SOL payload due to exception during activation process", e); + } + } + + private ActivateSolPayloadResponseData getActivatePayloadResponse( + IpmiConnector ipmiConnector, + ConnectionHandle connectionHandle, + ActivateSolPayload activatePayload) + throws Exception { + ActivateSolPayloadResponseData activatePayloadResponseData; + + try { + activatePayloadResponseData = (ActivateSolPayloadResponseData) ipmiConnector + .sendMessage( + connectionHandle, + activatePayload); + } catch (IPMIException e) { + if (e.getCompletionCode() == CompletionCode.InsufficentPrivilege) { + raiseSessionPrivileges(ipmiConnector, connectionHandle); + + activatePayloadResponseData = (ActivateSolPayloadResponseData) ipmiConnector + .sendMessage( + connectionHandle, + activatePayload); + } else { + throw e; + } + } + + return activatePayloadResponseData; + } + + /** + * Checks for available SOL payload instances and, if any, returns first available. + * + * @param ipmiConnector + * {@link IpmiConnector} that will be used for communication + * @param connectionHandle + * {@link ConnectionHandle} representing single connection to managed system. + * @return number of first available SOL payload instance. + * @throws Exception + * If any exception occurred during communication or if no available instances were found. + */ + private int getFirstAvailablePayloadInstance(IpmiConnector ipmiConnector, ConnectionHandle connectionHandle) + throws Exception { + GetPayloadActivationStatus getPayloadActivationStatus = new GetPayloadActivationStatus( + connectionHandle.getCipherSuite(), + PayloadType.Sol); + GetPayloadActivationStatusResponseData getActivationResponseData = (GetPayloadActivationStatusResponseData) ipmiConnector + .sendMessage( + connectionHandle, + getPayloadActivationStatus); + + if (getActivationResponseData.getInstanceCapacity() <= 0 + || getActivationResponseData.getAvailableInstances().isEmpty()) { + throw new SOLException("Cannot activate SOL payload, as there are no available payload instances."); + } + + return TypeConverter.byteToInt(getActivationResponseData.getAvailableInstances().get(0)); + } + + /** + * Sends proper command to managed system in order to raise user privileges in given session to maximum available + * level. + * + * @param ipmiConnector + * {@link IpmiConnector} that will be used for communication + * @param connectionHandle + * {@link ConnectionHandle} representing single connection to managed system. + * @throws Exception + * If any exception occurred during communication. + */ + private void raiseSessionPrivileges(IpmiConnector ipmiConnector, ConnectionHandle connectionHandle) throws Exception { + SetSessionPrivilegeLevel setSessionPrivilegeLevel = new SetSessionPrivilegeLevel( + IpmiVersion.V20, + connectionHandle.getCipherSuite(), + AuthenticationType.RMCPPlus, + PrivilegeLevel.Administrator); + ipmiConnector.sendMessage(connectionHandle, setSessionPrivilegeLevel); + } + + /** + * Writes single byte to the port. + * This operation blocks until all data can be sent to remote server and is either accepted or rejected by the server. + * + * @param singleByte + * a byte to write + * @return true if byte was successfully sent and acknowledged by remote server, false otherwise. + */ + public boolean writeByte(byte singleByte) { + return writeBytes(new byte[] { singleByte }); + } + + /** + * Writes bytes array to the port. + * This operation blocks until all data can be sent to remote server and is either accepted or rejected by the server. + * + * @param buffer + * an array of bytes to write + * @return true if all bytes were successfully sent and acknowledged by remote server, false otherwise. + */ + public boolean writeBytes(byte[] buffer) { + boolean result = true; + + int maxBufferSize = maxPayloadSize - SolMessage.PAYLOAD_HEADER_LENGTH; + byte[] remainingBytes = buffer; + int currentIndex = 0; + + while (remainingBytes.length - currentIndex > maxBufferSize) { + byte[] bufferChunk = Arrays.copyOfRange(remainingBytes, currentIndex, maxBufferSize); + currentIndex += maxBufferSize; + + result &= sendMessage(bufferChunk); + + if (!result) { + return false; + } + } + + if (remainingBytes.length - currentIndex > 0) { + remainingBytes = Arrays.copyOfRange(remainingBytes, currentIndex, remainingBytes.length); + result &= sendMessage(remainingBytes); + } + + return result; + } + + /** + * Writes single integer (in range from 0 to 255) to the port. + * This operation blocks until all data can be sent to remote server and is either accepted or rejected by the server. + * + * @param singleInt + * an integer value to write (must be in range from 0 to 255) + * @return true if integer was successfully sent and acknowledged by remote server, false otherwise. + */ + public boolean writeInt(int singleInt) { + return writeBytes(new byte[] { TypeConverter.intToByte(singleInt) }); + } + + /** + * Writes integers (in range from 0 to 255) array to the port. + * This operation blocks until all data can be sent to remote server and is either accepted or rejected by the server. + * + * @param buffer + * an array of integer values to write (each must be in range from 0 to 255) + * @return true if all integers were successfully sent and acknowledged by remote server, false otherwise. + */ + public boolean writeIntArray(int[] buffer) { + byte[] byteBuffer = new byte[buffer.length]; + + for (int i = 0; i < buffer.length; i++) { + byteBuffer[i] = TypeConverter.intToByte(buffer[i]); + } + + return writeBytes(byteBuffer); + } + + /** + * Writes {@link String} to port, using platform's default {@link Charset} when converting {@link String} to byte + * array. + * This operation blocks until all data can be sent to remote server and is either accepted or rejected by the server. + * + * @param string + * a string to write to the port. + * @return true if whole string was successfully sent and acknowledged by remote server, false otherwise. + */ + public boolean writeString(String string) { + return writeBytes(string.getBytes()); + } + + /** + * Writes {@link String} to port, using given {@link Charset} when converting {@link String} to byte array. + * This operation blocks until all data can be sent to remote server and is either accepted or rejected by the server. + * + * @param string + * a string to write to port + * @param charset + * {@link Charset} that the string is encoded in + * @return true if whole string was successfully sent and acknowledged by remote server, false otherwise. + */ + public boolean writeString(String string, Charset charset) { + return writeBytes(string.getBytes(charset)); + } + + /** + * Read all available bytes from the port. + * Returns immediately, without waiting for data to be available. + * + * @return all bytes that could be read or empty array if no bytes were available. + */ + public byte[] readBytes() { + return readBytes(inboundMessageListener.getAvailableBytesCount()); + } + + /** + * Reads at max given number of bytes from the port. + * Returns immediately, without waiting for data to be available. + * + * @param byteCount + * maximum number of bytes that should be read + * @return byte array containing bytes that could be read, but no more than given byteCount. + * Returns empty array if no bytes were available. + */ + public byte[] readBytes(int byteCount) { + return inboundMessageListener.readBytes(byteCount); + } + + /** + * Reads at max given number of bytes from the port. + * This operation blocks until given number of bytes is available to be read or until given timeout is hit. + * + * @param byteCount + * maximum number of bytes that should be read. + * @param timeout + * maximum time in milliseconds that we want to wait for all available bytes + * @return byte array containing bytes that could be read, but no more than byteCount. + * When the timeout is hit, returns just bytes that were available or empty array if no bytes were available. + */ + public byte[] readBytes(int byteCount, int timeout) { + waitForData(byteCount, timeout); + + return readBytes(byteCount); + } + + /** + * Reads all available bytes from the port as integer (in range from 0 to 255) values array. + * Returns immediately, without waiting for data to be available. + * + * @return all bytes that could be read as int array (each value in range from 0 to 255) or empty array if no data was + * available. + */ + public int[] readIntArray() { + return readIntArray(inboundMessageListener.getAvailableBytesCount()); + } + + /** + * Reads at max given number of integer values (in range from 0 to 255) from the port. + * Returns immediately, without waiting for data to be available. + * + * @param byteCount + * maximum number of bytes that should be read + * @return integer array containing integer values that could be read, but no more than given byteCount (each value in + * range from 0 to 255). + * Returns empty array if no data was available. + */ + public int[] readIntArray(int byteCount) { + byte[] bytesArray = readBytes(byteCount); + int[] intArray = new int[bytesArray.length]; + + for (int i = 0; i < bytesArray.length; i++) { + intArray[i] = TypeConverter.byteToInt(bytesArray[i]); + } + + return intArray; + } + + /** + * Reads at max given number of integer values (in range from 0 to 255) from the port. + * This operation blocks until given number of bytes is available to be read or until given timeout is hit. + * + * @param byteCount + * maximum number of bytes that should be read. + * @param timeout + * maximum time in milliseconds that we want to wait for all available data + * @return integer array containing integer values that could be read, but no more than byteCount (each value in range + * from 0 to 255). + * When the timeout is hit, returns just data that was available or empty array if no data was available. + */ + public int[] readIntArray(int byteCount, int timeout) { + waitForData(byteCount, timeout); + + return readIntArray(byteCount); + } + + /** + * Read all available bytes from the port and converts them to {@link String} using platform's default + * {@link Charset}. + * Returns immediately, without waiting for data to be available. + * + * @return all bytes that could be read as {@link String}. + */ + public String readString() { + return readString(inboundMessageListener.getAvailableBytesCount()); + } + + /** + * Reads at max given number of bytes from the port, converting them to {@link String} using platform's default + * {@link Charset}. + * Returns immediately, without waiting for data to be available. + * + * @param byteCount + * maximum number of bytes that should be read + * @return all bytes that could be read as {@link String}, but no more than given byteCount. + */ + public String readString(int byteCount) { + return new String(readBytes(byteCount)); + } + + /** + * Reads at max given number of bytes from the port, converting them to {@link String} using platform's default + * {@link Charset}. + * This operation blocks until given number of bytes is available to be read or until given timeout is hit. + * + * @param byteCount + * maximum number of bytes that should be read. + * @param timeout + * maximum time in milliseconds that we want to wait for all available bytes + * @return all bytes that could be read as {@link String}, but no more than given byteCount. + * When the timeout is hit, returns just bytes that were available. + */ + public String readString(int byteCount, int timeout) { + waitForData(byteCount, timeout); + + return readString(byteCount); + } + + /** + * Read all available bytes from the port and converts them to {@link String} using given {@link Charset}. + * Returns immediately, without waiting for data to be available. + * + * @param charset + * {@link Charset} that will be used when converting bytes to {@link String} + * @return all bytes that could be read as {@link String}. + */ + public String readString(Charset charset) { + return readString(charset, inboundMessageListener.getAvailableBytesCount()); + } + + /** + * Reads at max given number of bytes from the port, converting them to {@link String} using given {@link Charset}. + * Returns immediately, without waiting for data to be available. + * + * @param charset + * {@link Charset} that will be used when converting bytes to {@link String} + * @param byteCount + * maximum number of bytes that should be read + * @return all bytes that could be read as {@link String}, but no more than given byteCount. + */ + public String readString(Charset charset, int byteCount) { + return new String(readBytes(byteCount), charset); + } + + /** + * Reads at max given number of bytes from the port, converting them to {@link String} using given {@link Charset}. + * This operation blocks until given number of bytes is available to be read or until given timeout is hit. + * + * @param charset + * {@link Charset} that will be used when converting bytes to {@link String} + * @param byteCount + * maximum number of bytes that should be read. + * @param timeout + * maximum time in milliseconds that we want to wait for all available bytes + * @return all bytes that could be read as {@link String}, but no more than given byteCount. + * When the timeout is hit, returns just bytes that were available. + */ + public String readString(Charset charset, int byteCount, int timeout) { + waitForData(byteCount, timeout); + + return readString(charset, byteCount); + } + + private void waitForData(int wantedByteCount, int timeout) { + long startTime = System.currentTimeMillis(); + + while (isTooFewBytesAvailable(wantedByteCount) && timeoutNotHit(timeout, startTime)) { + // NOP, just waiting + } + } + + private boolean isTooFewBytesAvailable(int wantedByteCount) { + return inboundMessageListener.getAvailableBytesCount() < wantedByteCount; + } + + private boolean timeoutNotHit(int timeout, long startTime) { + return System.currentTimeMillis() - startTime < timeout; + } + + /** + * Invokes given SOL-specific operations on remote serial port. + * + * @param operations + * a bunch of {@link SolOperation}s that should be invoked + * @return true if operations were successfully sent and acknowledged by remote server, false otherwise. + */ + public boolean invokeOperations(SolOperation... operations) { + Set operationSet = new HashSet(); + + for (SolOperation operation : operations) { + operationSet.add(operation); + } + + return sendMessage(operationSet); + } + + /** + * Registers new {@link SolEventListener} that will be informed about SOL events fired by remote system. + * + * @param listener + * listener to be registered + */ + public void registerEventListener(SolEventListener listener) { + eventListeners.add(listener); + } + + /** + * Unregister given {@link SolEventListener}, preventing it from receiving SOL events from remote server. + * + * @param listener + * listener to be unregistered + */ + public void unregisterEventListener(SolEventListener listener) { + eventListeners.remove(listener); + } + + private boolean sendMessage(byte[] characterData) { + SolCoder payloadCoder = new SolCoder(characterData, session.getConnectionHandle().getCipherSuite()); + + SolResponseData responseData = sendPayload(payloadCoder); + + notifyResponseListeners(characterData, new HashSet(), responseData); + + byte[] remainingCharacterData = characterData; + + while (isNackForMessagePart(responseData, remainingCharacterData.length)) { + remainingCharacterData = Arrays + .copyOfRange( + remainingCharacterData, + responseData.getAcceptedCharactersNumber(), + remainingCharacterData.length); + + SolCoder partialPayloadCoder = new SolCoder( + remainingCharacterData, + session.getConnectionHandle().getCipherSuite()); + responseData = sendPayload(partialPayloadCoder); + + notifyResponseListeners(remainingCharacterData, new HashSet(), responseData); + } + + return responseData != null && responseData.getAcknowledgeState() == SolAckState.ACK; + } + + private boolean sendMessage(Set operations) { + SolCoder payloadCoder = new SolCoder(operations, session.getConnectionHandle().getCipherSuite()); + + SolResponseData responseData = sendPayload(payloadCoder); + + notifyResponseListeners(new byte[0], operations, responseData); + + return responseData != null && responseData.getAcknowledgeState() == SolAckState.ACK; + } + + private void notifyResponseListeners( + byte[] characterData, + Set solOperations, + SolResponseData responseData) { + if (responseData != null && responseData.getStatuses() != null && !responseData.getStatuses().isEmpty()) { + for (SolEventListener listener : eventListeners) { + listener.processResponseEvent(responseData.getStatuses(), characterData, solOperations); + } + } + } + + private SolResponseData sendPayload(PayloadCoder payloadCoder) { + ConnectionHandle connectionHandle = session.getConnectionHandle(); + + try { + SolResponseData responseData = (SolResponseData) connector.sendMessage(connectionHandle, payloadCoder); + + int actualRetries = 0; + + while (isNackForWholeMessage(responseData) && actualRetries < connector.getRetries()) { + actualRetries++; + + responseData = (SolResponseData) connector + .retryMessage( + connectionHandle, + responseData.getRequestSequenceNumber(), + PayloadType.Sol); + } + + return responseData; + } catch (Exception e) { + LOGGER.error("Error while sending message", e); + return null; + } + } + + @Override + public synchronized void close() throws IOException { + if (!closed) { + try { + ConnectionHandle connectionHandle = session.getConnectionHandle(); + + DeactivatePayload deactivatePayload = new DeactivatePayload( + connectionHandle.getCipherSuite(), + PayloadType.Sol, + payloadInstance); + + connector.sendMessage(connectionHandle, deactivatePayload); + + if (isSessionInternal) { + connector.closeSession(connectionHandle); + connector.tearDown(); + } + + closed = true; + } catch (Exception e) { + throw new IOException("Error while closing Serial over LAN instance", e); + } + + } + } + + private boolean isNackForWholeMessage(SolResponseData responseData) { + return responseData != null + && responseData.getAcknowledgeState() == SolAckState.NACK + && responseData.getAcceptedCharactersNumber() == 0; + } + + private boolean isNackForMessagePart(SolResponseData responseData, int previousMessageDataLength) { + return responseData != null + && responseData.getAcknowledgeState() == SolAckState.NACK + && responseData.getAcceptedCharactersNumber() > 0 + && responseData.getAcceptedCharactersNumber() < previousMessageDataLength; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/api/sol/SolEventListener.java b/src/main/java/org/metricshub/ipmi/core/api/sol/SolEventListener.java index bfb92ed..24346e6 100644 --- a/src/main/java/org/metricshub/ipmi/core/api/sol/SolEventListener.java +++ b/src/main/java/org/metricshub/ipmi/core/api/sol/SolEventListener.java @@ -1,4 +1,4 @@ -package org.metricshub.ipmi.core.api.sol; +package org.metricshub.ipmi.core.api.sol; /*- * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ @@ -33,26 +33,29 @@ */ public interface SolEventListener { - /** - * Process event sent proactively by remote server. - * - * @param statuses - * statuses indicated by remote server - */ - void processRequestEvent(Set statuses); + /** + * Process event sent proactively by remote server. + * + * @param statuses + * statuses indicated by remote server + */ + void processRequestEvent(Set statuses); - /** - * Process event sent by remote server as a response for some outbound message. - * - * @param statuses - * statuses indicated by remote server - * @param correspondingRequestData - * data from message, that caused this event to be fired. - * Can be empty array if message didn't contain character data. - * @param correspondingRequestOperations - * set of operations invoked on remote server's serial port that caused this event to be fired. - * Can be empty set if corresponding request message didn't contain any operations to be invoked - */ - void processResponseEvent(Set statuses, byte[] correspondingRequestData, Set correspondingRequestOperations); + /** + * Process event sent by remote server as a response for some outbound message. + * + * @param statuses + * statuses indicated by remote server + * @param correspondingRequestData + * data from message, that caused this event to be fired. + * Can be empty array if message didn't contain character data. + * @param correspondingRequestOperations + * set of operations invoked on remote server's serial port that caused this event to be fired. + * Can be empty set if corresponding request message didn't contain any operations to be invoked + */ + void processResponseEvent( + Set statuses, + byte[] correspondingRequestData, + Set correspondingRequestOperations); } diff --git a/src/main/java/org/metricshub/ipmi/core/api/sol/SpecificCipherSuiteSelector.java b/src/main/java/org/metricshub/ipmi/core/api/sol/SpecificCipherSuiteSelector.java index 125db8b..772a8d8 100644 --- a/src/main/java/org/metricshub/ipmi/core/api/sol/SpecificCipherSuiteSelector.java +++ b/src/main/java/org/metricshub/ipmi/core/api/sol/SpecificCipherSuiteSelector.java @@ -31,15 +31,15 @@ */ public class SpecificCipherSuiteSelector implements CipherSuiteSelectionHandler { - private final CipherSuite cipherSuite; + private final CipherSuite cipherSuite; - public SpecificCipherSuiteSelector(CipherSuite cipherSuite) { - this.cipherSuite = cipherSuite; - } + public SpecificCipherSuiteSelector(CipherSuite cipherSuite) { + this.cipherSuite = cipherSuite; + } - @Override - public CipherSuite choose(List availableCipherSuites) { - return cipherSuite; - } + @Override + public CipherSuite choose(List availableCipherSuites) { + return cipherSuite; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/api/sync/IpmiConnector.java b/src/main/java/org/metricshub/ipmi/core/api/sync/IpmiConnector.java index 9251d51..136246b 100644 --- a/src/main/java/org/metricshub/ipmi/core/api/sync/IpmiConnector.java +++ b/src/main/java/org/metricshub/ipmi/core/api/sync/IpmiConnector.java @@ -50,74 +50,93 @@ import java.util.Random; /** - *

Synchronous API for connecting to BMC via IPMI.


Creating connection consists of the following steps: + *

+ * Synchronous API for connecting to BMC via IPMI. + *

+ *
+ * Creating connection consists of the following steps: *
    *
  • Create {@link Connection} and get associated with it {@link ConnectionHandle} via - * {@link #createConnection(InetAddress)}
  • Get {@link CipherSuite}s that are available for the connection via - * {@link #getAvailableCipherSuites(ConnectionHandle)}
  • Pick {@link CipherSuite} and {@link PrivilegeLevel} that will + * {@link #createConnection(InetAddress)}
  • + *
  • Get {@link CipherSuite}s that are available for the connection via + * {@link #getAvailableCipherSuites(ConnectionHandle)}
  • + *
  • Pick {@link CipherSuite} and {@link PrivilegeLevel} that will * be used during session and get {@link GetChannelAuthenticationCapabilitiesResponseData} to find out allowed * authentication options via - * {@link #getChannelAuthenticationCapabilities(ConnectionHandle, CipherSuite, PrivilegeLevel)}
  • Provide username, + * {@link #getChannelAuthenticationCapabilities(ConnectionHandle, CipherSuite, PrivilegeLevel)}
  • + *
  • Provide username, * password and (if the BMC needs it) the BMC Kg key and start session via - * {@link #openSession(ConnectionHandle, String, String, byte[])}
  • + * {@link #openSession(ConnectionHandle, String, String, byte[])} *
*
- *

Send message register via - * {@link #sendMessage(ConnectionHandle, PayloadCoder)}


To close session call - * {@link #closeSession(ConnectionHandle)}

When done with work, clean up via {@link #tearDown()}


+ *

+ * Send message register via + * {@link #sendMessage(ConnectionHandle, PayloadCoder)} + *

+ *
+ *

+ * To close session call + * {@link #closeSession(ConnectionHandle)} + *

+ *

+ * When done with work, clean up via {@link #tearDown()} + *

+ *
*/ public class IpmiConnector { - private static Logger logger = LoggerFactory.getLogger(IpmiConnector.class); - - private IpmiAsyncConnector asyncConnector; - - private int retries; - - private int idleTime; - - private Random random = new Random(System.currentTimeMillis()); - - /** - * Starts {@link IpmiConnector} and initiates the {@link ConnectionManager} at the given port. Wildcard IP address - * will be used. - * @param port - * - the port that will be used by {@link IpmiAsyncConnector} to communicate with the remote hosts. - * @throws FileNotFoundException - * when properties file was not found - * @throws IOException - * when properties file was not found - */ - public IpmiConnector(int port) throws IOException { - asyncConnector = new IpmiAsyncConnector(port); - loadProperties(); - } - - /** - * Starts {@link IpmiConnector} and initiates the {@link ConnectionManager} at the given port and IP interface. - * @param port - * - the port that will be used by {@link IpmiAsyncConnector} to communicate with the remote hosts. - * @param address - * - the IP address that will be used by {@link IpmiAsyncConnector} to communicate with the remote hosts. - * @throws FileNotFoundException - * when properties file was not found - * @throws IOException - * when properties file was not found - */ - public IpmiConnector(int port, InetAddress address) throws IOException { - asyncConnector = new IpmiAsyncConnector(port, address); - loadProperties(); - } + private static Logger logger = LoggerFactory.getLogger(IpmiConnector.class); + + private IpmiAsyncConnector asyncConnector; + + private int retries; + + private int idleTime; + + private Random random = new Random(System.currentTimeMillis()); + + /** + * Starts {@link IpmiConnector} and initiates the {@link ConnectionManager} at the given port. Wildcard IP address + * will be used. + * + * @param port + * - the port that will be used by {@link IpmiAsyncConnector} to communicate with the remote hosts. + * @throws FileNotFoundException + * when properties file was not found + * @throws IOException + * when properties file was not found + */ + public IpmiConnector(int port) throws IOException { + asyncConnector = new IpmiAsyncConnector(port); + loadProperties(); + } + + /** + * Starts {@link IpmiConnector} and initiates the {@link ConnectionManager} at the given port and IP interface. + * + * @param port + * - the port that will be used by {@link IpmiAsyncConnector} to communicate with the remote hosts. + * @param address + * - the IP address that will be used by {@link IpmiAsyncConnector} to communicate with the remote hosts. + * @throws FileNotFoundException + * when properties file was not found + * @throws IOException + * when properties file was not found + */ + public IpmiConnector(int port, InetAddress address) throws IOException { + asyncConnector = new IpmiAsyncConnector(port, address); + loadProperties(); + } /** * Starts {@link IpmiConnector} and initiates the {@link ConnectionManager} at * the given port. Wildcard IP address will be used. - * - * @param port the port that will be used by {@link IpmiAsyncConnector} to - * communicate with the remote hosts. + * + * @param port the port that will be used by {@link IpmiAsyncConnector} to + * communicate with the remote hosts. * @param pingPeriod the period in milliseconds used to send the keep alive - * messages.
- * 0 If keep-alive messages should be disabled. + * messages.
+ * 0 If keep-alive messages should be disabled. * @throws IOException When IpmiAsyncConnector cannot be created. */ public IpmiConnector(int port, long pingPeriod) throws IOException { @@ -134,331 +153,355 @@ private void loadProperties() { idleTime = Integer.parseInt(manager.getProperty("idleTime")); } - /** - * Creates connection to the remote host on default IPMI port. - * @param address - * - {@link InetAddress} of the remote host - * @return handle to the connection to the remote host - * @throws IOException - * when properties file was not found - * @throws FileNotFoundException - * when properties file was not found - */ - public ConnectionHandle createConnection(InetAddress address) throws IOException { - return createConnection(address, Constants.IPMI_PORT); - } - - /** - * Creates connection to the remote host on specified port. - * @param address - * - {@link InetAddress} of the remote host - * @param port - * - remote UDP port - * @return handle to the connection to the remote host - * @throws IOException - * when properties file was not found - * @throws FileNotFoundException - * when properties file was not found - */ - public ConnectionHandle createConnection(InetAddress address, int port) throws IOException { - return asyncConnector.createConnection(address, port); - } - - /** - * Creates connection to the remote host, with pre set {@link CipherSuite} and {@link PrivilegeLevel}, skipping the - * getAvailableCipherSuites and getChannelAuthenticationCapabilities phases. - * @param address - * - {@link InetAddress} of the remote host - * @return handle to the connection to the remote host - * @throws IOException - * when properties file was not found - * @throws FileNotFoundException - * when properties file was not found - */ - public ConnectionHandle createConnection(InetAddress address, CipherSuite cipherSuite, PrivilegeLevel privilegeLevel) - throws IOException { - return createConnection(address, Constants.IPMI_PORT, cipherSuite, privilegeLevel); - } - - /** - * Creates connection to the remote host, with pre set {@link CipherSuite} and {@link PrivilegeLevel}, skipping the - * getAvailableCipherSuites and getChannelAuthenticationCapabilities phases. - * @param address - * - {@link InetAddress} of the remote host - * @param port - * - remote UDP port - * @return handle to the connection to the remote host - * @throws IOException - * when properties file was not found - * @throws FileNotFoundException - * when properties file was not found - */ - public ConnectionHandle createConnection(InetAddress address, int port, CipherSuite cipherSuite, PrivilegeLevel privilegeLevel) - throws IOException { - return asyncConnector.createConnection(address, port, cipherSuite, privilegeLevel); - } - - /** - * Gets {@link CipherSuite}s available for the connection with the remote host. - * @param connectionHandle - * {@link ConnectionHandle} to the connection created before - * @see #createConnection(InetAddress) - * @return list of the {@link CipherSuite}s that are allowed during the connection - * @throws Exception - * when sending message to the managed system fails - */ - public List getAvailableCipherSuites(ConnectionHandle connectionHandle) throws Exception { - return asyncConnector.getAvailableCipherSuites(connectionHandle); - } - - /** - * Gets the authentication capabilities for the connection with the remote host. - * @param connectionHandle - * - {@link ConnectionHandle} associated with the host - * @param cipherSuite - * - {@link CipherSuite} that will be used during the connection - * @param requestedPrivilegeLevel - * - {@link PrivilegeLevel} that is requested for the session - * @return - {@link GetChannelAuthenticationCapabilitiesResponseData} - * @throws ConnectionException - * when connection is in the state that does not allow to perform this operation. - * @throws Exception - * when sending message to the managed system fails - */ - public GetChannelAuthenticationCapabilitiesResponseData getChannelAuthenticationCapabilities( - ConnectionHandle connectionHandle, CipherSuite cipherSuite, PrivilegeLevel requestedPrivilegeLevel) - throws Exception { - return asyncConnector.getChannelAuthenticationCapabilities(connectionHandle, cipherSuite, - requestedPrivilegeLevel); - } - - /** - * Establishes the session with the remote host. - * @param connectionHandle - * - {@link ConnectionHandle} associated with the remote host. - * @param username - * - the username - * @param password - * - password matching the username - * @param bmcKey - * - the key that should be provided if the two-key authentication is enabled, null otherwise. - * - * @return object representing newly created {@link Session} - * - * @throws ConnectionException - * when connection is in the state that does not allow to perform this operation. - * @throws Exception - * when sending message to the managed system or initializing one of the cipherSuite's algorithms fails - */ - public Session openSession(ConnectionHandle connectionHandle, String username, String password, byte[] bmcKey) - throws Exception { - return asyncConnector.openSession(connectionHandle, username, password, bmcKey); - } - - /** - * Returns session already bound to given connection handle fulfilling given criteria. - * - * @param remoteAddress - * IP addres of the managed system - * @param remotePort - * UDP port of the managed system - * @param user - * IPMI user for whom the connection is established - * @return session object fulfilling given criteria, or null if no session was registered for such connection. - */ - public Session getExistingSessionForCriteria(InetAddress remoteAddress, int remotePort, String user) { - return asyncConnector.getExistingSessionForCriteria(remoteAddress, remotePort, user); - } - - /** - * Closes the session with the remote host if it is currently in open state. - * @param connectionHandle - * - {@link ConnectionHandle} associated with the remote host. - * @throws ConnectionException - * when connection is in the state that does not allow to perform this operation. - * @throws Exception - * when sending message to the managed system or initializing one of the cipherSuite's algorithms fails - */ - public void closeSession(ConnectionHandle connectionHandle) throws Exception { - asyncConnector.closeSession(connectionHandle); - } - - /** - * Sends the IPMI message to the remote host. - * @param connectionHandle - * - {@link ConnectionHandle} associated with the remote host. - * @param request - * - {@link PayloadCoder} containing the request to be sent - * @return {@link ResponseData} for the request - * @throws ConnectionException - * when connection is in the state that does not allow to perform this operation. - * @throws Exception - * when sending message to the managed system or initializing one of the cipherSuite's algorithms fails - */ - public ResponseData sendMessage(ConnectionHandle connectionHandle, PayloadCoder request) throws Exception { - return sendMessage(connectionHandle, request, true); - } - - /** - * Sends the IPMI message to the remote host and doesn't wait for any response. - * @param connectionHandle - * - {@link ConnectionHandle} associated with the remote host. - * @param request - * - {@link PayloadCoder} containing the request to be sent - * @throws ConnectionException - * when connection is in the state that does not allow to perform this operation. - * @throws Exception - * when sending message to the managed system or initializing one of the cipherSuite's algorithms fails - */ - public void sendOneWayMessage(ConnectionHandle connectionHandle, PayloadCoder request) throws Exception { - sendMessage(connectionHandle, request, false); - } - - /** - * Re-sends message with given tag having given {@link PayloadType}, using passed {@link ConnectionHandle}. - * - * @param connectionHandle - * - {@link ConnectionHandle} associated with the remote host. - * @param tag - * - tag of the message to retry - * @param messagePayloadType - * - {@link PayloadType} of the message that should be retried - * @return {@link ResponseData} for the re-sent request or null if message could not be resent. - * @throws Exception - * when sending message to the managed system fails - */ - public ResponseData retryMessage(ConnectionHandle connectionHandle, byte tag, PayloadType messagePayloadType) throws Exception { - MessageListener listener = new MessageListener(connectionHandle); - asyncConnector.registerListener(listener); - - int retryResult = asyncConnector.retry(connectionHandle, tag, messagePayloadType); - - ResponseData data = retryResult != -1 ? listener.waitForAnswer(tag) : null; - - asyncConnector.unregisterListener(listener); - - return data; - } - - private ResponseData sendMessage(ConnectionHandle connectionHandle, PayloadCoder request, boolean waitForResponse) throws Exception { - MessageListener listener = new MessageListener(connectionHandle); - - if (waitForResponse) { - asyncConnector.registerListener(listener); - } - - ResponseData data = sendThroughAsyncConnector(request, connectionHandle, listener, waitForResponse); - - if (waitForResponse) { - asyncConnector.unregisterListener(listener); - } - - return data; - } - - private ResponseData sendThroughAsyncConnector(PayloadCoder request, ConnectionHandle connectionHandle, - MessageListener listener, boolean waitForResponse) throws Exception { - ResponseData responseData = null; - - int tries = 0; - int tag = -1; - boolean messageSent = false; - - while (!messageSent) { - try { - ++tries; - - if (tag >= 0) { - tag = asyncConnector.retry(connectionHandle, tag, request.getSupportedPayloadType()); - } - - if (tag < 0){ - tag = asyncConnector.sendMessage(connectionHandle, request, !waitForResponse); - } - - logger.debug("Sending message with tag {}, try {}", tag, tries); - - if (waitForResponse) { - responseData = listener.waitForAnswer(tag); - } - - messageSent = true; - } catch (IllegalArgumentException e) { - throw e; - } catch (IPMIException e) { - handleErrorResponse(tries, e); - } catch (Exception e) { - handleRetriesWhenException(tries, e); - } - } - - return responseData; - } - - private void handleRetriesWhenException(int tries, Exception e) throws Exception { - if (tries > retries) { - throw e; - } else { - long sleepTime = (random.nextLong() % (idleTime / 2)) + (idleTime / 2); - - Thread.sleep(sleepTime); - logger.warn("Receiving message failed, retrying", e); - } - } - - private void handleErrorResponse(int tries, IPMIException e) throws Exception { - if (e.getCompletionCode() == CompletionCode.InitializationInProgress - || e.getCompletionCode() == CompletionCode.InsufficientResources - || e.getCompletionCode() == CompletionCode.NodeBusy - || e.getCompletionCode() == CompletionCode.Timeout) { - - handleRetriesWhenException(tries, e); - } else { - throw e; - } - } - - /** - * Registers {@link InboundMessageListener} that will react on any request sent from remote system to the application. - * - * @param listener - * listener to be registered. - */ - public void registerIncomingMessageListener(InboundMessageListener listener) { - asyncConnector.registerIncomingPayloadListener(listener); - } - - /** - * Closes the connection with the given handle - */ - public void closeConnection(ConnectionHandle handle) { - asyncConnector.closeConnection(handle); - } - - /** - * Finalizes the connector and closes all connections. - */ - public void tearDown() { - asyncConnector.tearDown(); - } - - /** - * Changes the timeout value for connection with the given handle. - * @param handle - * - {@link ConnectionHandle} associated with the remote host. - * @param timeout - * - new timeout value in ms - */ - public void setTimeout(ConnectionHandle handle, int timeout) { - asyncConnector.setTimeout(handle, timeout); - } - - /** - * Returns configured number of retries. - * - * @return number of retries when message could not be sent - */ - public int getRetries() { - return retries; - } + /** + * Creates connection to the remote host on default IPMI port. + * + * @param address + * - {@link InetAddress} of the remote host + * @return handle to the connection to the remote host + * @throws IOException + * when properties file was not found + * @throws FileNotFoundException + * when properties file was not found + */ + public ConnectionHandle createConnection(InetAddress address) throws IOException { + return createConnection(address, Constants.IPMI_PORT); + } + + /** + * Creates connection to the remote host on specified port. + * + * @param address + * - {@link InetAddress} of the remote host + * @param port + * - remote UDP port + * @return handle to the connection to the remote host + * @throws IOException + * when properties file was not found + * @throws FileNotFoundException + * when properties file was not found + */ + public ConnectionHandle createConnection(InetAddress address, int port) throws IOException { + return asyncConnector.createConnection(address, port); + } + + /** + * Creates connection to the remote host, with pre set {@link CipherSuite} and {@link PrivilegeLevel}, skipping the + * getAvailableCipherSuites and getChannelAuthenticationCapabilities phases. + * + * @param address + * - {@link InetAddress} of the remote host + * @return handle to the connection to the remote host + * @throws IOException + * when properties file was not found + * @throws FileNotFoundException + * when properties file was not found + */ + public ConnectionHandle createConnection(InetAddress address, CipherSuite cipherSuite, PrivilegeLevel privilegeLevel) + throws IOException { + return createConnection(address, Constants.IPMI_PORT, cipherSuite, privilegeLevel); + } + + /** + * Creates connection to the remote host, with pre set {@link CipherSuite} and {@link PrivilegeLevel}, skipping the + * getAvailableCipherSuites and getChannelAuthenticationCapabilities phases. + * + * @param address + * - {@link InetAddress} of the remote host + * @param port + * - remote UDP port + * @return handle to the connection to the remote host + * @throws IOException + * when properties file was not found + * @throws FileNotFoundException + * when properties file was not found + */ + public ConnectionHandle createConnection( + InetAddress address, + int port, + CipherSuite cipherSuite, + PrivilegeLevel privilegeLevel) + throws IOException { + return asyncConnector.createConnection(address, port, cipherSuite, privilegeLevel); + } + + /** + * Gets {@link CipherSuite}s available for the connection with the remote host. + * + * @param connectionHandle + * {@link ConnectionHandle} to the connection created before + * @see #createConnection(InetAddress) + * @return list of the {@link CipherSuite}s that are allowed during the connection + * @throws Exception + * when sending message to the managed system fails + */ + public List getAvailableCipherSuites(ConnectionHandle connectionHandle) throws Exception { + return asyncConnector.getAvailableCipherSuites(connectionHandle); + } + + /** + * Gets the authentication capabilities for the connection with the remote host. + * + * @param connectionHandle + * - {@link ConnectionHandle} associated with the host + * @param cipherSuite + * - {@link CipherSuite} that will be used during the connection + * @param requestedPrivilegeLevel + * - {@link PrivilegeLevel} that is requested for the session + * @return - {@link GetChannelAuthenticationCapabilitiesResponseData} + * @throws ConnectionException + * when connection is in the state that does not allow to perform this operation. + * @throws Exception + * when sending message to the managed system fails + */ + public GetChannelAuthenticationCapabilitiesResponseData getChannelAuthenticationCapabilities( + ConnectionHandle connectionHandle, + CipherSuite cipherSuite, + PrivilegeLevel requestedPrivilegeLevel) + throws Exception { + return asyncConnector + .getChannelAuthenticationCapabilities( + connectionHandle, + cipherSuite, + requestedPrivilegeLevel); + } + + /** + * Establishes the session with the remote host. + * + * @param connectionHandle + * - {@link ConnectionHandle} associated with the remote host. + * @param username + * - the username + * @param password + * - password matching the username + * @param bmcKey + * - the key that should be provided if the two-key authentication is enabled, null otherwise. + * @return object representing newly created {@link Session} + * @throws ConnectionException + * when connection is in the state that does not allow to perform this operation. + * @throws Exception + * when sending message to the managed system or initializing one of the cipherSuite's algorithms fails + */ + public Session openSession(ConnectionHandle connectionHandle, String username, String password, byte[] bmcKey) + throws Exception { + return asyncConnector.openSession(connectionHandle, username, password, bmcKey); + } + + /** + * Returns session already bound to given connection handle fulfilling given criteria. + * + * @param remoteAddress + * IP addres of the managed system + * @param remotePort + * UDP port of the managed system + * @param user + * IPMI user for whom the connection is established + * @return session object fulfilling given criteria, or null if no session was registered for such connection. + */ + public Session getExistingSessionForCriteria(InetAddress remoteAddress, int remotePort, String user) { + return asyncConnector.getExistingSessionForCriteria(remoteAddress, remotePort, user); + } + + /** + * Closes the session with the remote host if it is currently in open state. + * + * @param connectionHandle + * - {@link ConnectionHandle} associated with the remote host. + * @throws ConnectionException + * when connection is in the state that does not allow to perform this operation. + * @throws Exception + * when sending message to the managed system or initializing one of the cipherSuite's algorithms fails + */ + public void closeSession(ConnectionHandle connectionHandle) throws Exception { + asyncConnector.closeSession(connectionHandle); + } + + /** + * Sends the IPMI message to the remote host. + * + * @param connectionHandle + * - {@link ConnectionHandle} associated with the remote host. + * @param request + * - {@link PayloadCoder} containing the request to be sent + * @return {@link ResponseData} for the request + * @throws ConnectionException + * when connection is in the state that does not allow to perform this operation. + * @throws Exception + * when sending message to the managed system or initializing one of the cipherSuite's algorithms fails + */ + public ResponseData sendMessage(ConnectionHandle connectionHandle, PayloadCoder request) throws Exception { + return sendMessage(connectionHandle, request, true); + } + + /** + * Sends the IPMI message to the remote host and doesn't wait for any response. + * + * @param connectionHandle + * - {@link ConnectionHandle} associated with the remote host. + * @param request + * - {@link PayloadCoder} containing the request to be sent + * @throws ConnectionException + * when connection is in the state that does not allow to perform this operation. + * @throws Exception + * when sending message to the managed system or initializing one of the cipherSuite's algorithms fails + */ + public void sendOneWayMessage(ConnectionHandle connectionHandle, PayloadCoder request) throws Exception { + sendMessage(connectionHandle, request, false); + } + + /** + * Re-sends message with given tag having given {@link PayloadType}, using passed {@link ConnectionHandle}. + * + * @param connectionHandle + * - {@link ConnectionHandle} associated with the remote host. + * @param tag + * - tag of the message to retry + * @param messagePayloadType + * - {@link PayloadType} of the message that should be retried + * @return {@link ResponseData} for the re-sent request or null if message could not be resent. + * @throws Exception + * when sending message to the managed system fails + */ + public ResponseData retryMessage(ConnectionHandle connectionHandle, byte tag, PayloadType messagePayloadType) + throws Exception { + MessageListener listener = new MessageListener(connectionHandle); + asyncConnector.registerListener(listener); + + int retryResult = asyncConnector.retry(connectionHandle, tag, messagePayloadType); + + ResponseData data = retryResult != -1 ? listener.waitForAnswer(tag) : null; + + asyncConnector.unregisterListener(listener); + + return data; + } + + private ResponseData sendMessage(ConnectionHandle connectionHandle, PayloadCoder request, boolean waitForResponse) + throws Exception { + MessageListener listener = new MessageListener(connectionHandle); + + if (waitForResponse) { + asyncConnector.registerListener(listener); + } + + ResponseData data = sendThroughAsyncConnector(request, connectionHandle, listener, waitForResponse); + + if (waitForResponse) { + asyncConnector.unregisterListener(listener); + } + + return data; + } + + private ResponseData sendThroughAsyncConnector( + PayloadCoder request, + ConnectionHandle connectionHandle, + MessageListener listener, + boolean waitForResponse) + throws Exception { + ResponseData responseData = null; + + int tries = 0; + int tag = -1; + boolean messageSent = false; + + while (!messageSent) { + try { + ++tries; + + if (tag >= 0) { + tag = asyncConnector.retry(connectionHandle, tag, request.getSupportedPayloadType()); + } + + if (tag < 0) { + tag = asyncConnector.sendMessage(connectionHandle, request, !waitForResponse); + } + + logger.debug("Sending message with tag {}, try {}", tag, tries); + + if (waitForResponse) { + responseData = listener.waitForAnswer(tag); + } + + messageSent = true; + } catch (IllegalArgumentException e) { + throw e; + } catch (IPMIException e) { + handleErrorResponse(tries, e); + } catch (Exception e) { + handleRetriesWhenException(tries, e); + } + } + + return responseData; + } + + private void handleRetriesWhenException(int tries, Exception e) throws Exception { + if (tries > retries) { + throw e; + } else { + long sleepTime = (random.nextLong() % (idleTime / 2)) + (idleTime / 2); + + Thread.sleep(sleepTime); + logger.warn("Receiving message failed, retrying", e); + } + } + + private void handleErrorResponse(int tries, IPMIException e) throws Exception { + if (e.getCompletionCode() == CompletionCode.InitializationInProgress + || e.getCompletionCode() == CompletionCode.InsufficientResources + || e.getCompletionCode() == CompletionCode.NodeBusy + || e.getCompletionCode() == CompletionCode.Timeout) { + + handleRetriesWhenException(tries, e); + } else { + throw e; + } + } + + /** + * Registers {@link InboundMessageListener} that will react on any request sent from remote system to the application. + * + * @param listener + * listener to be registered. + */ + public void registerIncomingMessageListener(InboundMessageListener listener) { + asyncConnector.registerIncomingPayloadListener(listener); + } + + /** + * Closes the connection with the given handle + */ + public void closeConnection(ConnectionHandle handle) { + asyncConnector.closeConnection(handle); + } + + /** + * Finalizes the connector and closes all connections. + */ + public void tearDown() { + asyncConnector.tearDown(); + } + + /** + * Changes the timeout value for connection with the given handle. + * + * @param handle + * - {@link ConnectionHandle} associated with the remote host. + * @param timeout + * - new timeout value in ms + */ + public void setTimeout(ConnectionHandle handle, int timeout) { + asyncConnector.setTimeout(handle, timeout); + } + + /** + * Returns configured number of retries. + * + * @return number of retries when message could not be sent + */ + public int getRetries() { + return retries; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/api/sync/MessageListener.java b/src/main/java/org/metricshub/ipmi/core/api/sync/MessageListener.java index 530aeaf..7e29ef9 100644 --- a/src/main/java/org/metricshub/ipmi/core/api/sync/MessageListener.java +++ b/src/main/java/org/metricshub/ipmi/core/api/sync/MessageListener.java @@ -42,76 +42,76 @@ */ public class MessageListener implements IpmiResponseListener { - private ConnectionHandle handle; + private ConnectionHandle handle; - private int tag; + private int tag; - private IpmiResponse response; + private IpmiResponse response; - /** - * Messages that have proper connection handle but arrived before tag was - * set - they need to be checked in case expected message arrived very early - * between sending the request and starting waiting for answer (waiting - * cannot be initialized before sending message since tag is not yet known - * then) - */ - private List quickMessages; + /** + * Messages that have proper connection handle but arrived before tag was + * set - they need to be checked in case expected message arrived very early + * between sending the request and starting waiting for answer (waiting + * cannot be initialized before sending message since tag is not yet known + * then) + */ + private List quickMessages; - /** - * Initiates the {@link MessageListener} - * - * @param handle - * - {@link ConnectionHandle} associated with the - * {@link Connection} {@link MessageListener} is expecting - * message from. - */ - public MessageListener(ConnectionHandle handle) { - quickMessages = new ArrayList(); - this.handle = handle; - tag = -1; - response = null; - } + /** + * Initiates the {@link MessageListener} + * + * @param handle + * - {@link ConnectionHandle} associated with the + * {@link Connection} {@link MessageListener} is expecting + * message from. + */ + public MessageListener(ConnectionHandle handle) { + quickMessages = new ArrayList(); + this.handle = handle; + tag = -1; + response = null; + } - /** - * Blocks the invoking thread until deserved message arrives (tag and handle - * as specified in {@link #MessageListener(ConnectionHandle)}). - * - * @param tag - * - tag of the expected message - * @return {@link ResponseData} for message. - * @throws Exception - * when message delivery fails - */ - public ResponseData waitForAnswer(int tag) throws Exception { - if (tag < 0 || tag > 63) { - throw new IllegalArgumentException("Corrupted message tag"); - } - this.tag = tag; - for (IpmiResponse quickResponse : quickMessages) { - this.notify(quickResponse); - } + /** + * Blocks the invoking thread until deserved message arrives (tag and handle + * as specified in {@link #MessageListener(ConnectionHandle)}). + * + * @param messageTag + * - tag of the expected message + * @return {@link ResponseData} for message. + * @throws Exception + * when message delivery fails + */ + public ResponseData waitForAnswer(int messageTag) throws Exception { + if (messageTag < 0 || messageTag > 63) { + throw new IllegalArgumentException("Corrupted message tag"); + } + this.tag = messageTag; + for (IpmiResponse quickResponse : quickMessages) { + this.notify(quickResponse); + } - while (response == null) { - Thread.sleep(1); - } - if (response instanceof IpmiResponseData) { - this.tag = -1; - quickMessages.clear(); - return ((IpmiResponseData) response).getResponseData(); - } else /* response instanceof IpmiError */{ - throw ((IpmiError) response).getException(); - } - } + while (response == null) { + Thread.sleep(1); + } + if (response instanceof IpmiResponseData) { + this.tag = -1; + quickMessages.clear(); + return ((IpmiResponseData) response).getResponseData(); + } else /* response instanceof IpmiError */ { + throw ((IpmiError) response).getException(); + } + } - @Override - public synchronized void notify(IpmiResponse response) { - if (response.getHandle().getHandle() == handle.getHandle()) { - if (tag == -1) { - quickMessages.add(response); - } else if (response.getTag() == tag) { - this.response = response; - } - } - } + @Override + public synchronized void notify(IpmiResponse ipmiResponse) { + if (ipmiResponse.getHandle().getHandle() == handle.getHandle()) { + if (tag == -1) { + quickMessages.add(ipmiResponse); + } else if (ipmiResponse.getTag() == tag) { + this.response = ipmiResponse; + } + } + } } diff --git a/src/main/java/org/metricshub/ipmi/core/api/sync/package-info.java b/src/main/java/org/metricshub/ipmi/core/api/sync/package-info.java index bd7c60a..76cfb64 100644 --- a/src/main/java/org/metricshub/ipmi/core/api/sync/package-info.java +++ b/src/main/java/org/metricshub/ipmi/core/api/sync/package-info.java @@ -1,8 +1,8 @@ /** * The library's API.
- * - * For synchronous API see {@link org.metricshub.ipmi.core.api.sync}, for asynchronous API see {@link org.metricshub.ipmi.core.api.async} - * + * For synchronous API see {@link org.metricshub.ipmi.core.api.sync}, for asynchronous API see + * {@link org.metricshub.ipmi.core.api.async} + * * @see org.metricshub.ipmi.core.api.sync * @see org.metricshub.ipmi.core.api.async */ diff --git a/src/main/java/org/metricshub/ipmi/core/coding/Decoder.java b/src/main/java/org/metricshub/ipmi/core/coding/Decoder.java index 4075557..984fdc9 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/Decoder.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/Decoder.java @@ -39,40 +39,48 @@ */ public final class Decoder { - /** - * Decodes raw data into {@link ResponseData} - a wrapper class for - * message-specific response data. - * - * @param data - * - raw RMCP packet to be decoded - * @param protocolDecoder - * - instance of {@link IpmiDecoder} class for decoding of the - * IPMI session header and (if present) IPMI LAN packet. If IPMI - * LAN packet is present, {@link Protocolv15Decoder} or - * {@link Protocolv20Decoder} should be used (depending on IPMI - * protocol version used). Otherwise, - * {@link PlainCommandv20Decoder} should be used. - * @param payloadCoder - * - instance of {@link PayloadCoder} class used for wrapping - * payload into message-dependent {@link ResponseData} object. - * @return {@link ResponseData} - * @throws IPMIException - * when request to the server fails. - * @see CompletionCode - * @throws IllegalArgumentException - * when data is corrupted - * @throws NoSuchAlgorithmException - * - when authentication, confidentiality or integrity algorithm - * fails. - * @throws InvalidKeyException - * when creating of the authentication algorithm key fails - */ - public static ResponseData decode(byte[] data, IpmiDecoder protocolDecoder, - PayloadCoder payloadCoder) throws IPMIException, NoSuchAlgorithmException, InvalidKeyException { - return payloadCoder.getResponseData(protocolDecoder.decode(RmcpDecoder - .decode(data))); - } + /** + * Decodes raw data into {@link ResponseData} - a wrapper class for + * message-specific response data. + * + * @param data + * - raw RMCP packet to be decoded + * @param protocolDecoder + * - instance of {@link IpmiDecoder} class for decoding of the + * IPMI session header and (if present) IPMI LAN packet. If IPMI + * LAN packet is present, {@link Protocolv15Decoder} or + * {@link Protocolv20Decoder} should be used (depending on IPMI + * protocol version used). Otherwise, + * {@link PlainCommandv20Decoder} should be used. + * @param payloadCoder + * - instance of {@link PayloadCoder} class used for wrapping + * payload into message-dependent {@link ResponseData} object. + * @return {@link ResponseData} + * @throws IPMIException + * when request to the server fails. + * @see CompletionCode + * @throws IllegalArgumentException + * when data is corrupted + * @throws NoSuchAlgorithmException + * - when authentication, confidentiality or integrity algorithm + * fails. + * @throws InvalidKeyException + * when creating of the authentication algorithm key fails + */ + public static ResponseData decode( + byte[] data, + IpmiDecoder protocolDecoder, + PayloadCoder payloadCoder) + throws IPMIException, + NoSuchAlgorithmException, + InvalidKeyException { + return payloadCoder + .getResponseData( + protocolDecoder + .decode( + RmcpDecoder + .decode(data))); + } - private Decoder() { - } + private Decoder() {} } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/DecoderRunner.java b/src/main/java/org/metricshub/ipmi/core/coding/DecoderRunner.java index ca2a89b..3c4f5b1 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/DecoderRunner.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/DecoderRunner.java @@ -100,974 +100,1222 @@ */ public class DecoderRunner extends Thread { - private DatagramSocket socket; + private DatagramSocket socket; - private static int managedSeqNum; - private static boolean lock; + private static int managedSeqNum; + private static boolean lock; - private static Rakp1 r1; - private static Rakp1ResponseData r1rd; - private static CipherSuite cs = new CipherSuite((byte) 0, - SecurityConstants.AA_RAKP_HMAC_SHA1, (byte) 0, (byte) 0); + private static Rakp1 r1; + private static Rakp1ResponseData r1rd; + private static CipherSuite cs = new CipherSuite( + (byte) 0, + SecurityConstants.AA_RAKP_HMAC_SHA1, + (byte) 0, + (byte) 0); - private static Logger logger = LoggerFactory.getLogger(DecoderRunner.class); + private static Logger logger = LoggerFactory.getLogger(DecoderRunner.class); - private static int cssrcv = 16; + private static int cssrcv = 16; - private static int reservation; + private static int reservation; - private static int nextRecId = 0; + private static int nextRecId = 0; - private static byte[] cssrec; + private static byte[] cssrec; - private static int fruId = 0; + private static int fruId = 0; - private static int fruSize = 528; + private static int fruSize = 528; - public static void main(String[] args) throws IOException, InterruptedException, NoSuchAlgorithmException, InvalidKeyException { + public static void main(String[] args) + throws IOException, + InterruptedException, + NoSuchAlgorithmException, + InvalidKeyException { - logger.info(DateFormat.getInstance().format( - new Date(new Date().getTime()))); + logger + .info( + DateFormat + .getInstance() + .format( + new Date(new Date().getTime()))); - lock = true; + lock = true; - DecoderRunner dr = new DecoderRunner(); + DecoderRunner dr = new DecoderRunner(); - dr.socket = new DatagramSocket(6666); + dr.socket = new DatagramSocket(6666); - dr.start(); + dr.start(); - Properties properties = new Properties(); - properties.load(new FileInputStream("src/test/resources/test.properties")); + Properties properties = new Properties(); + properties.load(new FileInputStream("src/test/resources/test.properties")); - Thread.sleep(100); + Thread.sleep(100); - InetAddress ad = InetAddress.getByName((String)properties.get("testIp")); + InetAddress ad = InetAddress.getByName((String) properties.get("testIp")); - byte index = 0; + byte index = 0; - while (cssrcv >= 16) { + while (cssrcv >= 16) { - Thread.sleep(300); + Thread.sleep(300); - lock = true; + lock = true; - byte[] outmsg = Encoder.encode(new Protocolv20Encoder(), - new GetChannelCipherSuites(TypeConverter.intToByte(0xE), - index), 0, 0,0); + byte[] outmsg = Encoder + .encode( + new Protocolv20Encoder(), + new GetChannelCipherSuites( + TypeConverter.intToByte(0xE), + index), + 0, + 0, + 0); - ++index; - DatagramPacket packet = new DatagramPacket(outmsg, outmsg.length, - ad, 0x26F); + ++index; + DatagramPacket packet = new DatagramPacket( + outmsg, + outmsg.length, + ad, + 0x26F); - dr.socket.send(packet); + dr.socket.send(packet); - while (lock) { - Thread.sleep(1); - } - } + while (lock) { + Thread.sleep(1); + } + } - List csl = CipherSuite.getCipherSuites(cssrec); + List csl = CipherSuite.getCipherSuites(cssrec); - for (CipherSuite c : csl) { - try { - logger.info(c.getId() + ": " - + c.getAuthenticationAlgorithm().getCode() + " " - + c.getIntegrityAlgorithm().getCode() + " " - + c.getConfidentialityAlgorithm().getCode()); - } catch (Exception e) { - logger.error(e.getMessage(), e); - } - } + for (CipherSuite c : csl) { + try { + logger + .info( + c.getId() + ": " + + c.getAuthenticationAlgorithm().getCode() + " " + + c.getIntegrityAlgorithm().getCode() + " " + + c.getConfidentialityAlgorithm().getCode()); + } catch (Exception e) { + logger.error(e.getMessage(), e); + } + } - cs = csl.get(2); + cs = csl.get(2); - Thread.sleep(300); + Thread.sleep(300); - byte[] outmsg = Encoder - .encode(new Protocolv15Encoder(), - new GetChannelAuthenticationCapabilities(IpmiVersion.V15, - IpmiVersion.V20, cs, PrivilegeLevel.User, - TypeConverter.intToByte(14)), 0, 0, 0); + byte[] outmsg = Encoder + .encode( + new Protocolv15Encoder(), + new GetChannelAuthenticationCapabilities( + IpmiVersion.V15, + IpmiVersion.V20, + cs, + PrivilegeLevel.User, + TypeConverter.intToByte(14)), + 0, + 0, + 0); - DatagramPacket packet = new DatagramPacket(outmsg, outmsg.length, ad, - 0x26F); + DatagramPacket packet = new DatagramPacket( + outmsg, + outmsg.length, + ad, + 0x26F); + + dr.socket.send(packet); + + Thread.sleep(150); + + outmsg = Encoder + .encode( + new Protocolv20Encoder(), + new OpenSession( + 44, + PrivilegeLevel.MaximumAvailable, + cs), + 0, + 0, + 0); + + packet = new DatagramPacket(outmsg, outmsg.length, ad, 0x26F); + + dr.socket.send(packet); + + Thread.sleep(300); + + while (lock) { + Thread.sleep(1); + } + + lock = true; + + r1 = new Rakp1( + managedSeqNum, + PrivilegeLevel.User, + (String) properties.get("username"), + (String) properties.get("password"), + null, + cs); + + outmsg = Encoder.encode(new Protocolv20Encoder(), r1, 1, 1, 0); + + packet = new DatagramPacket(outmsg, outmsg.length, ad, 0x26F); + + dr.socket.send(packet); + + Thread.sleep(150); + + while (lock) { + Thread.sleep(1); + } + + try { + cs.initializeAlgorithms(r1.calculateSik(r1rd)); + } catch (NoSuchPaddingException e) { + logger.error(e.getMessage(), e); + } + + outmsg = Encoder + .encode( + new Protocolv20Encoder(), + new Rakp3( + (byte) 0, + managedSeqNum, + cs, + r1, + r1rd), + 1, + 1, + 0); + + packet = new DatagramPacket(outmsg, outmsg.length, ad, 0x26F); + + dr.socket.send(packet); + + Thread.sleep(150); + + outmsg = Encoder + .encode( + new Protocolv20Encoder(), + new GetChassisStatus( + IpmiVersion.V20, + cs, + AuthenticationType.RMCPPlus), + 1, + 1, + r1 + .getManagedSystemSessionId()); + + packet = new DatagramPacket(outmsg, outmsg.length, ad, 0x26F); + + dr.socket.send(packet); + + Thread.sleep(300); + + outmsg = Encoder + .encode( + new Protocolv20Encoder(), + new GetSdrRepositoryInfo( + IpmiVersion.V20, + cs, + AuthenticationType.RMCPPlus), + 2, + 2, + r1 + .getManagedSystemSessionId()); - dr.socket.send(packet); + packet = new DatagramPacket(outmsg, outmsg.length, ad, 0x26F); - Thread.sleep(150); + dr.socket.send(packet); + Thread.sleep(300); - outmsg = Encoder.encode(new Protocolv20Encoder(), new OpenSession(44, - PrivilegeLevel.MaximumAvailable, cs), 0, 0, 0); + outmsg = Encoder + .encode( + new Protocolv20Encoder(), + new ReserveSdrRepository( + IpmiVersion.V20, + cs, + AuthenticationType.RMCPPlus), + 3, + 3, + r1 + .getManagedSystemSessionId()); - packet = new DatagramPacket(outmsg, outmsg.length, ad, 0x26F); + packet = new DatagramPacket(outmsg, outmsg.length, ad, 0x26F); - dr.socket.send(packet); + dr.socket.send(packet); - Thread.sleep(300); + int seq = 4; - while (lock) { - Thread.sleep(1); - } + lock = true; - lock = true; + while (lock) { + Thread.sleep(1); + } + while (nextRecId < 65535) { - r1 = new Rakp1(managedSeqNum, PrivilegeLevel.User, (String)properties.get("username"), (String)properties.get("password"), - null, cs); + Thread.sleep(200); - outmsg = Encoder.encode(new Protocolv20Encoder(), r1, 1, 1,0); + logger.info(">>Sending request for record " + nextRecId); - packet = new DatagramPacket(outmsg, outmsg.length, ad, 0x26F); + int sequence = seq++; - dr.socket.send(packet); + outmsg = Encoder + .encode( + new Protocolv20Encoder(), + new GetSdr( + IpmiVersion.V20, + cs, + AuthenticationType.RMCPPlus, + reservation, + nextRecId), + sequence, + sequence, + r1 + .getManagedSystemSessionId()); - Thread.sleep(150); + packet = new DatagramPacket(outmsg, outmsg.length, ad, 0x26F); - while (lock) { - Thread.sleep(1); - } + dr.socket.send(packet); + lock = true; - try { - cs.initializeAlgorithms(r1.calculateSik(r1rd)); - } catch (NoSuchPaddingException e) { - logger.error(e.getMessage(), e); - } + while (lock) { + Thread.sleep(1); + } - outmsg = Encoder.encode(new Protocolv20Encoder(), new Rakp3((byte) 0, - managedSeqNum, cs, r1, r1rd), 1, 1, 0); + if (nextRecId > 0) { + logger.info(">>Sending request for reading " + nextRecId); - packet = new DatagramPacket(outmsg, outmsg.length, ad, 0x26F); + sequence = seq++; - dr.socket.send(packet); + outmsg = Encoder + .encode( + new Protocolv20Encoder(), + new GetSensorReading( + IpmiVersion.V20, + cs, + AuthenticationType.RMCPPlus, + nextRecId), + sequence, + sequence, + r1.getManagedSystemSessionId()); - Thread.sleep(150); + packet = new DatagramPacket(outmsg, outmsg.length, ad, 0x26F); - outmsg = Encoder.encode(new Protocolv20Encoder(), new GetChassisStatus( - IpmiVersion.V20, cs, AuthenticationType.RMCPPlus), 1, 1, r1 - .getManagedSystemSessionId()); + dr.socket.send(packet); - packet = new DatagramPacket(outmsg, outmsg.length, ad, 0x26F); + lock = true; - dr.socket.send(packet); + while (lock && nextRecId < 65535) { + Thread.sleep(1); + } + } - Thread.sleep(300); + } - outmsg = Encoder.encode(new Protocolv20Encoder(), - new GetSdrRepositoryInfo(IpmiVersion.V20, cs, - AuthenticationType.RMCPPlus), 2, 2, r1 - .getManagedSystemSessionId()); + nextRecId = 0; - packet = new DatagramPacket(outmsg, outmsg.length, ad, 0x26F); + Thread.sleep(300); - dr.socket.send(packet); - Thread.sleep(300); + logger.info(">>Sending GetSelInfo"); - outmsg = Encoder.encode(new Protocolv20Encoder(), - new ReserveSdrRepository(IpmiVersion.V20, cs, - AuthenticationType.RMCPPlus), 3, 3, r1 - .getManagedSystemSessionId()); + int sequence = seq++; - packet = new DatagramPacket(outmsg, outmsg.length, ad, 0x26F); + outmsg = Encoder + .encode( + new Protocolv20Encoder(), + new GetSelInfo( + IpmiVersion.V20, + cs, + AuthenticationType.RMCPPlus), + sequence, + sequence, + r1 + .getManagedSystemSessionId()); - dr.socket.send(packet); + packet = new DatagramPacket(outmsg, outmsg.length, ad, 0x26F); - int seq = 4; + dr.socket.send(packet); - lock = true; + Thread.sleep(300); - while (lock) { - Thread.sleep(1); - } + logger.info(">>Sending Reserve SEL"); - while (nextRecId < 65535) { + sequence = seq++; - Thread.sleep(200); + outmsg = Encoder + .encode( + new Protocolv20Encoder(), + new ReserveSel( + IpmiVersion.V20, + cs, + AuthenticationType.RMCPPlus), + sequence, + sequence, + r1 + .getManagedSystemSessionId()); - logger.info(">>Sending request for record " + nextRecId); + packet = new DatagramPacket(outmsg, outmsg.length, ad, 0x26F); - int sequence = seq++; + dr.socket.send(packet); - outmsg = Encoder.encode(new Protocolv20Encoder(), new GetSdr( - IpmiVersion.V20, cs, AuthenticationType.RMCPPlus, - reservation, nextRecId), sequence, sequence, r1 - .getManagedSystemSessionId()); + lock = true; - packet = new DatagramPacket(outmsg, outmsg.length, ad, 0x26F); + while (lock) { + Thread.sleep(1); + } - dr.socket.send(packet); - lock = true; + while (nextRecId < 65535) { - while (lock) { - Thread.sleep(1); - } + Thread.sleep(200); - if (nextRecId > 0) { - logger.info(">>Sending request for reading " + nextRecId); + logger.info(">>Sending request for SEL record " + nextRecId); - sequence = seq++; + sequence = seq++; - outmsg = Encoder.encode(new Protocolv20Encoder(), - new GetSensorReading(IpmiVersion.V20, cs, - AuthenticationType.RMCPPlus, nextRecId), sequence, sequence, - r1.getManagedSystemSessionId()); + outmsg = Encoder + .encode( + new Protocolv20Encoder(), + new GetSelEntry( + IpmiVersion.V20, + cs, + AuthenticationType.RMCPPlus, + reservation, + nextRecId), + sequence, + sequence, + r1 + .getManagedSystemSessionId()); - packet = new DatagramPacket(outmsg, outmsg.length, ad, 0x26F); + packet = new DatagramPacket(outmsg, outmsg.length, ad, 0x26F); - dr.socket.send(packet); + dr.socket.send(packet); + lock = true; - lock = true; + while (lock) { + Thread.sleep(1); + } + } - while (lock && nextRecId < 65535) { - Thread.sleep(1); - } - } + Thread.sleep(300); - } + logger.info(">>Sending GetFruInventoryAreaInfo"); - nextRecId = 0; + sequence = seq++; - Thread.sleep(300); + outmsg = Encoder + .encode( + new Protocolv20Encoder(), + new GetFruInventoryAreaInfo( + IpmiVersion.V20, + cs, + AuthenticationType.RMCPPlus, + fruId), + sequence, + sequence, + r1 + .getManagedSystemSessionId()); - logger.info(">>Sending GetSelInfo"); + packet = new DatagramPacket(outmsg, outmsg.length, ad, 0x26F); - int sequence = seq++; + dr.socket.send(packet); - outmsg = Encoder.encode(new Protocolv20Encoder(), new GetSelInfo( - IpmiVersion.V20, cs, AuthenticationType.RMCPPlus), sequence, sequence, r1 - .getManagedSystemSessionId()); + for (int i = 0; i < fruSize; i += 100) { - packet = new DatagramPacket(outmsg, outmsg.length, ad, 0x26F); + Thread.sleep(300); - dr.socket.send(packet); + logger.info(">>Sending ReadFruData"); - Thread.sleep(300); + int cnt = 100; + if (i + cnt > fruSize) { + cnt = fruSize % 100; + } - logger.info(">>Sending Reserve SEL"); + sequence = seq++; - sequence = seq++; + outmsg = Encoder + .encode( + new Protocolv20Encoder(), + new ReadFruData( + IpmiVersion.V20, + cs, + AuthenticationType.RMCPPlus, + fruId, + BaseUnit.Bytes, + i, + cnt), + sequence, + sequence, + r1 + .getManagedSystemSessionId()); - outmsg = Encoder.encode(new Protocolv20Encoder(), new ReserveSel( - IpmiVersion.V20, cs, AuthenticationType.RMCPPlus), sequence, sequence, r1 - .getManagedSystemSessionId()); + packet = new DatagramPacket(outmsg, outmsg.length, ad, 0x26F); - packet = new DatagramPacket(outmsg, outmsg.length, ad, 0x26F); + dr.socket.send(packet); - dr.socket.send(packet); + } - lock = true; + Thread.sleep(300); - while (lock) { - Thread.sleep(1); - } + sequence = seq + 1; - while (nextRecId < 65535) { - - Thread.sleep(200); - - logger.info(">>Sending request for SEL record " + nextRecId); - - sequence = seq++; - - outmsg = Encoder.encode(new Protocolv20Encoder(), new GetSelEntry( - IpmiVersion.V20, cs, AuthenticationType.RMCPPlus, - reservation, nextRecId), sequence, sequence, r1 - .getManagedSystemSessionId()); - - packet = new DatagramPacket(outmsg, outmsg.length, ad, 0x26F); - - dr.socket.send(packet); - lock = true; - - while (lock) { - Thread.sleep(1); - } - } - - Thread.sleep(300); - - logger.info(">>Sending GetFruInventoryAreaInfo"); - - sequence = seq++; - - outmsg = Encoder.encode(new Protocolv20Encoder(), - new GetFruInventoryAreaInfo(IpmiVersion.V20, cs, - AuthenticationType.RMCPPlus, fruId), sequence, sequence, r1 - .getManagedSystemSessionId()); - - packet = new DatagramPacket(outmsg, outmsg.length, ad, 0x26F); - - dr.socket.send(packet); - - for(int i = 0; i < fruSize; i += 100) { - - - Thread.sleep(300); - - logger.info(">>Sending ReadFruData"); - - int cnt = 100; - if(i + cnt > fruSize) { - cnt = fruSize % 100; - } - - sequence = seq++; - - outmsg = Encoder.encode(new Protocolv20Encoder(), - new ReadFruData(IpmiVersion.V20, cs, - AuthenticationType.RMCPPlus, fruId, BaseUnit.Bytes, i, cnt), sequence, sequence, r1 - .getManagedSystemSessionId()); - - packet = new DatagramPacket(outmsg, outmsg.length, ad, 0x26F); - - dr.socket.send(packet); - - } - - Thread.sleep(300); - - sequence = seq + 1; - - outmsg = Encoder.encode( - new Protocolv20Encoder(), - new CloseSession(IpmiVersion.V20, cs, - AuthenticationType.RMCPPlus, r1 - .getManagedSystemSessionId()), sequence, sequence, r1 - .getManagedSystemSessionId()); - - packet = new DatagramPacket(outmsg, outmsg.length, ad, 0x26F); - - dr.socket.send(packet); - - Thread.sleep(1000); - - dr.socket.close(); - - } - - @Override - public void run() { - - super.run(); - - cssrec = new byte[0]; - - byte[] buffer = null; - - while (cssrcv >= 16) { - DatagramPacket resp = new DatagramPacket(new byte[256], 256); - - try { - socket.receive(resp); - buffer = new byte[resp.getLength()]; - System.arraycopy(resp.getData(), 0, buffer, 0, buffer.length); - } catch (IOException e) { - logger.error(e.getMessage(), e); - } - - GetChannelCipherSuitesResponseData data = null; - - try { - data = (GetChannelCipherSuitesResponseData) Decoder.decode( - buffer, new Protocolv20Decoder(CipherSuite.getEmpty()), - new GetChannelCipherSuites()); - } catch (Exception e) { - logger.error(e.getMessage(), e); - } - - if (data != null && data.getCipherSuiteData() != null) { - cssrcv = data.getCipherSuiteData().length; - - logger.info("{}", data.getCipherSuiteData().length); - - byte[] temp = new byte[cssrec.length + cssrcv]; - - System.arraycopy(cssrec, 0, temp, 0, cssrec.length); - System.arraycopy(data.getCipherSuiteData(), 0, temp, - cssrec.length, cssrcv); - cssrec = temp; - - } else { - cssrcv = 0; - logger.info("{}", 0); - } - - lock = false; - } - - DatagramPacket resp = new DatagramPacket(new byte[256], 256); - - try { - socket.receive(resp); - buffer = new byte[resp.getLength()]; - System.arraycopy(resp.getData(), 0, buffer, 0, buffer.length); - } catch (IOException e) { - logger.error(e.getMessage(), e); - } - - GetChannelAuthenticationCapabilitiesResponseData data = null; - - try { - data = (GetChannelAuthenticationCapabilitiesResponseData) Decoder - .decode(buffer, new Protocolv15Decoder(), - new GetChannelAuthenticationCapabilities( - IpmiVersion.V15, IpmiVersion.V20, cs)); - } catch (Exception e) { - logger.error(e.getMessage(), e); - } - - logger.info("---------------------------------------------"); - - logger.info("{}", data.getChannelNumber()); - logger.info("{}", data.isIpmiv20Support()); - logger.info("{}", data.getAuthenticationTypes().toString()); - logger.info("{}", data.isKgEnabled()); - logger.info("{}", data.isPerMessageAuthenticationEnabled()); - logger.info("{}", data.isUserLevelAuthenticationEnabled()); - logger.info("{}", data.isNonNullUsernamesEnabled()); - logger.info("{}", data.isNullUsernamesEnabled()); - logger.info("{}", data.isAnonymusLoginEnabled()); - logger.info("{}", data.getOemId()); - logger.info("{}", data.getOemData()); - - logger.info("##############################################"); - - resp = new DatagramPacket(new byte[256], 256); - - try { - socket.receive(resp); - buffer = new byte[resp.getLength()]; - System.arraycopy(resp.getData(), 0, buffer, 0, buffer.length); - logger.info(">>>> " + resp.getLength()); - } catch (IOException e) { - logger.error(e.getMessage(), e); - } - - OpenSessionResponseData data2 = null; - - try { - data2 = (OpenSessionResponseData) Decoder.decode(buffer, - new PlainCommandv20Decoder(CipherSuite.getEmpty()), - new OpenSession(CipherSuite.getEmpty())); - } catch (Exception e) { - logger.error(e.getMessage(), e); - } - - logger.info("{}", data2.getMessageTag()); - logger.info("{}", data2.getStatusCode()); - logger.info("{}", data2.getPrivilegeLevel()); - logger.info("{}", data2.getRemoteConsoleSessionId()); - logger.info("{}", data2.getManagedSystemSessionId()); - logger.info("{}", data2.getAuthenticationAlgorithm()); - logger.info("{}", data2.getConfidentialityAlgorithm()); - logger.info("{}", data2.getIntegrityAlgorithm()); - - managedSeqNum = data2.getManagedSystemSessionId(); - lock = false; - - logger.info("---------------------------------------------"); - - resp = new DatagramPacket(new byte[256], 256); - - try { - socket.receive(resp); - buffer = new byte[resp.getLength()]; - System.arraycopy(resp.getData(), 0, buffer, 0, buffer.length); - } catch (IOException e) { - logger.error(e.getMessage(), e); - } - - Rakp1ResponseData data3 = null; - - try { - data3 = (Rakp1ResponseData) Decoder.decode(buffer, - new PlainCommandv20Decoder(CipherSuite.getEmpty()), r1); - } catch (Exception e) { - logger.error(e.getMessage(), e); - } - - r1rd = data3; - - logger.info("{}", data3.getMessageTag()); - logger.info("{}", data3.getStatusCode()); - logger.info("{}", data3.getRemoteConsoleSessionId()); - logger.info("{}", data3.getManagedSystemGuid()); - - logger.info("---------------------------------------------"); - lock = false; - - resp = new DatagramPacket(new byte[256], 256); - - try { - socket.receive(resp); - buffer = new byte[resp.getLength()]; - System.arraycopy(resp.getData(), 0, buffer, 0, buffer.length); - } catch (IOException e) { - logger.error(e.getMessage(), e); - } - - Rakp3ResponseData data4 = null; - - try { - data4 = (Rakp3ResponseData) Decoder.decode(buffer, - new PlainCommandv20Decoder(CipherSuite.getEmpty()), - new Rakp3(cs, r1, r1rd)); - } catch (Exception e) { - logger.error(e.getMessage(), e); - } - - logger.info("{}", data4.getMessageTag()); - logger.info("{}", data4.getStatusCode()); - logger.info("{}", data4.getConsoleSessionId()); - - logger.info("---------------------------------------------"); - - resp = new DatagramPacket(new byte[256], 256); - - try { - socket.receive(resp); - buffer = new byte[resp.getLength()]; - System.arraycopy(resp.getData(), 0, buffer, 0, buffer.length); - } catch (IOException e) { - logger.error(e.getMessage(), e); - } - - GetChassisStatusResponseData data5 = null; - - try { - data5 = (GetChassisStatusResponseData) Decoder.decode(buffer, - new Protocolv20Decoder(cs), new GetChassisStatus( - IpmiVersion.V20, cs, AuthenticationType.RMCPPlus)); - } catch (Exception e) { - logger.error(e.getMessage(), e); - } - - logger.info("{}", data5.getPowerRestorePolicy()); - logger.info("{}", data5.isPowerControlFault()); - logger.info("{}", data5.isPowerFault()); - logger.info("{}", data5.isInterlock()); - logger.info("{}", data5.isPowerOverload()); - logger.info("{}", data5.isPowerOn()); - - logger.info("________"); - - logger.info("{}", data5.wasIpmiPowerOn()); - logger.info("{}", data5.wasPowerFault()); - logger.info("{}", data5.wasInterlock()); - logger.info("{}", data5.wasPowerOverload()); - - logger.info("________"); - - logger.info("{}", data5.isChassisIdentifyCommandSupported()); - if (data5.isChassisIdentifyCommandSupported()) { - logger.info("{}", data5.getChassisIdentifyState()); - } - logger.info("{}", data5.coolingFaultDetected()); - logger.info("{}", data5.driveFaultDetected()); - logger.info("{}", data5.isFrontPanelLockoutActive()); - logger.info("{}", data5.isChassisIntrusionActive()); - - logger.info("________"); - - logger.info("{}", data5.isFrontPanelButtonCapabilitiesSet()); - - if (data5.isFrontPanelButtonCapabilitiesSet()) { - try { - logger.info("{}", data5.isStandbyButtonDisableAllowed()); - logger.info("{}", data5 - .isDiagnosticInterruptButtonDisableAllowed()); - logger.info("{}", data5.isResetButtonDisableAllowed()); - logger.info("{}", data5.isPowerOffButtonDisableAllowed()); - logger.info("{}", data5.isStandbyButtonDisabled()); - logger.info("{}", data5.isDiagnosticInterruptButtonDisabled()); - logger.info("{}", data5.isResetButtonDisabled()); - logger.info("{}", data5.isPowerOffButtonDisabled()); - } catch (IllegalAccessException e) { - logger.error(e.getMessage(), e); - } - - } - - logger.info("---------------------------------------------"); - - resp = new DatagramPacket(new byte[256], 256); - - try { - socket.receive(resp); - buffer = new byte[resp.getLength()]; - System.arraycopy(resp.getData(), 0, buffer, 0, buffer.length); - } catch (IOException e) { - logger.error(e.getMessage(), e); - } - - GetSdrRepositoryInfoResponseData data6 = null; - - try { - data6 = (GetSdrRepositoryInfoResponseData) Decoder.decode(buffer, - new Protocolv20Decoder(cs), new GetSdrRepositoryInfo( - IpmiVersion.V20, cs, AuthenticationType.RMCPPlus)); - } catch (Exception e) { - logger.error(e.getMessage(), e); - } - - logger.info("{}", data6.getSdrVersion()); - logger.info("{}", data6.getRecordCount()); - logger.info("{}", data6.getAddTimestamp()); - logger.info("{}", data6.getDelTimestamp()); - logger.info("{}", data6.isReserveSupported()); - - logger.info("---------------------------------------------"); - - resp = new DatagramPacket(new byte[256], 256); - - try { - socket.receive(resp); - buffer = new byte[resp.getLength()]; - System.arraycopy(resp.getData(), 0, buffer, 0, buffer.length); - } catch (IOException e) { - logger.error(e.getMessage(), e); - } - - ReserveSdrRepositoryResponseData data7 = null; - - try { - data7 = (ReserveSdrRepositoryResponseData) Decoder.decode(buffer, - new Protocolv20Decoder(cs), new ReserveSdrRepository( - IpmiVersion.V20, cs, AuthenticationType.RMCPPlus)); - } catch (Exception e) { - logger.error(e.getMessage(), e); - } - - logger.info("{}", data7.getReservationId()); - - reservation = data7.getReservationId(); - - logger.info("< 0) { - resp = new DatagramPacket(new byte[256], 256); - - try { - socket.receive(resp); - buffer = new byte[resp.getLength()]; - System.arraycopy(resp.getData(), 0, buffer, 0, - buffer.length); - } catch (IOException e) { - logger.error(e.getMessage(), e); - } - GetSensorReadingResponseData data9 = null; - - try { - data9 = (GetSensorReadingResponseData) Decoder.decode( - buffer, new Protocolv20Decoder(cs), - new GetSensorReading(IpmiVersion.V20, cs, AuthenticationType.RMCPPlus, 0)); - - if (record instanceof FullSensorRecord) { - FullSensorRecord rec = (FullSensorRecord) record; - logger.info(data9.getSensorReading(rec) - + " " - + rec.getSensorBaseUnit().toString() - + (rec.getRateUnit() != RateUnit.None ? " per " - + rec.getRateUnit() : "")); - } - if (record instanceof CompactSensorRecord) { - CompactSensorRecord rec = (CompactSensorRecord) record; - List events = data9.getStatesAsserted( - rec.getSensorType(), rec.getEventReadingType()); - StringBuilder s = new StringBuilder(); - for (int i = 0; i < events.size(); ++i) { - s.append(events.get(i)).append(", "); - } - logger.info(s.toString()); - - } - } catch (Exception e) { - logger.error(e.getMessage(), e); - } - } - - try { - Thread.sleep(100); - } catch (InterruptedException e) { - logger.error(e.getMessage(), e); - } - - nextRecId = data8.getNextRecordId(); - - logger.info("---------------------------------------------"); - - lock = false; - } - - resp = new DatagramPacket(new byte[256], 256); - - try { - socket.receive(resp); - buffer = new byte[resp.getLength()]; - System.arraycopy(resp.getData(), 0, buffer, 0, buffer.length); - } catch (IOException e) { - logger.error(e.getMessage(), e); - } - - GetSelInfoResponseData data10 = null; - - try { - data10 = (GetSelInfoResponseData) Decoder.decode(buffer, - new Protocolv20Decoder(cs), new GetSelInfo(IpmiVersion.V20, - cs, AuthenticationType.RMCPPlus)); - } catch (Exception e) { - logger.error(e.getMessage(), e); - } - - logger.info("{}", data10.getSelVersion()); - logger.info("{}", data10.getEntriesCount()); - logger.info(DateFormat.getInstance().format( - data10.getAdditionTimestamp())); - logger.info(DateFormat.getInstance().format( - data10.getEraseTimestamp())); - - logger.info("---------------------------------------------"); - - resp = new DatagramPacket(new byte[256], 256); - - try { - socket.receive(resp); - buffer = new byte[resp.getLength()]; - System.arraycopy(resp.getData(), 0, buffer, 0, buffer.length); - } catch (IOException e) { - logger.error(e.getMessage(), e); - } - - ReserveSelResponseData data11 = null; - - try { - data11 = (ReserveSelResponseData) Decoder.decode(buffer, - new Protocolv20Decoder(cs), new ReserveSel(IpmiVersion.V20, - cs, AuthenticationType.RMCPPlus)); - } catch (Exception e) { - logger.error(e.getMessage(), e); - } - - logger.info("{}", data11.getReservationId()); - - reservation = data11.getReservationId(); - reservation = 0; - - lock = false; - - logger.info("---------------------------------------------"); - - while (nextRecId < 65535) { - - resp = new DatagramPacket(new byte[256], 256); - - try { - socket.receive(resp); - buffer = new byte[resp.getLength()]; - System.arraycopy(resp.getData(), 0, buffer, 0, buffer.length); - } catch (IOException e) { - logger.error(e.getMessage(), e); - } - GetSelEntryResponseData data12 = null; - - try { - data12 = (GetSelEntryResponseData) Decoder.decode(buffer, - new Protocolv20Decoder(cs), new GetSelEntry( - IpmiVersion.V20, cs, AuthenticationType.RMCPPlus, 0, 0)); - } catch (Exception e) { - logger.error(e.getMessage(), e); - } - - logger.info(data12.getSelRecord().toString()); - - SelRecord rec = data12.getSelRecord(); - - logger.info("Sensor: " + rec.getSensorType()); - logger.info("{}", rec.getTimestamp()); - logger.info("{}", rec.getEventDirection()); - logger.info("{}", rec.getEvent()); - - nextRecId = data12.getNextRecordId(); - - lock = false; - - logger.info("---------------------------------------------"); - } - - resp = new DatagramPacket(new byte[256], 256); - - try { - socket.receive(resp); - buffer = new byte[resp.getLength()]; - System.arraycopy(resp.getData(), 0, buffer, 0, buffer.length); - } catch (IOException e) { - logger.error(e.getMessage(), e); - } - - GetFruInventoryAreaInfoResponseData data13 = null; - - try { - data13 = (GetFruInventoryAreaInfoResponseData) Decoder.decode( - buffer, new Protocolv20Decoder(cs), - new GetFruInventoryAreaInfo(IpmiVersion.V20, cs, AuthenticationType.RMCPPlus, 0)); - } catch (Exception e) { - logger.error(e.getMessage(), e); - } - - logger.info("FRU inventory area size: " - + data13.getFruInventoryAreaSize()); - - logger.info("FRU Unit: " + data13.getFruUnit()); - - logger.info("---------------------------------------------"); - - List rd = new ArrayList(); - - for(int i = 0; i < fruSize; i += 100) { - resp = new DatagramPacket(new byte[256], 256); - - try { - socket.receive(resp); - buffer = new byte[resp.getLength()]; - System.arraycopy(resp.getData(), 0, buffer, 0, buffer.length); - } catch (IOException e) { - logger.error(e.getMessage(), e); - } - - ReadFruDataResponseData data14 = null; - - try { - data14 = (ReadFruDataResponseData) Decoder.decode(buffer, - new Protocolv20Decoder(cs), new ReadFruData(IpmiVersion.V20, - cs, AuthenticationType.RMCPPlus, 0, BaseUnit.Bytes, 0, 0)); - } catch (Exception e) { - logger.error(e.getMessage(), e); - } - - rd.add(data14); - - logger.info("{}", data14.getFruData().length); - - logger.info("---------------------------------------------"); - - } - - List records = ReadFruData.decodeFruData(rd); - - for(FruRecord r : records) { - if(r instanceof ChassisInfo) { - ChassisInfo chassisInfo = (ChassisInfo) r; - logger.info("Chassis info:"); - logger.info("Chassis type: " + chassisInfo.getChassisType()); - logger.info("Chassis part number: " + chassisInfo.getChassisPartNumber()); - logger.info("Chassis serial number: " + chassisInfo.getChassisSerialNumber()); - for(String info : chassisInfo.getCustomChassisInfo()) { - logger.info("Custom chassis info: " + info); - } - logger.info("---------------------------------------------"); - } else if(r instanceof BoardInfo) { - BoardInfo boardInfo = (BoardInfo) r; - logger.info("Board info:"); - logger.info("Board MFG date: " + boardInfo.getMfgDate().toString()); - logger.info("Board manufacturer: " + boardInfo.getBoardManufacturer()); - logger.info("Board product name: " + boardInfo.getBoardProductName()); - logger.info("Board part number: " + boardInfo.getBoardPartNumber()); - logger.info("Board serial number: " + boardInfo.getBoardSerialNumber()); - for(String info : boardInfo.getCustomBoardInfo()) { - logger.info("Custom board info: " + info); - } - logger.info("---------------------------------------------"); - } else if(r instanceof ProductInfo) { - ProductInfo productInfo = (ProductInfo) r; - logger.info("Product info:"); - logger.info("Product manufacturer: " + productInfo.getManufacturerName()); - logger.info("Product product name: " + productInfo.getProductName()); - logger.info("Product part number: " + productInfo.getProductModelNumber()); - logger.info("Product version: " + productInfo.getProductVersion()); - logger.info("Product serial number: " + productInfo.getProductSerialNumber()); - logger.info("Product asset tag: " + productInfo.getAssetTag()); - for(String info : productInfo.getCustomProductInfo()) { - logger.info("Custom board info: " + info); - } - logger.info("---------------------------------------------"); - } - } - } + outmsg = Encoder + .encode( + new Protocolv20Encoder(), + new CloseSession( + IpmiVersion.V20, + cs, + AuthenticationType.RMCPPlus, + r1 + .getManagedSystemSessionId()), + sequence, + sequence, + r1 + .getManagedSystemSessionId()); + + packet = new DatagramPacket(outmsg, outmsg.length, ad, 0x26F); + + dr.socket.send(packet); + + Thread.sleep(1000); + + dr.socket.close(); + + } + + @Override + public void run() { + + super.run(); + + cssrec = new byte[0]; + + byte[] buffer = null; + + while (cssrcv >= 16) { + DatagramPacket resp = new DatagramPacket(new byte[256], 256); + + try { + socket.receive(resp); + buffer = new byte[resp.getLength()]; + System.arraycopy(resp.getData(), 0, buffer, 0, buffer.length); + } catch (IOException e) { + logger.error(e.getMessage(), e); + } + + GetChannelCipherSuitesResponseData data = null; + + try { + data = (GetChannelCipherSuitesResponseData) Decoder + .decode( + buffer, + new Protocolv20Decoder(CipherSuite.getEmpty()), + new GetChannelCipherSuites()); + } catch (Exception e) { + logger.error(e.getMessage(), e); + } + + if (data != null && data.getCipherSuiteData() != null) { + cssrcv = data.getCipherSuiteData().length; + + logger.info("{}", data.getCipherSuiteData().length); + + byte[] temp = new byte[cssrec.length + cssrcv]; + + System.arraycopy(cssrec, 0, temp, 0, cssrec.length); + System + .arraycopy( + data.getCipherSuiteData(), + 0, + temp, + cssrec.length, + cssrcv); + cssrec = temp; + + } else { + cssrcv = 0; + logger.info("{}", 0); + } + + lock = false; + } + + DatagramPacket resp = new DatagramPacket(new byte[256], 256); + + try { + socket.receive(resp); + buffer = new byte[resp.getLength()]; + System.arraycopy(resp.getData(), 0, buffer, 0, buffer.length); + } catch (IOException e) { + logger.error(e.getMessage(), e); + } + + GetChannelAuthenticationCapabilitiesResponseData data = null; + + try { + data = (GetChannelAuthenticationCapabilitiesResponseData) Decoder + .decode( + buffer, + new Protocolv15Decoder(), + new GetChannelAuthenticationCapabilities( + IpmiVersion.V15, + IpmiVersion.V20, + cs)); + } catch (Exception e) { + logger.error(e.getMessage(), e); + } + + logger.info("---------------------------------------------"); + + logger.info("{}", data.getChannelNumber()); + logger.info("{}", data.isIpmiv20Support()); + logger.info("{}", data.getAuthenticationTypes().toString()); + logger.info("{}", data.isKgEnabled()); + logger.info("{}", data.isPerMessageAuthenticationEnabled()); + logger.info("{}", data.isUserLevelAuthenticationEnabled()); + logger.info("{}", data.isNonNullUsernamesEnabled()); + logger.info("{}", data.isNullUsernamesEnabled()); + logger.info("{}", data.isAnonymusLoginEnabled()); + logger.info("{}", data.getOemId()); + logger.info("{}", data.getOemData()); + + logger.info("##############################################"); + + resp = new DatagramPacket(new byte[256], 256); + + try { + socket.receive(resp); + buffer = new byte[resp.getLength()]; + System.arraycopy(resp.getData(), 0, buffer, 0, buffer.length); + logger.info(">>>> " + resp.getLength()); + } catch (IOException e) { + logger.error(e.getMessage(), e); + } + + OpenSessionResponseData data2 = null; + + try { + data2 = (OpenSessionResponseData) Decoder + .decode( + buffer, + new PlainCommandv20Decoder(CipherSuite.getEmpty()), + new OpenSession(CipherSuite.getEmpty())); + } catch (Exception e) { + logger.error(e.getMessage(), e); + } + + logger.info("{}", data2.getMessageTag()); + logger.info("{}", data2.getStatusCode()); + logger.info("{}", data2.getPrivilegeLevel()); + logger.info("{}", data2.getRemoteConsoleSessionId()); + logger.info("{}", data2.getManagedSystemSessionId()); + logger.info("{}", data2.getAuthenticationAlgorithm()); + logger.info("{}", data2.getConfidentialityAlgorithm()); + logger.info("{}", data2.getIntegrityAlgorithm()); + + managedSeqNum = data2.getManagedSystemSessionId(); + lock = false; + + logger.info("---------------------------------------------"); + + resp = new DatagramPacket(new byte[256], 256); + + try { + socket.receive(resp); + buffer = new byte[resp.getLength()]; + System.arraycopy(resp.getData(), 0, buffer, 0, buffer.length); + } catch (IOException e) { + logger.error(e.getMessage(), e); + } + + Rakp1ResponseData data3 = null; + + try { + data3 = (Rakp1ResponseData) Decoder + .decode( + buffer, + new PlainCommandv20Decoder(CipherSuite.getEmpty()), + r1); + } catch (Exception e) { + logger.error(e.getMessage(), e); + } + + r1rd = data3; + + logger.info("{}", data3.getMessageTag()); + logger.info("{}", data3.getStatusCode()); + logger.info("{}", data3.getRemoteConsoleSessionId()); + logger.info("{}", data3.getManagedSystemGuid()); + + logger.info("---------------------------------------------"); + lock = false; + + resp = new DatagramPacket(new byte[256], 256); + + try { + socket.receive(resp); + buffer = new byte[resp.getLength()]; + System.arraycopy(resp.getData(), 0, buffer, 0, buffer.length); + } catch (IOException e) { + logger.error(e.getMessage(), e); + } + + Rakp3ResponseData data4 = null; + + try { + data4 = (Rakp3ResponseData) Decoder + .decode( + buffer, + new PlainCommandv20Decoder(CipherSuite.getEmpty()), + new Rakp3(cs, r1, r1rd)); + } catch (Exception e) { + logger.error(e.getMessage(), e); + } + + logger.info("{}", data4.getMessageTag()); + logger.info("{}", data4.getStatusCode()); + logger.info("{}", data4.getConsoleSessionId()); + + logger.info("---------------------------------------------"); + + resp = new DatagramPacket(new byte[256], 256); + + try { + socket.receive(resp); + buffer = new byte[resp.getLength()]; + System.arraycopy(resp.getData(), 0, buffer, 0, buffer.length); + } catch (IOException e) { + logger.error(e.getMessage(), e); + } + + GetChassisStatusResponseData data5 = null; + + try { + data5 = (GetChassisStatusResponseData) Decoder + .decode( + buffer, + new Protocolv20Decoder(cs), + new GetChassisStatus( + IpmiVersion.V20, + cs, + AuthenticationType.RMCPPlus)); + } catch (Exception e) { + logger.error(e.getMessage(), e); + } + + logger.info("{}", data5.getPowerRestorePolicy()); + logger.info("{}", data5.isPowerControlFault()); + logger.info("{}", data5.isPowerFault()); + logger.info("{}", data5.isInterlock()); + logger.info("{}", data5.isPowerOverload()); + logger.info("{}", data5.isPowerOn()); + + logger.info("________"); + + logger.info("{}", data5.wasIpmiPowerOn()); + logger.info("{}", data5.wasPowerFault()); + logger.info("{}", data5.wasInterlock()); + logger.info("{}", data5.wasPowerOverload()); + + logger.info("________"); + + logger.info("{}", data5.isChassisIdentifyCommandSupported()); + if (data5.isChassisIdentifyCommandSupported()) { + logger.info("{}", data5.getChassisIdentifyState()); + } + logger.info("{}", data5.coolingFaultDetected()); + logger.info("{}", data5.driveFaultDetected()); + logger.info("{}", data5.isFrontPanelLockoutActive()); + logger.info("{}", data5.isChassisIntrusionActive()); + + logger.info("________"); + + logger.info("{}", data5.isFrontPanelButtonCapabilitiesSet()); + + if (data5.isFrontPanelButtonCapabilitiesSet()) { + try { + logger.info("{}", data5.isStandbyButtonDisableAllowed()); + logger + .info( + "{}", + data5 + .isDiagnosticInterruptButtonDisableAllowed()); + logger.info("{}", data5.isResetButtonDisableAllowed()); + logger.info("{}", data5.isPowerOffButtonDisableAllowed()); + logger.info("{}", data5.isStandbyButtonDisabled()); + logger.info("{}", data5.isDiagnosticInterruptButtonDisabled()); + logger.info("{}", data5.isResetButtonDisabled()); + logger.info("{}", data5.isPowerOffButtonDisabled()); + } catch (IllegalAccessException e) { + logger.error(e.getMessage(), e); + } + + } + + logger.info("---------------------------------------------"); + + resp = new DatagramPacket(new byte[256], 256); + + try { + socket.receive(resp); + buffer = new byte[resp.getLength()]; + System.arraycopy(resp.getData(), 0, buffer, 0, buffer.length); + } catch (IOException e) { + logger.error(e.getMessage(), e); + } + + GetSdrRepositoryInfoResponseData data6 = null; + + try { + data6 = (GetSdrRepositoryInfoResponseData) Decoder + .decode( + buffer, + new Protocolv20Decoder(cs), + new GetSdrRepositoryInfo( + IpmiVersion.V20, + cs, + AuthenticationType.RMCPPlus)); + } catch (Exception e) { + logger.error(e.getMessage(), e); + } + + logger.info("{}", data6.getSdrVersion()); + logger.info("{}", data6.getRecordCount()); + logger.info("{}", data6.getAddTimestamp()); + logger.info("{}", data6.getDelTimestamp()); + logger.info("{}", data6.isReserveSupported()); + + logger.info("---------------------------------------------"); + + resp = new DatagramPacket(new byte[256], 256); + + try { + socket.receive(resp); + buffer = new byte[resp.getLength()]; + System.arraycopy(resp.getData(), 0, buffer, 0, buffer.length); + } catch (IOException e) { + logger.error(e.getMessage(), e); + } + + ReserveSdrRepositoryResponseData data7 = null; + + try { + data7 = (ReserveSdrRepositoryResponseData) Decoder + .decode( + buffer, + new Protocolv20Decoder(cs), + new ReserveSdrRepository( + IpmiVersion.V20, + cs, + AuthenticationType.RMCPPlus)); + } catch (Exception e) { + logger.error(e.getMessage(), e); + } + + logger.info("{}", data7.getReservationId()); + + reservation = data7.getReservationId(); + + logger.info("< 0) { + resp = new DatagramPacket(new byte[256], 256); + + try { + socket.receive(resp); + buffer = new byte[resp.getLength()]; + System + .arraycopy( + resp.getData(), + 0, + buffer, + 0, + buffer.length); + } catch (IOException e) { + logger.error(e.getMessage(), e); + } + GetSensorReadingResponseData data9 = null; + + try { + data9 = (GetSensorReadingResponseData) Decoder + .decode( + buffer, + new Protocolv20Decoder(cs), + new GetSensorReading(IpmiVersion.V20, cs, AuthenticationType.RMCPPlus, 0)); + + if (record instanceof FullSensorRecord) { + FullSensorRecord rec = (FullSensorRecord) record; + logger + .info( + data9.getSensorReading(rec) + + " " + + rec.getSensorBaseUnit().toString() + + (rec.getRateUnit() != RateUnit.None ? + " per " + + rec.getRateUnit() : + "")); + } + if (record instanceof CompactSensorRecord) { + CompactSensorRecord rec = (CompactSensorRecord) record; + List events = data9 + .getStatesAsserted( + rec.getSensorType(), + rec.getEventReadingType()); + StringBuilder s = new StringBuilder(); + for (int i = 0; i < events.size(); ++i) { + s.append(events.get(i)).append(", "); + } + logger.info(s.toString()); + + } + } catch (Exception e) { + logger.error(e.getMessage(), e); + } + } + + try { + Thread.sleep(100); + } catch (InterruptedException e) { + logger.error(e.getMessage(), e); + } + + nextRecId = data8.getNextRecordId(); + + logger.info("---------------------------------------------"); + + lock = false; + } + + resp = new DatagramPacket(new byte[256], 256); + + try { + socket.receive(resp); + buffer = new byte[resp.getLength()]; + System.arraycopy(resp.getData(), 0, buffer, 0, buffer.length); + } catch (IOException e) { + logger.error(e.getMessage(), e); + } + + GetSelInfoResponseData data10 = null; + + try { + data10 = (GetSelInfoResponseData) Decoder + .decode( + buffer, + new Protocolv20Decoder(cs), + new GetSelInfo( + IpmiVersion.V20, + cs, + AuthenticationType.RMCPPlus)); + } catch (Exception e) { + logger.error(e.getMessage(), e); + } + + logger.info("{}", data10.getSelVersion()); + logger.info("{}", data10.getEntriesCount()); + logger + .info( + DateFormat + .getInstance() + .format( + data10.getAdditionTimestamp())); + logger + .info( + DateFormat + .getInstance() + .format( + data10.getEraseTimestamp())); + + logger.info("---------------------------------------------"); + + resp = new DatagramPacket(new byte[256], 256); + + try { + socket.receive(resp); + buffer = new byte[resp.getLength()]; + System.arraycopy(resp.getData(), 0, buffer, 0, buffer.length); + } catch (IOException e) { + logger.error(e.getMessage(), e); + } + + ReserveSelResponseData data11 = null; + + try { + data11 = (ReserveSelResponseData) Decoder + .decode( + buffer, + new Protocolv20Decoder(cs), + new ReserveSel( + IpmiVersion.V20, + cs, + AuthenticationType.RMCPPlus)); + } catch (Exception e) { + logger.error(e.getMessage(), e); + } + + logger.info("{}", data11.getReservationId()); + + reservation = data11.getReservationId(); + reservation = 0; + + lock = false; + + logger.info("---------------------------------------------"); + + while (nextRecId < 65535) { + + resp = new DatagramPacket(new byte[256], 256); + + try { + socket.receive(resp); + buffer = new byte[resp.getLength()]; + System.arraycopy(resp.getData(), 0, buffer, 0, buffer.length); + } catch (IOException e) { + logger.error(e.getMessage(), e); + } + GetSelEntryResponseData data12 = null; + + try { + data12 = (GetSelEntryResponseData) Decoder + .decode( + buffer, + new Protocolv20Decoder(cs), + new GetSelEntry( + IpmiVersion.V20, + cs, + AuthenticationType.RMCPPlus, + 0, + 0)); + } catch (Exception e) { + logger.error(e.getMessage(), e); + } + + logger.info(data12.getSelRecord().toString()); + + SelRecord rec = data12.getSelRecord(); + + logger.info("Sensor: " + rec.getSensorType()); + logger.info("{}", rec.getTimestamp()); + logger.info("{}", rec.getEventDirection()); + logger.info("{}", rec.getEvent()); + + nextRecId = data12.getNextRecordId(); + + lock = false; + + logger.info("---------------------------------------------"); + } + + resp = new DatagramPacket(new byte[256], 256); + + try { + socket.receive(resp); + buffer = new byte[resp.getLength()]; + System.arraycopy(resp.getData(), 0, buffer, 0, buffer.length); + } catch (IOException e) { + logger.error(e.getMessage(), e); + } + + GetFruInventoryAreaInfoResponseData data13 = null; + + try { + data13 = (GetFruInventoryAreaInfoResponseData) Decoder + .decode( + buffer, + new Protocolv20Decoder(cs), + new GetFruInventoryAreaInfo(IpmiVersion.V20, cs, AuthenticationType.RMCPPlus, 0)); + } catch (Exception e) { + logger.error(e.getMessage(), e); + } + + logger + .info( + "FRU inventory area size: " + + data13.getFruInventoryAreaSize()); + + logger.info("FRU Unit: " + data13.getFruUnit()); + + logger.info("---------------------------------------------"); + + List rd = new ArrayList(); + + for (int i = 0; i < fruSize; i += 100) { + resp = new DatagramPacket(new byte[256], 256); + + try { + socket.receive(resp); + buffer = new byte[resp.getLength()]; + System.arraycopy(resp.getData(), 0, buffer, 0, buffer.length); + } catch (IOException e) { + logger.error(e.getMessage(), e); + } + + ReadFruDataResponseData data14 = null; + + try { + data14 = (ReadFruDataResponseData) Decoder + .decode( + buffer, + new Protocolv20Decoder(cs), + new ReadFruData( + IpmiVersion.V20, + cs, + AuthenticationType.RMCPPlus, + 0, + BaseUnit.Bytes, + 0, + 0)); + } catch (Exception e) { + logger.error(e.getMessage(), e); + } + + rd.add(data14); + + logger.info("{}", data14.getFruData().length); + + logger.info("---------------------------------------------"); + + } + + List records = ReadFruData.decodeFruData(rd); + + for (FruRecord r : records) { + if (r instanceof ChassisInfo) { + ChassisInfo chassisInfo = (ChassisInfo) r; + logger.info("Chassis info:"); + logger.info("Chassis type: " + chassisInfo.getChassisType()); + logger.info("Chassis part number: " + chassisInfo.getChassisPartNumber()); + logger.info("Chassis serial number: " + chassisInfo.getChassisSerialNumber()); + for (String info : chassisInfo.getCustomChassisInfo()) { + logger.info("Custom chassis info: " + info); + } + logger.info("---------------------------------------------"); + } else if (r instanceof BoardInfo) { + BoardInfo boardInfo = (BoardInfo) r; + logger.info("Board info:"); + logger.info("Board MFG date: " + boardInfo.getMfgDate().toString()); + logger.info("Board manufacturer: " + boardInfo.getBoardManufacturer()); + logger.info("Board product name: " + boardInfo.getBoardProductName()); + logger.info("Board part number: " + boardInfo.getBoardPartNumber()); + logger.info("Board serial number: " + boardInfo.getBoardSerialNumber()); + for (String info : boardInfo.getCustomBoardInfo()) { + logger.info("Custom board info: " + info); + } + logger.info("---------------------------------------------"); + } else if (r instanceof ProductInfo) { + ProductInfo productInfo = (ProductInfo) r; + logger.info("Product info:"); + logger.info("Product manufacturer: " + productInfo.getManufacturerName()); + logger.info("Product product name: " + productInfo.getProductName()); + logger.info("Product part number: " + productInfo.getProductModelNumber()); + logger.info("Product version: " + productInfo.getProductVersion()); + logger.info("Product serial number: " + productInfo.getProductSerialNumber()); + logger.info("Product asset tag: " + productInfo.getAssetTag()); + for (String info : productInfo.getCustomProductInfo()) { + logger.info("Custom board info: " + info); + } + logger.info("---------------------------------------------"); + } + } + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/Encoder.java b/src/main/java/org/metricshub/ipmi/core/coding/Encoder.java index 3bac4f7..1f7b6a2 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/Encoder.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/Encoder.java @@ -37,41 +37,49 @@ */ public final class Encoder { - /** - * Encodes IPMI command specified by payloadCoder into byte array raw data. - * - * @param protcolEncoder - * - instance of {@link IpmiEncoder} class for encoding of the - * IPMI session header. {@link Protocolv15Decoder} or - * {@link Protocolv20Decoder} should be used (depending on IPMI - * protocol version used). - * @param payloadCoder - * - instance of {@link PayloadCoder} class used for building - * IPMI message payload. - * @param messageSequenceNumber - * - A generated sequence number used for matching request and - * response. If IPMI message is sent in a session, it is used as - * a Session Sequence Number. For all IPMI messages, - * messageSequenceNumber is used as a IPMI LAN Message sequence - * number and as an IPMI payload message tag. - * @param sessionId - * - ID of the managed system's session message is being sent in. - * For sessionless commands should be set to 0. - * @return encoded IPMI command - * @throws NoSuchAlgorithmException - * - when authentication, confidentiality or integrity algorithm - * fails. - * @throws InvalidKeyException - * - when creating of the algorithm key fails - */ - public static byte[] encode(IpmiEncoder protcolEncoder, PayloadCoder payloadCoder, - int messageSequenceNumber, int sessionSequenceNumber, int sessionId) - throws NoSuchAlgorithmException, InvalidKeyException { - return RmcpEncoder - .encode(new RmcpIpmiMessage(protcolEncoder.encode(payloadCoder - .encodePayload(messageSequenceNumber, sessionSequenceNumber, sessionId)))); - } + /** + * Encodes IPMI command specified by payloadCoder into byte array raw data. + * + * @param protcolEncoder + * - instance of {@link IpmiEncoder} class for encoding of the + * IPMI session header. {@link Protocolv15Decoder} or + * {@link Protocolv20Decoder} should be used (depending on IPMI + * protocol version used). + * @param payloadCoder + * - instance of {@link PayloadCoder} class used for building + * IPMI message payload. + * @param messageSequenceNumber + * - A generated sequence number used for matching request and + * response. If IPMI message is sent in a session, it is used as + * a Session Sequence Number. For all IPMI messages, + * messageSequenceNumber is used as a IPMI LAN Message sequence + * number and as an IPMI payload message tag. + * @param sessionId + * - ID of the managed system's session message is being sent in. + * For sessionless commands should be set to 0. + * @return encoded IPMI command + * @throws NoSuchAlgorithmException + * - when authentication, confidentiality or integrity algorithm + * fails. + * @throws InvalidKeyException + * - when creating of the algorithm key fails + */ + public static byte[] encode( + IpmiEncoder protcolEncoder, + PayloadCoder payloadCoder, + int messageSequenceNumber, + int sessionSequenceNumber, + int sessionId) + throws NoSuchAlgorithmException, + InvalidKeyException { + return RmcpEncoder + .encode( + new RmcpIpmiMessage( + protcolEncoder + .encode( + payloadCoder + .encodePayload(messageSequenceNumber, sessionSequenceNumber, sessionId)))); + } - private Encoder() { - } + private Encoder() {} } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/PayloadCoder.java b/src/main/java/org/metricshub/ipmi/core/coding/PayloadCoder.java index bcbe564..b3733de 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/PayloadCoder.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/PayloadCoder.java @@ -43,178 +43,202 @@ */ public abstract class PayloadCoder { - private IpmiVersion ipmiVersion; - - /** - * Authentication type used. Default == None; - */ - private AuthenticationType authenticationType; - - private CipherSuite cipherSuite; - - public void setIpmiVersion(IpmiVersion ipmiVersion) { - this.ipmiVersion = ipmiVersion; - } - - public IpmiVersion getIpmiVersion() { - return ipmiVersion; - } - - public void setAuthenticationType(AuthenticationType authenticationType) { - this.authenticationType = authenticationType; - } - - public AuthenticationType getAuthenticationType() { - return authenticationType; - } - - public void setCipherSuite(CipherSuite cipherSuite) { - this.cipherSuite = cipherSuite; - } - - public CipherSuite getCipherSuite() { - return cipherSuite; - } - - public PayloadCoder() { - setSessionParameters(IpmiVersion.V20, CipherSuite.getEmpty(), - AuthenticationType.RMCPPlus); - } - - public PayloadCoder(IpmiVersion version, CipherSuite cipherSuite, - AuthenticationType authenticationType) { - setSessionParameters(version, cipherSuite, authenticationType); - } - - /** - * Sets session parameters. - * - * @param version - * - IPMI version of the command. - * @param cipherSuite - * - {@link CipherSuite} containing authentication, - * confidentiality and integrity algorithms for this session. - * @param authenticationType - * - Type of authentication used. Must be RMCPPlus for IPMI v2.0. - */ - public void setSessionParameters(IpmiVersion version, - CipherSuite cipherSuite, AuthenticationType authenticationType) { - - if (version == IpmiVersion.V20 - && authenticationType != AuthenticationType.RMCPPlus) { - throw new IllegalArgumentException( - "Authentication Type must be RMCPPlus for IPMI v2.0 messages"); - } - - setIpmiVersion(version); - setAuthenticationType(authenticationType); - setCipherSuite(cipherSuite); - } - - /** - * Prepares an IPMI request message containing class-specific payload. - * - * @param messageSequenceNumber - * - A generated sequence number used for matching request and - * response. For all IPMI messages, - * messageSequenceNumber is used as a IPMI LAN Message sequence - * number and as an IPMI payload message tag. - * @param sessionSequenceNumber - * - If IPMI message is sent in a session, it is used as - * a Session Sequence Number - * @param sessionId - * - ID of the managed system's session message is being sent in. - * For sessionless commands should b set to 0. - * @return IPMI message - * @throws NoSuchAlgorithmException - * - when authentication, confidentiality or integrity algorithm - * fails. - * @throws InvalidKeyException - * - when creating of the algorithm key fails - */ - public IpmiMessage encodePayload(int messageSequenceNumber, int sessionSequenceNumber, int sessionId) throws NoSuchAlgorithmException, InvalidKeyException { - if (getIpmiVersion() == IpmiVersion.V15) { - return encodeV15Payload(messageSequenceNumber, sessionSequenceNumber, sessionId); - } else /* IPMI version 2.0 */{ - return encodeV20Payload(messageSequenceNumber, sessionSequenceNumber, sessionId); - } - } - - private Ipmiv15Message encodeV15Payload(int messageSequenceNumber, int sessionSequenceNumber, int sessionId) throws NoSuchAlgorithmException, InvalidKeyException { - Ipmiv15Message message = new Ipmiv15Message(); - - message.setAuthenticationType(getAuthenticationType()); - - message.setSessionID(sessionId); - - message.setSessionSequenceNumber(sessionSequenceNumber); - - message.setPayload(preparePayload(messageSequenceNumber)); - - return message; - } - - private Ipmiv20Message encodeV20Payload(int messageSequenceNumber, int sessionSequenceNumber, int sessionId) throws NoSuchAlgorithmException, InvalidKeyException { - Ipmiv20Message message = new Ipmiv20Message(getCipherSuite() - .getConfidentialityAlgorithm()); - - message.setAuthenticationType(getAuthenticationType()); - - message.setSessionID(sessionId); - - message.setSessionSequenceNumber(sessionSequenceNumber); - - message.setPayloadType(getSupportedPayloadType()); - - message.setPayloadAuthenticated(getCipherSuite() - .getIntegrityAlgorithm().getCode() != SecurityConstants.IA_NONE); - - message.setPayloadEncrypted(getCipherSuite() - .getConfidentialityAlgorithm().getCode() != SecurityConstants.CA_NONE); - - message.setPayload(preparePayload(messageSequenceNumber)); - - message.setAuthCode(getCipherSuite() - .getIntegrityAlgorithm() - .generateAuthCode(message.getIntegrityAlgorithmBase(new Protocolv20Encoder()))); - - return message; - } - - public abstract PayloadType getSupportedPayloadType(); - - /** - * Prepares {@link IpmiPayload} to be encoded. Called from - * {@link #encodePayload(int, int, int)} - * - * @param sequenceNumber - * - sequenceNumber is used as an IPMI payload message tag - * @return IPMI payload - * @throws NoSuchAlgorithmException - * - when authentication, confidentiality or integrity algorithm - * fails. - * @throws InvalidKeyException - * - when creating of the algorithm key fails - */ - protected abstract IpmiPayload preparePayload(int sequenceNumber) throws NoSuchAlgorithmException, InvalidKeyException; - - /** - * Retrieves payload-specific response data from IPMI message - * - * @param message - * - IPMI message - * @return response data - * @throws IllegalArgumentException - * when message is not a response for class-specific command or - * response has invalid length. - * @throws IPMIException - * when response completion code isn't OK. - * @throws NoSuchAlgorithmException - * when authentication, confidentiality or integrity algorithm - * fails. - * @throws InvalidKeyException - * when creating of the authentication algorithm key fails - */ - public abstract ResponseData getResponseData(IpmiMessage message) throws IPMIException, NoSuchAlgorithmException, InvalidKeyException; + private IpmiVersion ipmiVersion; + + /** + * Authentication type used. Default == None; + */ + private AuthenticationType authenticationType; + + private CipherSuite cipherSuite; + + public void setIpmiVersion(IpmiVersion ipmiVersion) { + this.ipmiVersion = ipmiVersion; + } + + public IpmiVersion getIpmiVersion() { + return ipmiVersion; + } + + public void setAuthenticationType(AuthenticationType authenticationType) { + this.authenticationType = authenticationType; + } + + public AuthenticationType getAuthenticationType() { + return authenticationType; + } + + public void setCipherSuite(CipherSuite cipherSuite) { + this.cipherSuite = cipherSuite; + } + + public CipherSuite getCipherSuite() { + return cipherSuite; + } + + public PayloadCoder() { + setSessionParameters( + IpmiVersion.V20, + CipherSuite.getEmpty(), + AuthenticationType.RMCPPlus); + } + + public PayloadCoder(IpmiVersion version, CipherSuite cipherSuite, + AuthenticationType authenticationType) { + setSessionParameters(version, cipherSuite, authenticationType); + } + + /** + * Sets session parameters. + * + * @param version + * - IPMI version of the command. + * @param sessionCipherSuite + * - {@link CipherSuite} containing authentication, + * confidentiality and integrity algorithms for this session. + * @param sessionAuthenticationType + * - Type of authentication used. Must be RMCPPlus for IPMI v2.0. + */ + public void setSessionParameters( + IpmiVersion version, + CipherSuite sessionCipherSuite, + AuthenticationType sessionAuthenticationType) { + + if (version == IpmiVersion.V20 + && sessionAuthenticationType != AuthenticationType.RMCPPlus) { + throw new IllegalArgumentException( + "Authentication Type must be RMCPPlus for IPMI v2.0 messages"); + } + + setIpmiVersion(version); + setAuthenticationType(sessionAuthenticationType); + setCipherSuite(sessionCipherSuite); + } + + /** + * Prepares an IPMI request message containing class-specific payload. + * + * @param messageSequenceNumber + * - A generated sequence number used for matching request and + * response. For all IPMI messages, + * messageSequenceNumber is used as a IPMI LAN Message sequence + * number and as an IPMI payload message tag. + * @param sessionSequenceNumber + * - If IPMI message is sent in a session, it is used as + * a Session Sequence Number + * @param sessionId + * - ID of the managed system's session message is being sent in. + * For sessionless commands should b set to 0. + * @return IPMI message + * @throws NoSuchAlgorithmException + * - when authentication, confidentiality or integrity algorithm + * fails. + * @throws InvalidKeyException + * - when creating of the algorithm key fails + */ + public IpmiMessage encodePayload(int messageSequenceNumber, int sessionSequenceNumber, int sessionId) + throws NoSuchAlgorithmException, + InvalidKeyException { + if (getIpmiVersion() == IpmiVersion.V15) { + return encodeV15Payload(messageSequenceNumber, sessionSequenceNumber, sessionId); + } else /* IPMI version 2.0 */ { + return encodeV20Payload(messageSequenceNumber, sessionSequenceNumber, sessionId); + } + } + + private Ipmiv15Message encodeV15Payload(int messageSequenceNumber, int sessionSequenceNumber, int sessionId) + throws NoSuchAlgorithmException, + InvalidKeyException { + Ipmiv15Message message = new Ipmiv15Message(); + + message.setAuthenticationType(getAuthenticationType()); + + message.setSessionID(sessionId); + + message.setSessionSequenceNumber(sessionSequenceNumber); + + message.setPayload(preparePayload(messageSequenceNumber)); + + return message; + } + + private Ipmiv20Message encodeV20Payload(int messageSequenceNumber, int sessionSequenceNumber, int sessionId) + throws NoSuchAlgorithmException, + InvalidKeyException { + Ipmiv20Message message = new Ipmiv20Message( + getCipherSuite() + .getConfidentialityAlgorithm()); + + message.setAuthenticationType(getAuthenticationType()); + + message.setSessionID(sessionId); + + message.setSessionSequenceNumber(sessionSequenceNumber); + + message.setPayloadType(getSupportedPayloadType()); + + message + .setPayloadAuthenticated( + getCipherSuite() + .getIntegrityAlgorithm() + .getCode() != SecurityConstants.IA_NONE); + + message + .setPayloadEncrypted( + getCipherSuite() + .getConfidentialityAlgorithm() + .getCode() != SecurityConstants.CA_NONE); + + message.setPayload(preparePayload(messageSequenceNumber)); + + message + .setAuthCode( + getCipherSuite() + .getIntegrityAlgorithm() + .generateAuthCode(message.getIntegrityAlgorithmBase(new Protocolv20Encoder()))); + + return message; + } + + public abstract PayloadType getSupportedPayloadType(); + + /** + * Prepares {@link IpmiPayload} to be encoded. Called from + * {@link #encodePayload(int, int, int)} + * + * @param sequenceNumber + * - sequenceNumber is used as an IPMI payload message tag + * @return IPMI payload + * @throws NoSuchAlgorithmException + * - when authentication, confidentiality or integrity algorithm + * fails. + * @throws InvalidKeyException + * - when creating of the algorithm key fails + */ + protected abstract IpmiPayload preparePayload(int sequenceNumber) + throws NoSuchAlgorithmException, + InvalidKeyException; + + /** + * Retrieves payload-specific response data from IPMI message + * + * @param message + * - IPMI message + * @return response data + * @throws IllegalArgumentException + * when message is not a response for class-specific command or + * response has invalid length. + * @throws IPMIException + * when response completion code isn't OK. + * @throws NoSuchAlgorithmException + * when authentication, confidentiality or integrity algorithm + * fails. + * @throws InvalidKeyException + * when creating of the authentication algorithm key fails + */ + public abstract ResponseData getResponseData(IpmiMessage message) + throws IPMIException, + NoSuchAlgorithmException, + InvalidKeyException; } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/CommandCodes.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/CommandCodes.java index 87ea494..44e4d15 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/CommandCodes.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/CommandCodes.java @@ -28,103 +28,101 @@ * Contains command codes for IPMI commands Byte constants are encoded as pseudo * unsigned bytes. IpmiLanConstants doesn't use {@link TypeConverter} because * fields need to be runtime constants. - * + * * @see TypeConverter#byteToInt(byte) * @see TypeConverter#intToByte(int) - * */ public final class CommandCodes { - /** - * An IPMI code for Get Chassis Status command - */ - public static final byte GET_CHASSIS_STATUS = 0x01; - - /** - * An IPMI code for Chassis Control command - */ - public static final byte CHASSIS_CONTROL = 0x02; - - /** - * An IPMI code for Get FRU Inventory Area Info command - */ - public static final byte GET_FRU_INVENTORY_AREA_INFO = 0x10; - - /** - * An IPMI code for Read FRU Data command - */ - public static final byte READ_FRU_DATA = 0x11; - - /** - * An IPMI code for Get Device SDR Info command - */ - public static final byte GET_SDR_REPOSITORY_INFO = 0x20; - - /** - * An IPMI code for Get Device SDR Info command - */ - public static final byte GET_DEVICE_SDR_INFO = 0x21; - - /** - * An IPMI code for Reserve SDR Repository command - */ - public static final byte RESERVE_SDR_REPOSITORY = 0x22; - - /** - * An IPMI code for Get SDR command - */ - public static final byte GET_SDR = 0x23; - - /** - * An IPMI code for Get Channel Authentication Capabilities command - */ - public static final byte GET_CHANNEL_AUTHENTICATION_CAPABILITIES = 0x38; - - /** - * An IPMI code for Set Session Privilege Level command - */ - public static final byte SET_SESSION_PRIVILEGE_LEVEL = 0x3B; - - /** - * An IPMI code for Get SEL Info command - */ - public static final byte GET_SEL_INFO = 0x40; - - /** - * An IPMI code for Reserve SEL command - */ - public static final byte RESERVE_SEL = 0x42; - - /** - * An IPMI code for Get SEL Entry command - */ - public static final byte GET_SEL_ENTRY = 0x43; - - /** - * An IPMI code for Get Channel Payload Support command - */ - public static final byte GET_CHANNEL_PAYLOAD_SUPPORT = 0x4E; - - /** - * An IPMI code for Activate Payload command - */ - public static final byte ACTIVATE_PAYLOAD = 0x48; - - /** - * An IPMI code for Deactivate Payload command - */ - public static final byte DEACTIVATE_PAYLOAD = 0x49; - - /** - * An IPMI code for Get Payload Activation Status command - */ - public static final byte GET_PAYLOAD_ACTIVATION_STATUS = 0x4A; - - /** - * An IPMI code for Get Channel Cipher Suites command - */ - public static final byte GET_CHANNEL_CIPHER_SUITES = 0x54; - - private CommandCodes() { - } + /** + * An IPMI code for Get Chassis Status command + */ + public static final byte GET_CHASSIS_STATUS = 0x01; + + /** + * An IPMI code for Chassis Control command + */ + public static final byte CHASSIS_CONTROL = 0x02; + + /** + * An IPMI code for Get FRU Inventory Area Info command + */ + public static final byte GET_FRU_INVENTORY_AREA_INFO = 0x10; + + /** + * An IPMI code for Read FRU Data command + */ + public static final byte READ_FRU_DATA = 0x11; + + /** + * An IPMI code for Get Device SDR Info command + */ + public static final byte GET_SDR_REPOSITORY_INFO = 0x20; + + /** + * An IPMI code for Get Device SDR Info command + */ + public static final byte GET_DEVICE_SDR_INFO = 0x21; + + /** + * An IPMI code for Reserve SDR Repository command + */ + public static final byte RESERVE_SDR_REPOSITORY = 0x22; + + /** + * An IPMI code for Get SDR command + */ + public static final byte GET_SDR = 0x23; + + /** + * An IPMI code for Get Channel Authentication Capabilities command + */ + public static final byte GET_CHANNEL_AUTHENTICATION_CAPABILITIES = 0x38; + + /** + * An IPMI code for Set Session Privilege Level command + */ + public static final byte SET_SESSION_PRIVILEGE_LEVEL = 0x3B; + + /** + * An IPMI code for Get SEL Info command + */ + public static final byte GET_SEL_INFO = 0x40; + + /** + * An IPMI code for Reserve SEL command + */ + public static final byte RESERVE_SEL = 0x42; + + /** + * An IPMI code for Get SEL Entry command + */ + public static final byte GET_SEL_ENTRY = 0x43; + + /** + * An IPMI code for Get Channel Payload Support command + */ + public static final byte GET_CHANNEL_PAYLOAD_SUPPORT = 0x4E; + + /** + * An IPMI code for Activate Payload command + */ + public static final byte ACTIVATE_PAYLOAD = 0x48; + + /** + * An IPMI code for Deactivate Payload command + */ + public static final byte DEACTIVATE_PAYLOAD = 0x49; + + /** + * An IPMI code for Get Payload Activation Status command + */ + public static final byte GET_PAYLOAD_ACTIVATION_STATUS = 0x4A; + + /** + * An IPMI code for Get Channel Cipher Suites command + */ + public static final byte GET_CHANNEL_CIPHER_SUITES = 0x54; + + private CommandCodes() {} } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/CommandsConstants.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/CommandsConstants.java index 2972ad2..dfa7ef2 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/CommandsConstants.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/CommandsConstants.java @@ -28,42 +28,41 @@ * Set of constants. Byte constants are encoded as pseudo unsigned bytes. * IpmiLanConstants doesn't use {@link TypeConverter} because fields need to be * runtime constants. - * + * * @see TypeConverter#byteToInt(byte) * @see TypeConverter#intToByte(int) */ public final class CommandsConstants { - /** - * Highest available authentication level - */ - public static final byte AL_HIGHEST_AVAILABLE = 0x00; + /** + * Highest available authentication level + */ + public static final byte AL_HIGHEST_AVAILABLE = 0x00; - /** - * Authentication level = Callback - */ - public static final byte AL_CALLBACK = 0x01; + /** + * Authentication level = Callback + */ + public static final byte AL_CALLBACK = 0x01; - /** - * Authentication level = User - */ - public static final byte AL_USER = 0x02; + /** + * Authentication level = User + */ + public static final byte AL_USER = 0x02; - /** - * Authentication level = Operator - */ - public static final byte AL_OPERATOR = 0x03; + /** + * Authentication level = Operator + */ + public static final byte AL_OPERATOR = 0x03; - /** - * Authentication level = Administrator - */ - public static final byte AL_ADMINISTRATOR = 0x04; + /** + * Authentication level = Administrator + */ + public static final byte AL_ADMINISTRATOR = 0x04; - /** - * OEM-defined authentication level - */ - public static final byte AL_OEM = 0x05; + /** + * OEM-defined authentication level + */ + public static final byte AL_OEM = 0x05; - private CommandsConstants() { - } + private CommandsConstants() {} } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/IpmiCommandCoder.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/IpmiCommandCoder.java index ffcc925..859e69f 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/IpmiCommandCoder.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/IpmiCommandCoder.java @@ -34,86 +34,84 @@ /** * A wrapper for IPMI command. - * * Parameterless constructors in classes derived from IpmiCommandCoder are meant * to be used for decoding. To avoid omitting setting an important parameter * when encoding message use parametered constructors rather than the * parameterless ones. - * */ public abstract class IpmiCommandCoder extends PayloadCoder { - public IpmiCommandCoder() { + public IpmiCommandCoder() { - } + } - public IpmiCommandCoder(IpmiVersion version, CipherSuite cipherSuite, - AuthenticationType authenticationType) { - super(version, cipherSuite, authenticationType); - } + public IpmiCommandCoder(IpmiVersion version, CipherSuite cipherSuite, + AuthenticationType authenticationType) { + super(version, cipherSuite, authenticationType); + } - @Override - public PayloadType getSupportedPayloadType() { - return PayloadType.Ipmi; - } + @Override + public PayloadType getSupportedPayloadType() { + return PayloadType.Ipmi; + } - /** - * Checks if given message contains response command specific for this - * class. - * - * @param message {@link IpmiMessage} wrapping the IPMI message - * @return True if message contains response command specific for this - * class, false otherwise. - */ - public boolean isCommandResponse(IpmiMessage message) { - if (message.getPayload() instanceof IpmiPayload) { - if (message.getPayload() instanceof IpmiLanResponse) { - return ((IpmiLanResponse) message.getPayload()).getCommand() == getCommandCode(); - } else { - return message.getPayload() instanceof PlainMessage; - } - } else { - return false; - } - } + /** + * Checks if given message contains response command specific for this + * class. + * + * @param message {@link IpmiMessage} wrapping the IPMI message + * @return True if message contains response command specific for this + * class, false otherwise. + */ + public boolean isCommandResponse(IpmiMessage message) { + if (message.getPayload() instanceof IpmiPayload) { + if (message.getPayload() instanceof IpmiLanResponse) { + return ((IpmiLanResponse) message.getPayload()).getCommand() == getCommandCode(); + } else { + return message.getPayload() instanceof PlainMessage; + } + } else { + return false; + } + } - /** - * Retrieves command code specific for command represented by this class - * - * @return command code - */ - public abstract byte getCommandCode(); + /** + * Retrieves command code specific for command represented by this class + * + * @return command code + */ + public abstract byte getCommandCode(); - /** - * Retrieves network function specific for command represented by this - * class. - * - * @return network function - * @see NetworkFunction - */ - public abstract NetworkFunction getNetworkFunction(); + /** + * Retrieves network function specific for command represented by this + * class. + * + * @return network function + * @see NetworkFunction + */ + public abstract NetworkFunction getNetworkFunction(); - /** - * Used in several derived classes - converts {@link PrivilegeLevel} to - * byte. - * - * @param privilegeLevel - * @return privilegeLevel encoded as a byte due to {@link CommandsConstants} - */ - protected byte encodePrivilegeLevel(PrivilegeLevel privilegeLevel) { - switch (privilegeLevel) { - case MaximumAvailable: - return CommandsConstants.AL_HIGHEST_AVAILABLE; - case Callback: - return CommandsConstants.AL_CALLBACK; - case User: - return CommandsConstants.AL_USER; - case Operator: - return CommandsConstants.AL_OPERATOR; - case Administrator: - return CommandsConstants.AL_ADMINISTRATOR; - default: - throw new IllegalArgumentException("Invalid privilege level"); - } - } + /** + * Used in several derived classes - converts {@link PrivilegeLevel} to + * byte. + * + * @param privilegeLevel + * @return privilegeLevel encoded as a byte due to {@link CommandsConstants} + */ + protected byte encodePrivilegeLevel(PrivilegeLevel privilegeLevel) { + switch (privilegeLevel) { + case MaximumAvailable: + return CommandsConstants.AL_HIGHEST_AVAILABLE; + case Callback: + return CommandsConstants.AL_CALLBACK; + case User: + return CommandsConstants.AL_USER; + case Operator: + return CommandsConstants.AL_OPERATOR; + case Administrator: + return CommandsConstants.AL_ADMINISTRATOR; + default: + throw new IllegalArgumentException("Invalid privilege level"); + } + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/IpmiVersion.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/IpmiVersion.java index 9398296..9a6683e 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/IpmiVersion.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/IpmiVersion.java @@ -26,12 +26,12 @@ * Describes IPMI version */ public enum IpmiVersion { - /** - * IPMI v1.5 - */ - V15, - /** - * IPMI v2.0 - */ - V20, + /** + * IPMI v1.5 + */ + V15, + /** + * IPMI v2.0 + */ + V20, } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/PrivilegeLevel.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/PrivilegeLevel.java index cbbba9e..d026c93 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/PrivilegeLevel.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/PrivilegeLevel.java @@ -23,9 +23,9 @@ */ public enum PrivilegeLevel { - Callback, - User, - Operator, - Administrator, - MaximumAvailable + Callback, + User, + Operator, + Administrator, + MaximumAvailable } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/chassis/ChassisControl.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/chassis/ChassisControl.java index 2873f56..8a8e691 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/chassis/ChassisControl.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/chassis/ChassisControl.java @@ -45,64 +45,70 @@ */ public class ChassisControl extends IpmiCommandCoder { - private PowerCommand powerCommand; + private PowerCommand powerCommand; - /** - * Initiates ChassisControl for encoding and decoding. - * - * @param version - * - IPMI version of the command. - * @param cipherSuite - * - {@link CipherSuite} containing authentication, - * confidentiality and integrity algorithms for this session. - * @param authenticationType - * - Type of authentication used. Must be RMCPPlus for IPMI v2.0. - * @param powerCommand - * - {@link PowerCommand} that is to be performed - */ - public ChassisControl(IpmiVersion version, CipherSuite cipherSuite, - AuthenticationType authenticationType, PowerCommand powerCommand) { - super(version, cipherSuite, authenticationType); - this.powerCommand = powerCommand; - } + /** + * Initiates ChassisControl for encoding and decoding. + * + * @param version + * - IPMI version of the command. + * @param cipherSuite + * - {@link CipherSuite} containing authentication, + * confidentiality and integrity algorithms for this session. + * @param authenticationType + * - Type of authentication used. Must be RMCPPlus for IPMI v2.0. + * @param powerCommand + * - {@link PowerCommand} that is to be performed + */ + public ChassisControl(IpmiVersion version, CipherSuite cipherSuite, + AuthenticationType authenticationType, PowerCommand powerCommand) { + super(version, cipherSuite, authenticationType); + this.powerCommand = powerCommand; + } - @Override - public byte getCommandCode() { - return CommandCodes.CHASSIS_CONTROL; - } + @Override + public byte getCommandCode() { + return CommandCodes.CHASSIS_CONTROL; + } - @Override - public NetworkFunction getNetworkFunction() { - return NetworkFunction.ChassisRequest; - } + @Override + public NetworkFunction getNetworkFunction() { + return NetworkFunction.ChassisRequest; + } - @Override - protected IpmiPayload preparePayload(int sequenceNumber) - throws NoSuchAlgorithmException, InvalidKeyException { - byte[] requestData = new byte[1]; + @Override + protected IpmiPayload preparePayload(int sequenceNumber) + throws NoSuchAlgorithmException, + InvalidKeyException { + byte[] requestData = new byte[1]; - requestData[0] = TypeConverter.intToByte(powerCommand.getCode()); + requestData[0] = TypeConverter.intToByte(powerCommand.getCode()); - return new IpmiLanRequest(getNetworkFunction(), getCommandCode(), - requestData, TypeConverter.intToByte(sequenceNumber)); - } + return new IpmiLanRequest( + getNetworkFunction(), + getCommandCode(), + requestData, + TypeConverter.intToByte(sequenceNumber)); + } - @Override - public ResponseData getResponseData(IpmiMessage message) throws IPMIException, - NoSuchAlgorithmException, InvalidKeyException { - if (!isCommandResponse(message)) { - throw new IllegalArgumentException( - "This is not a response for Get Chassis Status command"); - } - if (!(message.getPayload() instanceof IpmiLanResponse)) { - throw new IllegalArgumentException("Invalid response payload"); - } - if (((IpmiLanResponse) message.getPayload()).getCompletionCode() != CompletionCode.Ok) { - throw new IPMIException( - ((IpmiLanResponse) message.getPayload()) - .getCompletionCode()); - } - return new ChassisControlResponseData(); - } + @Override + public ResponseData getResponseData(IpmiMessage message) + throws IPMIException, + NoSuchAlgorithmException, + InvalidKeyException { + if (!isCommandResponse(message)) { + throw new IllegalArgumentException( + "This is not a response for Get Chassis Status command"); + } + if (!(message.getPayload() instanceof IpmiLanResponse)) { + throw new IllegalArgumentException("Invalid response payload"); + } + if (((IpmiLanResponse) message.getPayload()).getCompletionCode() != CompletionCode.Ok) { + throw new IPMIException( + ((IpmiLanResponse) message.getPayload()) + .getCompletionCode()); + } + return new ChassisControlResponseData(); + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/chassis/ChassisIdentifyState.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/chassis/ChassisIdentifyState.java index a23cf74..259e6f0 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/chassis/ChassisIdentifyState.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/chassis/ChassisIdentifyState.java @@ -26,34 +26,34 @@ * Chassis Identify State. */ public enum ChassisIdentifyState { - Off(ChassisIdentifyState.OFF), - TemporaryOn(ChassisIdentifyState.TEMPORARYON), - IndefiniteOn(ChassisIdentifyState.INDEFINITEON), ; + Off(ChassisIdentifyState.OFF), + TemporaryOn(ChassisIdentifyState.TEMPORARYON), + IndefiniteOn(ChassisIdentifyState.INDEFINITEON),; - private static final int OFF = 0; - private static final int TEMPORARYON = 1; - private static final int INDEFINITEON = 2; + private static final int OFF = 0; + private static final int TEMPORARYON = 1; + private static final int INDEFINITEON = 2; - private int code; + private int code; - ChassisIdentifyState(int code) { - this.code = code; - } + ChassisIdentifyState(int code) { + this.code = code; + } - public int getCode() { - return code; - } + public int getCode() { + return code; + } - public static ChassisIdentifyState parseInt(int value) { - switch (value) { - case OFF: - return Off; - case TEMPORARYON: - return TemporaryOn; - case INDEFINITEON: - return IndefiniteOn; - default: - throw new IllegalArgumentException("Invalid value: " + value); - } - } + public static ChassisIdentifyState parseInt(int value) { + switch (value) { + case OFF: + return Off; + case TEMPORARYON: + return TemporaryOn; + case INDEFINITEON: + return IndefiniteOn; + default: + throw new IllegalArgumentException("Invalid value: " + value); + } + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/chassis/GetChassisStatus.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/chassis/GetChassisStatus.java index 248608c..5faa29f 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/chassis/GetChassisStatus.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/chassis/GetChassisStatus.java @@ -45,77 +45,83 @@ */ public class GetChassisStatus extends IpmiCommandCoder { - /** - * Initiates GetChassisStatus for encoding and decoding. - * - * @param version - * - IPMI version of the command. - * @param cipherSuite - * - {@link CipherSuite} containing authentication, - * confidentiality and integrity algorithms for this session. - * @param authenticationType - * - Type of authentication used. Must be RMCPPlus for IPMI v2.0. - */ - public GetChassisStatus(IpmiVersion version, CipherSuite cipherSuite, - AuthenticationType authenticationType) { - super(version, cipherSuite, authenticationType); - - if (version == IpmiVersion.V20 - && authenticationType != AuthenticationType.RMCPPlus) { - throw new IllegalArgumentException( - "Authentication Type must be RMCPPlus for IPMI v2.0 messages"); - } - } - - @Override - protected IpmiLanMessage preparePayload(int sequenceNumber) { - return new IpmiLanRequest(getNetworkFunction(), getCommandCode(), null, - TypeConverter.intToByte(sequenceNumber)); - } - - @Override - public byte getCommandCode() { - return CommandCodes.GET_CHASSIS_STATUS; - } - - @Override - public NetworkFunction getNetworkFunction() { - return NetworkFunction.ChassisRequest; - } - - @Override - public ResponseData getResponseData(IpmiMessage message) throws IPMIException, NoSuchAlgorithmException, InvalidKeyException { - if (!isCommandResponse(message)) { - throw new IllegalArgumentException( - "This is not a response for Get Chassis Status command"); - } - if (!(message.getPayload() instanceof IpmiLanResponse)) { - throw new IllegalArgumentException("Invalid response payload"); - } - if (((IpmiLanResponse) message.getPayload()).getCompletionCode() != CompletionCode.Ok) { - throw new IPMIException( - ((IpmiLanResponse) message.getPayload()) - .getCompletionCode()); - } - - byte[] raw = message.getPayload().getIpmiCommandData(); - - if (raw == null || (raw.length != 3 && raw.length != 4)) { - throw new IllegalArgumentException( - "Invalid response payload length"); - } - - GetChassisStatusResponseData responseData = new GetChassisStatusResponseData(); - - responseData.setCurrentPowerState(raw[0]); - responseData.setLastPowerEvent(raw[1]); - responseData.setMiscChassisState(raw[2]); - - if (raw.length == 4) { - responseData.setFrontPanelButtonCapabilities(raw[3]); - } - - return responseData; - } + /** + * Initiates GetChassisStatus for encoding and decoding. + * + * @param version + * - IPMI version of the command. + * @param cipherSuite + * - {@link CipherSuite} containing authentication, + * confidentiality and integrity algorithms for this session. + * @param authenticationType + * - Type of authentication used. Must be RMCPPlus for IPMI v2.0. + */ + public GetChassisStatus(IpmiVersion version, CipherSuite cipherSuite, + AuthenticationType authenticationType) { + super(version, cipherSuite, authenticationType); + + if (version == IpmiVersion.V20 + && authenticationType != AuthenticationType.RMCPPlus) { + throw new IllegalArgumentException( + "Authentication Type must be RMCPPlus for IPMI v2.0 messages"); + } + } + + @Override + protected IpmiLanMessage preparePayload(int sequenceNumber) { + return new IpmiLanRequest( + getNetworkFunction(), + getCommandCode(), + null, + TypeConverter.intToByte(sequenceNumber)); + } + + @Override + public byte getCommandCode() { + return CommandCodes.GET_CHASSIS_STATUS; + } + + @Override + public NetworkFunction getNetworkFunction() { + return NetworkFunction.ChassisRequest; + } + + @Override + public ResponseData getResponseData(IpmiMessage message) + throws IPMIException, + NoSuchAlgorithmException, + InvalidKeyException { + if (!isCommandResponse(message)) { + throw new IllegalArgumentException( + "This is not a response for Get Chassis Status command"); + } + if (!(message.getPayload() instanceof IpmiLanResponse)) { + throw new IllegalArgumentException("Invalid response payload"); + } + if (((IpmiLanResponse) message.getPayload()).getCompletionCode() != CompletionCode.Ok) { + throw new IPMIException( + ((IpmiLanResponse) message.getPayload()) + .getCompletionCode()); + } + + byte[] raw = message.getPayload().getIpmiCommandData(); + + if (raw == null || (raw.length != 3 && raw.length != 4)) { + throw new IllegalArgumentException( + "Invalid response payload length"); + } + + GetChassisStatusResponseData responseData = new GetChassisStatusResponseData(); + + responseData.setCurrentPowerState(raw[0]); + responseData.setLastPowerEvent(raw[1]); + responseData.setMiscChassisState(raw[2]); + + if (raw.length == 4) { + responseData.setFrontPanelButtonCapabilities(raw[3]); + } + + return responseData; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/chassis/GetChassisStatusResponseData.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/chassis/GetChassisStatusResponseData.java index 0a7e468..986a50a 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/chassis/GetChassisStatusResponseData.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/chassis/GetChassisStatusResponseData.java @@ -30,302 +30,305 @@ */ public class GetChassisStatusResponseData implements ResponseData { - public static final String FRONT_PANEL_BUTTON_CAPABILITIES_NOT_SET_MESSAGE = "Front Panel Button Capabilities not set"; - - private byte currentPowerState; - - private byte lastPowerEvent; - - private byte miscChassisState; - - private boolean isFrontPanelButtonCapabilitiesSet; - - private byte frontPanelButtonCapabilities; - - public GetChassisStatusResponseData() { - setFrontPanelButtonCapabilitiesSet(false); - } - - public void setCurrentPowerState(byte currentPowerState) { - this.currentPowerState = currentPowerState; - } - - public byte getCurrentPowerState() { - return currentPowerState; - } - - public PowerRestorePolicy getPowerRestorePolicy() { - switch ((currentPowerState & TypeConverter.intToByte(0x60)) >> 5) { - case 0: - return PowerRestorePolicy.PoweredOff; - case 1: - return PowerRestorePolicy.PowerRestored; - case 2: - return PowerRestorePolicy.PoweredUp; - default: - throw new IllegalArgumentException("Invalid Power Restore Policy"); - } - } - - /** - * @return True when controller attempted to turn system power on or off, - * but system did not enter desired state - */ - public boolean isPowerControlFault() { - return ((currentPowerState & TypeConverter.intToByte(0x10)) != 0); - } - - /** - * @return True when fault was detected in main power subsystem. - */ - public boolean isPowerFault() { - return ((currentPowerState & TypeConverter.intToByte(0x8)) != 0); - } - - /** - * @return True when interlock was detected (chassis is presently shut down - * because a chassis panel interlock switch is active) - */ - public boolean isInterlock() { - return ((currentPowerState & TypeConverter.intToByte(0x4)) != 0); - } - - /** - * @return True when system was shut down because of power overload - * condition. - */ - public boolean isPowerOverload() { - return ((currentPowerState & TypeConverter.intToByte(0x2)) != 0); - } - - /** - * @return True when system power is on. - */ - public boolean isPowerOn() { - return ((currentPowerState & TypeConverter.intToByte(0x1)) != 0); - } - - public void setLastPowerEvent(byte lastPowerEvent) { - this.lastPowerEvent = lastPowerEvent; - } - - public byte getLastPowerEvent() { - return lastPowerEvent; - } - - /** - * @return True when last 'Power is on' state was entered via IPMI command. - */ - public boolean wasIpmiPowerOn() { - return ((lastPowerEvent & TypeConverter.intToByte(0x10)) != 0); - } - - /** - * @return True if last power down caused by power fault. - */ - public boolean wasPowerFault() { - return ((lastPowerEvent & TypeConverter.intToByte(0x8)) != 0); - } - - /** - * @return True if last power down caused by a power interlock being - * activated. - */ - public boolean wasInterlock() { - return ((lastPowerEvent & TypeConverter.intToByte(0x4)) != 0); - } - - /** - * @return True if last power down caused by a Power overload. - */ - public boolean wasPowerOverload() { - return ((lastPowerEvent & TypeConverter.intToByte(0x2)) != 0); - } - - /** - * @return True if AC failed. - */ - public boolean acFailed() { - return ((lastPowerEvent & TypeConverter.intToByte(0x1)) != 0); - - } - - public void setMiscChassisState(byte miscChassisState) { - this.miscChassisState = miscChassisState; - } - - public byte getMiscChassisState() { - return miscChassisState; - } - - /** - * @return True if Chassis Identify command and state info supported. - */ - public boolean isChassisIdentifyCommandSupported() { - return ((miscChassisState & TypeConverter.intToByte(0x40)) != 0); - } - - public ChassisIdentifyState getChassisIdentifyState() { - if (!isChassisIdentifyCommandSupported()) { - throw new IllegalAccessError( - "Chassis Idetify command and state not supported"); - } - - return ChassisIdentifyState.parseInt((miscChassisState & TypeConverter - .intToByte(0x30)) >> 4); - } - - /** - * @return True if cooling or fan fault was detected. - */ - public boolean coolingFaultDetected() { - return ((miscChassisState & TypeConverter.intToByte(0x8)) != 0); - } - - /** - * @return True if drive fault was detected. - */ - public boolean driveFaultDetected() { - return ((miscChassisState & TypeConverter.intToByte(0x4)) != 0); - } - - /** - * @return True if Front Panel Lockout active (power off and reset via - * chassis push-buttons disabled.). - */ - public boolean isFrontPanelLockoutActive() { - return ((miscChassisState & TypeConverter.intToByte(0x2)) != 0); - } - - /** - * @return True if Chassis intrusion active is active. - */ - public boolean isChassisIntrusionActive() { - return ((miscChassisState & TypeConverter.intToByte(0x1)) != 0); - } - - public void setFrontPanelButtonCapabilities( - byte frontPanelButtonCapabilities) { - this.frontPanelButtonCapabilities = frontPanelButtonCapabilities; - setFrontPanelButtonCapabilitiesSet(true); - } - - public byte getFrontPanelButtonCapabilities() { - return frontPanelButtonCapabilities; - } - - /** - * @return Standby (sleep) button disable is allowed. - * @throws IllegalAccessException - * when Front Panel Button Capabilities wasn't set. - */ - public boolean isStandbyButtonDisableAllowed() - throws IllegalAccessException { - if (!isFrontPanelButtonCapabilitiesSet()) { - throw new IllegalAccessException(FRONT_PANEL_BUTTON_CAPABILITIES_NOT_SET_MESSAGE); - } - return ((frontPanelButtonCapabilities & TypeConverter.intToByte(0x80)) != 0); - } - - /** - * @return Diagnostic Interrupt button disable is allowed. - * @throws IllegalAccessException - * when Front Panel Button Capabilities wasn't set. - */ - public boolean isDiagnosticInterruptButtonDisableAllowed() - throws IllegalAccessException { - if (!isFrontPanelButtonCapabilitiesSet()) { - throw new IllegalAccessException(FRONT_PANEL_BUTTON_CAPABILITIES_NOT_SET_MESSAGE); - } - return ((frontPanelButtonCapabilities & TypeConverter.intToByte(0x40)) != 0); - } - - /** - * @return Reset button disable is allowed. - * @throws IllegalAccessException - * when Front Panel Button Capabilities wasn't set. - */ - public boolean isResetButtonDisableAllowed() throws IllegalAccessException { - if (!isFrontPanelButtonCapabilitiesSet()) { - throw new IllegalAccessException(FRONT_PANEL_BUTTON_CAPABILITIES_NOT_SET_MESSAGE); - } - return ((frontPanelButtonCapabilities & TypeConverter.intToByte(0x20)) != 0); - } - - /** - * @return Power off button disable allowed (in the case there is a single - * combined power/standby (sleep) button, disabling power off also - * disables sleep requests via that button.) - * @throws IllegalAccessException - * when Front Panel Button Capabilities wasn't set. - */ - public boolean isPowerOffButtonDisableAllowed() - throws IllegalAccessException { - if (!isFrontPanelButtonCapabilitiesSet()) { - throw new IllegalAccessException(FRONT_PANEL_BUTTON_CAPABILITIES_NOT_SET_MESSAGE); - } - return ((frontPanelButtonCapabilities & TypeConverter.intToByte(0x10)) != 0); - } - - /** - * @return Standby (sleep) button disabled. - * @throws IllegalAccessException - * when Front Panel Button Capabilities wasn't set. - */ - public boolean isStandbyButtonDisabled() throws IllegalAccessException { - if (!isFrontPanelButtonCapabilitiesSet()) { - throw new IllegalAccessException(FRONT_PANEL_BUTTON_CAPABILITIES_NOT_SET_MESSAGE); - } - return ((frontPanelButtonCapabilities & TypeConverter.intToByte(0x8)) != 0); - } - - /** - * @return Diagnostic Interrupt button disabled. - * @throws IllegalAccessException - * when Front Panel Button Capabilities wasn't set. - */ - public boolean isDiagnosticInterruptButtonDisabled() - throws IllegalAccessException { - if (!isFrontPanelButtonCapabilitiesSet()) { - throw new IllegalAccessException(FRONT_PANEL_BUTTON_CAPABILITIES_NOT_SET_MESSAGE); - } - return ((frontPanelButtonCapabilities & TypeConverter.intToByte(0x4)) != 0); - } - - /** - * @return Reset button disabled. - * @throws IllegalAccessException - * when Front Panel Button Capabilities wasn't set. - */ - public boolean isResetButtonDisabled() throws IllegalAccessException { - if (!isFrontPanelButtonCapabilitiesSet()) { - throw new IllegalAccessException(FRONT_PANEL_BUTTON_CAPABILITIES_NOT_SET_MESSAGE); - } - return ((frontPanelButtonCapabilities & TypeConverter.intToByte(0x2)) != 0); - } - - /** - * @return Power off button disabled (in the case there is a single combined - * power/standby (sleep) button, disabling power off also disables - * sleep requests via that button are also disabled.) - * @throws IllegalAccessException - * when Front Panel Button Capabilities wasn't set. - */ - public boolean isPowerOffButtonDisabled() throws IllegalAccessException { - if (!isFrontPanelButtonCapabilitiesSet()) { - throw new IllegalAccessException( - FRONT_PANEL_BUTTON_CAPABILITIES_NOT_SET_MESSAGE); - } - return ((frontPanelButtonCapabilities & TypeConverter.intToByte(0x1)) != 0); - } - - private void setFrontPanelButtonCapabilitiesSet( - boolean isFrontPanelButtonCapabilitiesSet) { - this.isFrontPanelButtonCapabilitiesSet = isFrontPanelButtonCapabilitiesSet; - } - - public boolean isFrontPanelButtonCapabilitiesSet() { - return isFrontPanelButtonCapabilitiesSet; - } + public static final String FRONT_PANEL_BUTTON_CAPABILITIES_NOT_SET_MESSAGE = "Front Panel Button Capabilities not set"; + + private byte currentPowerState; + + private byte lastPowerEvent; + + private byte miscChassisState; + + private boolean isFrontPanelButtonCapabilitiesSet; + + private byte frontPanelButtonCapabilities; + + public GetChassisStatusResponseData() { + setFrontPanelButtonCapabilitiesSet(false); + } + + public void setCurrentPowerState(byte currentPowerState) { + this.currentPowerState = currentPowerState; + } + + public byte getCurrentPowerState() { + return currentPowerState; + } + + public PowerRestorePolicy getPowerRestorePolicy() { + switch ((currentPowerState & TypeConverter.intToByte(0x60)) >> 5) { + case 0: + return PowerRestorePolicy.PoweredOff; + case 1: + return PowerRestorePolicy.PowerRestored; + case 2: + return PowerRestorePolicy.PoweredUp; + default: + throw new IllegalArgumentException("Invalid Power Restore Policy"); + } + } + + /** + * @return True when controller attempted to turn system power on or off, + * but system did not enter desired state + */ + public boolean isPowerControlFault() { + return ((currentPowerState & TypeConverter.intToByte(0x10)) != 0); + } + + /** + * @return True when fault was detected in main power subsystem. + */ + public boolean isPowerFault() { + return ((currentPowerState & TypeConverter.intToByte(0x8)) != 0); + } + + /** + * @return True when interlock was detected (chassis is presently shut down + * because a chassis panel interlock switch is active) + */ + public boolean isInterlock() { + return ((currentPowerState & TypeConverter.intToByte(0x4)) != 0); + } + + /** + * @return True when system was shut down because of power overload + * condition. + */ + public boolean isPowerOverload() { + return ((currentPowerState & TypeConverter.intToByte(0x2)) != 0); + } + + /** + * @return True when system power is on. + */ + public boolean isPowerOn() { + return ((currentPowerState & TypeConverter.intToByte(0x1)) != 0); + } + + public void setLastPowerEvent(byte lastPowerEvent) { + this.lastPowerEvent = lastPowerEvent; + } + + public byte getLastPowerEvent() { + return lastPowerEvent; + } + + /** + * @return True when last 'Power is on' state was entered via IPMI command. + */ + public boolean wasIpmiPowerOn() { + return ((lastPowerEvent & TypeConverter.intToByte(0x10)) != 0); + } + + /** + * @return True if last power down caused by power fault. + */ + public boolean wasPowerFault() { + return ((lastPowerEvent & TypeConverter.intToByte(0x8)) != 0); + } + + /** + * @return True if last power down caused by a power interlock being + * activated. + */ + public boolean wasInterlock() { + return ((lastPowerEvent & TypeConverter.intToByte(0x4)) != 0); + } + + /** + * @return True if last power down caused by a Power overload. + */ + public boolean wasPowerOverload() { + return ((lastPowerEvent & TypeConverter.intToByte(0x2)) != 0); + } + + /** + * @return True if AC failed. + */ + public boolean acFailed() { + return ((lastPowerEvent & TypeConverter.intToByte(0x1)) != 0); + + } + + public void setMiscChassisState(byte miscChassisState) { + this.miscChassisState = miscChassisState; + } + + public byte getMiscChassisState() { + return miscChassisState; + } + + /** + * @return True if Chassis Identify command and state info supported. + */ + public boolean isChassisIdentifyCommandSupported() { + return ((miscChassisState & TypeConverter.intToByte(0x40)) != 0); + } + + public ChassisIdentifyState getChassisIdentifyState() { + if (!isChassisIdentifyCommandSupported()) { + throw new IllegalAccessError( + "Chassis Idetify command and state not supported"); + } + + return ChassisIdentifyState + .parseInt( + (miscChassisState + & TypeConverter + .intToByte(0x30)) >> 4); + } + + /** + * @return True if cooling or fan fault was detected. + */ + public boolean coolingFaultDetected() { + return ((miscChassisState & TypeConverter.intToByte(0x8)) != 0); + } + + /** + * @return True if drive fault was detected. + */ + public boolean driveFaultDetected() { + return ((miscChassisState & TypeConverter.intToByte(0x4)) != 0); + } + + /** + * @return True if Front Panel Lockout active (power off and reset via + * chassis push-buttons disabled.). + */ + public boolean isFrontPanelLockoutActive() { + return ((miscChassisState & TypeConverter.intToByte(0x2)) != 0); + } + + /** + * @return True if Chassis intrusion active is active. + */ + public boolean isChassisIntrusionActive() { + return ((miscChassisState & TypeConverter.intToByte(0x1)) != 0); + } + + public void setFrontPanelButtonCapabilities( + byte frontPanelButtonCapabilities) { + this.frontPanelButtonCapabilities = frontPanelButtonCapabilities; + setFrontPanelButtonCapabilitiesSet(true); + } + + public byte getFrontPanelButtonCapabilities() { + return frontPanelButtonCapabilities; + } + + /** + * @return Standby (sleep) button disable is allowed. + * @throws IllegalAccessException + * when Front Panel Button Capabilities wasn't set. + */ + public boolean isStandbyButtonDisableAllowed() + throws IllegalAccessException { + if (!isFrontPanelButtonCapabilitiesSet()) { + throw new IllegalAccessException(FRONT_PANEL_BUTTON_CAPABILITIES_NOT_SET_MESSAGE); + } + return ((frontPanelButtonCapabilities & TypeConverter.intToByte(0x80)) != 0); + } + + /** + * @return Diagnostic Interrupt button disable is allowed. + * @throws IllegalAccessException + * when Front Panel Button Capabilities wasn't set. + */ + public boolean isDiagnosticInterruptButtonDisableAllowed() + throws IllegalAccessException { + if (!isFrontPanelButtonCapabilitiesSet()) { + throw new IllegalAccessException(FRONT_PANEL_BUTTON_CAPABILITIES_NOT_SET_MESSAGE); + } + return ((frontPanelButtonCapabilities & TypeConverter.intToByte(0x40)) != 0); + } + + /** + * @return Reset button disable is allowed. + * @throws IllegalAccessException + * when Front Panel Button Capabilities wasn't set. + */ + public boolean isResetButtonDisableAllowed() throws IllegalAccessException { + if (!isFrontPanelButtonCapabilitiesSet()) { + throw new IllegalAccessException(FRONT_PANEL_BUTTON_CAPABILITIES_NOT_SET_MESSAGE); + } + return ((frontPanelButtonCapabilities & TypeConverter.intToByte(0x20)) != 0); + } + + /** + * @return Power off button disable allowed (in the case there is a single + * combined power/standby (sleep) button, disabling power off also + * disables sleep requests via that button.) + * @throws IllegalAccessException + * when Front Panel Button Capabilities wasn't set. + */ + public boolean isPowerOffButtonDisableAllowed() + throws IllegalAccessException { + if (!isFrontPanelButtonCapabilitiesSet()) { + throw new IllegalAccessException(FRONT_PANEL_BUTTON_CAPABILITIES_NOT_SET_MESSAGE); + } + return ((frontPanelButtonCapabilities & TypeConverter.intToByte(0x10)) != 0); + } + + /** + * @return Standby (sleep) button disabled. + * @throws IllegalAccessException + * when Front Panel Button Capabilities wasn't set. + */ + public boolean isStandbyButtonDisabled() throws IllegalAccessException { + if (!isFrontPanelButtonCapabilitiesSet()) { + throw new IllegalAccessException(FRONT_PANEL_BUTTON_CAPABILITIES_NOT_SET_MESSAGE); + } + return ((frontPanelButtonCapabilities & TypeConverter.intToByte(0x8)) != 0); + } + + /** + * @return Diagnostic Interrupt button disabled. + * @throws IllegalAccessException + * when Front Panel Button Capabilities wasn't set. + */ + public boolean isDiagnosticInterruptButtonDisabled() + throws IllegalAccessException { + if (!isFrontPanelButtonCapabilitiesSet()) { + throw new IllegalAccessException(FRONT_PANEL_BUTTON_CAPABILITIES_NOT_SET_MESSAGE); + } + return ((frontPanelButtonCapabilities & TypeConverter.intToByte(0x4)) != 0); + } + + /** + * @return Reset button disabled. + * @throws IllegalAccessException + * when Front Panel Button Capabilities wasn't set. + */ + public boolean isResetButtonDisabled() throws IllegalAccessException { + if (!isFrontPanelButtonCapabilitiesSet()) { + throw new IllegalAccessException(FRONT_PANEL_BUTTON_CAPABILITIES_NOT_SET_MESSAGE); + } + return ((frontPanelButtonCapabilities & TypeConverter.intToByte(0x2)) != 0); + } + + /** + * @return Power off button disabled (in the case there is a single combined + * power/standby (sleep) button, disabling power off also disables + * sleep requests via that button are also disabled.) + * @throws IllegalAccessException + * when Front Panel Button Capabilities wasn't set. + */ + public boolean isPowerOffButtonDisabled() throws IllegalAccessException { + if (!isFrontPanelButtonCapabilitiesSet()) { + throw new IllegalAccessException( + FRONT_PANEL_BUTTON_CAPABILITIES_NOT_SET_MESSAGE); + } + return ((frontPanelButtonCapabilities & TypeConverter.intToByte(0x1)) != 0); + } + + private void setFrontPanelButtonCapabilitiesSet( + boolean frontPanelButtonCapabilitiesSet) { + this.isFrontPanelButtonCapabilitiesSet = frontPanelButtonCapabilitiesSet; + } + + public boolean isFrontPanelButtonCapabilitiesSet() { + return isFrontPanelButtonCapabilitiesSet; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/chassis/PowerCommand.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/chassis/PowerCommand.java index f09a17a..d2f09c0 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/chassis/PowerCommand.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/chassis/PowerCommand.java @@ -27,45 +27,47 @@ * {@link ChassisControl} command. */ public enum PowerCommand { - /** - * Force system into soft off (S4/S45) state. This is for 'emergency' - * management power down actions. The command does not initiate a clean - * shut-down of the operating system prior to powering down the system. - */ - PowerDown(PowerCommand.POWERDOWN), PowerUp(PowerCommand.POWERUP), - /** - * Hard reset. In some implementations, the BMC may not know whether a reset - * will cause any particular effect and will pulse the system reset signal - * regardless of power state. If the implementation can tell that no action - * will occur if a reset is delivered in a given power state, then it is - * recommended (but still optional) that a D5h 'Request parameter(s) not - * supported in present state.' error completion code be returned. - */ - HardReset(PowerCommand.HARDRESET), ; - private static final int POWERDOWN = 0; - private static final int POWERUP = 1; - private static final int HARDRESET = 3; + /** + * Force system into soft off (S4/S45) state. This is for 'emergency' + * management power down actions. The command does not initiate a clean + * shut-down of the operating system prior to powering down the system. + */ + PowerDown(PowerCommand.POWERDOWN), + PowerUp(PowerCommand.POWERUP), + /** + * Hard reset. In some implementations, the BMC may not know whether a reset + * will cause any particular effect and will pulse the system reset signal + * regardless of power state. If the implementation can tell that no action + * will occur if a reset is delivered in a given power state, then it is + * recommended (but still optional) that a D5h 'Request parameter(s) not + * supported in present state.' error completion code be returned. + */ + HardReset(PowerCommand.HARDRESET),; - private int code; + private static final int POWERDOWN = 0; + private static final int POWERUP = 1; + private static final int HARDRESET = 3; - PowerCommand(int code) { - this.code = code; - } + private int code; - public int getCode() { - return code; - } + PowerCommand(int code) { + this.code = code; + } - public static PowerCommand parseInt(int value) { - switch (value) { - case POWERDOWN: - return PowerDown; - case POWERUP: - return PowerUp; - case HARDRESET: - return HardReset; - default: - throw new IllegalArgumentException("Invalid value: " + value); - } - } + public int getCode() { + return code; + } + + public static PowerCommand parseInt(int value) { + switch (value) { + case POWERDOWN: + return PowerDown; + case POWERUP: + return PowerUp; + case HARDRESET: + return HardReset; + default: + throw new IllegalArgumentException("Invalid value: " + value); + } + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/chassis/PowerRestorePolicy.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/chassis/PowerRestorePolicy.java index 94a18c3..19032ef 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/chassis/PowerRestorePolicy.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/chassis/PowerRestorePolicy.java @@ -26,17 +26,17 @@ * Chassis power restore policy. */ public enum PowerRestorePolicy { - /** - * Chassis stays powered off after AC/mains returns - */ - PoweredOff, - /** - * After AC returns, power is restored to the state that was in effect when - * AC/mains was lost - */ - PowerRestored, - /** - * Chassis always powers up after AC/mains returns - */ - PoweredUp, + /** + * Chassis stays powered off after AC/mains returns + */ + PoweredOff, + /** + * After AC returns, power is restored to the state that was in effect when + * AC/mains was lost + */ + PowerRestored, + /** + * Chassis always powers up after AC/mains returns + */ + PoweredUp, } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/BaseUnit.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/BaseUnit.java index 5552e68..d35eb93 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/BaseUnit.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/BaseUnit.java @@ -26,44 +26,46 @@ * Represents unit which is used to access FRU */ public enum BaseUnit { - Bytes(BaseUnit.BYTES), Words(BaseUnit.WORDS), ; - private static final int BYTES = 0; - private static final int WORDS = 1; - private static final int BYTESIZE = 1; - private static final int WORDSIZE = 16; + Bytes(BaseUnit.BYTES), + Words(BaseUnit.WORDS),; - private int code; + private static final int BYTES = 0; + private static final int WORDS = 1; + private static final int BYTESIZE = 1; + private static final int WORDSIZE = 16; - BaseUnit(int code) { - this.code = code; - } + private int code; - public int getCode() { - return code; - } + BaseUnit(int code) { + this.code = code; + } - public static BaseUnit parseInt(int value) { - switch (value) { - case BYTES: - return Bytes; - case WORDS: - return Words; - default: - throw new IllegalArgumentException("Invalid value: " + value); - } - } + public int getCode() { + return code; + } - /** - * Returns size of the unit in bytes. - */ - public int getSize() { - switch (this) { - case Bytes: - return BYTESIZE; - case Words: - return WORDSIZE; - default: - throw new IllegalArgumentException("Invalid value: " + this); - } - } + public static BaseUnit parseInt(int value) { + switch (value) { + case BYTES: + return Bytes; + case WORDS: + return Words; + default: + throw new IllegalArgumentException("Invalid value: " + value); + } + } + + /** + * Returns size of the unit in bytes. + */ + public int getSize() { + switch (this) { + case Bytes: + return BYTESIZE; + case Words: + return WORDSIZE; + default: + throw new IllegalArgumentException("Invalid value: " + this); + } + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/GetFruInventoryAreaInfo.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/GetFruInventoryAreaInfo.java index 68ddc00..eee1061 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/GetFruInventoryAreaInfo.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/GetFruInventoryAreaInfo.java @@ -45,89 +45,103 @@ */ public class GetFruInventoryAreaInfo extends IpmiCommandCoder { - private int fruId; - - /** - * Initiates GetFruInventoryAreaInfo for both encoding and decoding. - * - * @param version - * - IPMI version of the command. - * @param cipherSuite - * - {@link CipherSuite} containing authentication, - * confidentiality and integrity algorithms for this session. - * @param authenticationType - * - Type of authentication used. Must be RMCPPlus for IPMI v2.0. - * @param fruId - * - ID of the FRU to get info from. Must be less than 256. - */ - public GetFruInventoryAreaInfo(IpmiVersion version, - CipherSuite cipherSuite, AuthenticationType authenticationType, - int fruId) { - super(version, cipherSuite, authenticationType); - - if (fruId > 255) { - throw new IllegalArgumentException("FRU ID cannot exceed 255"); - } - - this.fruId = fruId; - } - - @Override - public byte getCommandCode() { - return CommandCodes.GET_FRU_INVENTORY_AREA_INFO; - } - - @Override - public NetworkFunction getNetworkFunction() { - return NetworkFunction.StorageRequest; - } - - @Override - protected IpmiPayload preparePayload(int sequenceNumber) - throws NoSuchAlgorithmException, InvalidKeyException { - byte[] payload = new byte[] { TypeConverter.intToByte(fruId) }; - return new IpmiLanRequest(getNetworkFunction(), getCommandCode(), - payload, TypeConverter.intToByte(sequenceNumber)); - } - - @Override - public ResponseData getResponseData(IpmiMessage message) throws IPMIException, NoSuchAlgorithmException, InvalidKeyException { - - if (!isCommandResponse(message)) { - throw new IllegalArgumentException( - "This is not a response for Get FRU Inventory Info command"); - } - if (!(message.getPayload() instanceof IpmiLanResponse)) { - throw new IllegalArgumentException("Invalid response payload"); - } - if (((IpmiLanResponse) message.getPayload()).getCompletionCode() != CompletionCode.Ok) { - throw new IPMIException( - ((IpmiLanResponse) message.getPayload()) - .getCompletionCode()); - } - - byte[] raw = message.getPayload().getIpmiCommandData(); - - if (raw == null || raw.length != 3) { - throw new IllegalArgumentException( - "Invalid response payload length"); - } - - GetFruInventoryAreaInfoResponseData responseData = new GetFruInventoryAreaInfoResponseData(); - - byte[] buffer = new byte[4]; - - buffer[0] = raw[0]; - buffer[1] = raw[1]; - buffer[2] = 0; - buffer[3] = 0; - - responseData.setFruInventoryAreaSize(TypeConverter - .littleEndianByteArrayToInt(buffer)); - - responseData.setFruUnit(BaseUnit.parseInt(TypeConverter - .byteToInt(raw[2]) & 0x1)); - - return responseData; - } + private int fruId; + + /** + * Initiates GetFruInventoryAreaInfo for both encoding and decoding. + * + * @param version + * - IPMI version of the command. + * @param cipherSuite + * - {@link CipherSuite} containing authentication, + * confidentiality and integrity algorithms for this session. + * @param authenticationType + * - Type of authentication used. Must be RMCPPlus for IPMI v2.0. + * @param fruId + * - ID of the FRU to get info from. Must be less than 256. + */ + public GetFruInventoryAreaInfo(IpmiVersion version, + CipherSuite cipherSuite, AuthenticationType authenticationType, + int fruId) { + super(version, cipherSuite, authenticationType); + + if (fruId > 255) { + throw new IllegalArgumentException("FRU ID cannot exceed 255"); + } + + this.fruId = fruId; + } + + @Override + public byte getCommandCode() { + return CommandCodes.GET_FRU_INVENTORY_AREA_INFO; + } + + @Override + public NetworkFunction getNetworkFunction() { + return NetworkFunction.StorageRequest; + } + + @Override + protected IpmiPayload preparePayload(int sequenceNumber) + throws NoSuchAlgorithmException, + InvalidKeyException { + byte[] payload = new byte[] { TypeConverter.intToByte(fruId) }; + return new IpmiLanRequest( + getNetworkFunction(), + getCommandCode(), + payload, + TypeConverter.intToByte(sequenceNumber)); + } + + @Override + public ResponseData getResponseData(IpmiMessage message) + throws IPMIException, + NoSuchAlgorithmException, + InvalidKeyException { + + if (!isCommandResponse(message)) { + throw new IllegalArgumentException( + "This is not a response for Get FRU Inventory Info command"); + } + if (!(message.getPayload() instanceof IpmiLanResponse)) { + throw new IllegalArgumentException("Invalid response payload"); + } + if (((IpmiLanResponse) message.getPayload()).getCompletionCode() != CompletionCode.Ok) { + throw new IPMIException( + ((IpmiLanResponse) message.getPayload()) + .getCompletionCode()); + } + + byte[] raw = message.getPayload().getIpmiCommandData(); + + if (raw == null || raw.length != 3) { + throw new IllegalArgumentException( + "Invalid response payload length"); + } + + GetFruInventoryAreaInfoResponseData responseData = new GetFruInventoryAreaInfoResponseData(); + + byte[] buffer = new byte[4]; + + buffer[0] = raw[0]; + buffer[1] = raw[1]; + buffer[2] = 0; + buffer[3] = 0; + + responseData + .setFruInventoryAreaSize( + TypeConverter + .littleEndianByteArrayToInt(buffer)); + + responseData + .setFruUnit( + BaseUnit + .parseInt( + TypeConverter + .byteToInt(raw[2]) + & 0x1)); + + return responseData; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/GetFruInventoryAreaInfoResponseData.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/GetFruInventoryAreaInfoResponseData.java index 02dcc3a..25d8cc5 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/GetFruInventoryAreaInfoResponseData.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/GetFruInventoryAreaInfoResponseData.java @@ -29,23 +29,23 @@ */ public class GetFruInventoryAreaInfoResponseData implements ResponseData { - private int fruInventoryAreaSize; + private int fruInventoryAreaSize; - private BaseUnit fruUnit; + private BaseUnit fruUnit; - public int getFruInventoryAreaSize() { - return fruInventoryAreaSize; - } + public int getFruInventoryAreaSize() { + return fruInventoryAreaSize; + } - public void setFruInventoryAreaSize(int fruInventoryAreaSize) { - this.fruInventoryAreaSize = fruInventoryAreaSize; - } + public void setFruInventoryAreaSize(int fruInventoryAreaSize) { + this.fruInventoryAreaSize = fruInventoryAreaSize; + } - public BaseUnit getFruUnit() { - return fruUnit; - } + public BaseUnit getFruUnit() { + return fruUnit; + } - public void setFruUnit(BaseUnit fruUnit) { - this.fruUnit = fruUnit; - } + public void setFruUnit(BaseUnit fruUnit) { + this.fruUnit = fruUnit; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/ReadFruData.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/ReadFruData.java index c4b842d..b2e6a89 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/ReadFruData.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/ReadFruData.java @@ -55,223 +55,230 @@ */ public class ReadFruData extends IpmiCommandCoder { - private int offset; - - private int size; - - private int fruId; - - /** - * Initiates ReadFruData for both encoding and decoding. Sets session - * parameters to default. - * - * @see IpmiCommandCoder#setSessionParameters(IpmiVersion, CipherSuite, - * AuthenticationType) - * @param fruId - * - ID of the FRU to get info from. Must be less than 256. To - * get FRU ID use {@link GetSdr} to retrieve - * {@link FruDeviceLocatorRecord}. - * @param unit - * - {@link BaseUnit} indicating if the FRU device is accessed in - * {@link BaseUnit#Bytes} or {@link BaseUnit#Words} - * @param offset - * - offset to read in units specified by unit - * @param countToRead - * - size of the area to read in unit. Cannot exceed 255; - */ - public ReadFruData(int fruId, BaseUnit unit, int offset, int countToRead) { - super(); - - if (countToRead > 255) { - throw new IllegalArgumentException( - "Count to read cannot exceed 255"); - } - - if (fruId > 255) { - throw new IllegalArgumentException("FRU ID cannot exceed 255"); - } - - this.offset = offset * unit.getSize(); - - size = countToRead * unit.getSize(); - - this.fruId = fruId; - // TODO: Check if Count To Read field is encoded in words if the FRU is - // addressed in words (requires different server settings). - } - - /** - * Initiates ReadFruData for both encoding and decoding. - * - * @param version - * - IPMI version of the command. - * @param cipherSuite - * - {@link CipherSuite} containing authentication, - * confidentiality and integrity algorithms for this session. - * @param authenticationType - * - Type of authentication used. Must be RMCPPlus for IPMI v2.0. - * @param fruId - * - ID of the FRU to get info from. Must be less than 256. To - * get FRU ID use {@link GetSdr} to retrieve - * {@link FruDeviceLocatorRecord}. - * @param unit - * - {@link BaseUnit} indicating if the FRU device is accessed in - * {@link BaseUnit#Bytes} or {@link BaseUnit#Words} - * @param offset - * - offset to read in units specified by unit - * @param countToRead - * - size of the area to read in unit. Cannot exceed 255; - */ - public ReadFruData(IpmiVersion version, CipherSuite cipherSuite, - AuthenticationType authenticationType, int fruId, BaseUnit unit, - int offset, int countToRead) { - super(version, cipherSuite, authenticationType); - - if (countToRead > 255) { - throw new IllegalArgumentException( - "Count to read cannot exceed 255"); - } - - if (fruId > 255) { - throw new IllegalArgumentException("FRU ID cannot exceed 255"); - } - - this.offset = offset * unit.getSize(); - - size = countToRead * unit.getSize(); - - this.fruId = fruId; - // TODO: Check if Count To Read field is encoded in words if the FRU is - // addressed in words (requires different server settings). - } - - @Override - public byte getCommandCode() { - return CommandCodes.READ_FRU_DATA; - } - - @Override - public NetworkFunction getNetworkFunction() { - return NetworkFunction.StorageRequest; - } - - @Override - protected IpmiPayload preparePayload(int sequenceNumber) - throws NoSuchAlgorithmException, InvalidKeyException { - byte[] payload = new byte[4]; - payload[0] = TypeConverter.intToByte(fruId); - byte[] buffer = TypeConverter.intToLittleEndianByteArray(offset); - payload[1] = buffer[0]; - payload[2] = buffer[1]; - payload[3] = TypeConverter.intToByte(size); - - return new IpmiLanRequest(getNetworkFunction(), getCommandCode(), - payload, TypeConverter.intToByte(sequenceNumber)); - } - - @Override - public ResponseData getResponseData(IpmiMessage message) throws IPMIException, NoSuchAlgorithmException, InvalidKeyException { - - if (!isCommandResponse(message)) { - throw new IllegalArgumentException( - "This is not a response for Get SDR Repository Info command"); - } - if (!(message.getPayload() instanceof IpmiLanResponse)) { - throw new IllegalArgumentException("Invalid response payload"); - } - if (((IpmiLanResponse) message.getPayload()).getCompletionCode() != CompletionCode.Ok) { - throw new IPMIException( - ((IpmiLanResponse) message.getPayload()) - .getCompletionCode()); - } - - byte[] raw = message.getPayload().getIpmiCommandData(); - - if (raw == null || raw.length < 2) { - throw new IllegalArgumentException( - "Invalid response payload length"); - } - - ReadFruDataResponseData responseData = new ReadFruDataResponseData(); - - int sizeFromResponse = TypeConverter.byteToInt(raw[0]); - - byte[] fruData = new byte[sizeFromResponse]; - - System.arraycopy(raw, 1, fruData, 0, sizeFromResponse); - - responseData.setFruData(fruData); - - return responseData; - } - - /** - * Decodes {@link FruRecord}s from data provided by {@link ReadFruData} - * command. Size of the FRU Inventory Area might exceed size of the - * communication packet so it might come in many - * {@link ReadFruDataResponseData} packets. - * - * @param fruData - * - list of {@link ReadFruDataResponseData} containing FRU data - * @return list of {@link FruRecord}s containing decoded FRU data. - */ - @SuppressWarnings("unused") - public static List decodeFruData( - List fruData) { - - int size = 0; - - ArrayList list = new ArrayList(); - - for (ReadFruDataResponseData responseData : fruData) { - size += responseData.getFruData().length; - } - - byte[] data = new byte[size]; - - int offset = 0; - - for (ReadFruDataResponseData responseData : fruData) { - int length = responseData.getFruData().length; - System.arraycopy(responseData.getFruData(), 0, data, offset, length); - offset += length; - } - - if (data[0] == 0x1) { - - int chassisOffset = TypeConverter.byteToInt(data[2]) * 8; - int boardOffset = TypeConverter.byteToInt(data[3]) * 8; - int productInfoOffset = TypeConverter.byteToInt(data[4]) * 8; - int multiRecordOffset = TypeConverter.byteToInt(data[5]) * 8; - - if (chassisOffset != 0) { - list.add(new ChassisInfo(data, chassisOffset)); - } - if (boardOffset != 0) { - list.add(new BoardInfo(data, boardOffset)); - } - if (productInfoOffset != 0) { - list.add(new ProductInfo(data, productInfoOffset)); - } - if (multiRecordOffset != 0) { - addMultirecords(list, data, multiRecordOffset); - } - } else if (false) { - // TODO: Recognize SPD record (returned from DIMM FRUs) - } else { - throw new IllegalArgumentException("Invalid format version: " + data[0]); - } - - return list; - } - - private static void addMultirecords(ArrayList list, byte[] data, int multiRecordOffset) { - int currentMultirecordOffset = multiRecordOffset; - - while ((TypeConverter.byteToInt(data[currentMultirecordOffset + 1]) & 0x80) == 0) { - list.add(MultiRecordInfo.populateMultiRecord(data, currentMultirecordOffset)); - currentMultirecordOffset += TypeConverter.byteToInt(data[currentMultirecordOffset + 2]) + 5; - } - } + private int offset; + + private int size; + + private int fruId; + + /** + * Initiates ReadFruData for both encoding and decoding. Sets session + * parameters to default. + * + * @see IpmiCommandCoder#setSessionParameters(IpmiVersion, CipherSuite, + * AuthenticationType) + * @param fruId + * - ID of the FRU to get info from. Must be less than 256. To + * get FRU ID use {@link GetSdr} to retrieve + * {@link FruDeviceLocatorRecord}. + * @param unit + * - {@link BaseUnit} indicating if the FRU device is accessed in + * {@link BaseUnit#Bytes} or {@link BaseUnit#Words} + * @param offset + * - offset to read in units specified by unit + * @param countToRead + * - size of the area to read in unit. Cannot exceed 255; + */ + public ReadFruData(int fruId, BaseUnit unit, int offset, int countToRead) { + super(); + + if (countToRead > 255) { + throw new IllegalArgumentException( + "Count to read cannot exceed 255"); + } + + if (fruId > 255) { + throw new IllegalArgumentException("FRU ID cannot exceed 255"); + } + + this.offset = offset * unit.getSize(); + + size = countToRead * unit.getSize(); + + this.fruId = fruId; + // TODO: Check if Count To Read field is encoded in words if the FRU is + // addressed in words (requires different server settings). + } + + /** + * Initiates ReadFruData for both encoding and decoding. + * + * @param version + * - IPMI version of the command. + * @param cipherSuite + * - {@link CipherSuite} containing authentication, + * confidentiality and integrity algorithms for this session. + * @param authenticationType + * - Type of authentication used. Must be RMCPPlus for IPMI v2.0. + * @param fruId + * - ID of the FRU to get info from. Must be less than 256. To + * get FRU ID use {@link GetSdr} to retrieve + * {@link FruDeviceLocatorRecord}. + * @param unit + * - {@link BaseUnit} indicating if the FRU device is accessed in + * {@link BaseUnit#Bytes} or {@link BaseUnit#Words} + * @param offset + * - offset to read in units specified by unit + * @param countToRead + * - size of the area to read in unit. Cannot exceed 255; + */ + public ReadFruData(IpmiVersion version, CipherSuite cipherSuite, + AuthenticationType authenticationType, int fruId, BaseUnit unit, + int offset, int countToRead) { + super(version, cipherSuite, authenticationType); + + if (countToRead > 255) { + throw new IllegalArgumentException( + "Count to read cannot exceed 255"); + } + + if (fruId > 255) { + throw new IllegalArgumentException("FRU ID cannot exceed 255"); + } + + this.offset = offset * unit.getSize(); + + size = countToRead * unit.getSize(); + + this.fruId = fruId; + // TODO: Check if Count To Read field is encoded in words if the FRU is + // addressed in words (requires different server settings). + } + + @Override + public byte getCommandCode() { + return CommandCodes.READ_FRU_DATA; + } + + @Override + public NetworkFunction getNetworkFunction() { + return NetworkFunction.StorageRequest; + } + + @Override + protected IpmiPayload preparePayload(int sequenceNumber) + throws NoSuchAlgorithmException, + InvalidKeyException { + byte[] payload = new byte[4]; + payload[0] = TypeConverter.intToByte(fruId); + byte[] buffer = TypeConverter.intToLittleEndianByteArray(offset); + payload[1] = buffer[0]; + payload[2] = buffer[1]; + payload[3] = TypeConverter.intToByte(size); + + return new IpmiLanRequest( + getNetworkFunction(), + getCommandCode(), + payload, + TypeConverter.intToByte(sequenceNumber)); + } + + @Override + public ResponseData getResponseData(IpmiMessage message) + throws IPMIException, + NoSuchAlgorithmException, + InvalidKeyException { + + if (!isCommandResponse(message)) { + throw new IllegalArgumentException( + "This is not a response for Get SDR Repository Info command"); + } + if (!(message.getPayload() instanceof IpmiLanResponse)) { + throw new IllegalArgumentException("Invalid response payload"); + } + if (((IpmiLanResponse) message.getPayload()).getCompletionCode() != CompletionCode.Ok) { + throw new IPMIException( + ((IpmiLanResponse) message.getPayload()) + .getCompletionCode()); + } + + byte[] raw = message.getPayload().getIpmiCommandData(); + + if (raw == null || raw.length < 2) { + throw new IllegalArgumentException( + "Invalid response payload length"); + } + + ReadFruDataResponseData responseData = new ReadFruDataResponseData(); + + int sizeFromResponse = TypeConverter.byteToInt(raw[0]); + + byte[] fruData = new byte[sizeFromResponse]; + + System.arraycopy(raw, 1, fruData, 0, sizeFromResponse); + + responseData.setFruData(fruData); + + return responseData; + } + + /** + * Decodes {@link FruRecord}s from data provided by {@link ReadFruData} + * command. Size of the FRU Inventory Area might exceed size of the + * communication packet so it might come in many + * {@link ReadFruDataResponseData} packets. + * + * @param fruData + * - list of {@link ReadFruDataResponseData} containing FRU data + * @return list of {@link FruRecord}s containing decoded FRU data. + */ + @SuppressWarnings("unused") + public static List decodeFruData( + List fruData) { + + int size = 0; + + ArrayList list = new ArrayList(); + + for (ReadFruDataResponseData responseData : fruData) { + size += responseData.getFruData().length; + } + + byte[] data = new byte[size]; + + int offset = 0; + + for (ReadFruDataResponseData responseData : fruData) { + int length = responseData.getFruData().length; + System.arraycopy(responseData.getFruData(), 0, data, offset, length); + offset += length; + } + + if (data[0] == 0x1) { + + int chassisOffset = TypeConverter.byteToInt(data[2]) * 8; + int boardOffset = TypeConverter.byteToInt(data[3]) * 8; + int productInfoOffset = TypeConverter.byteToInt(data[4]) * 8; + int multiRecordOffset = TypeConverter.byteToInt(data[5]) * 8; + + if (chassisOffset != 0) { + list.add(new ChassisInfo(data, chassisOffset)); + } + if (boardOffset != 0) { + list.add(new BoardInfo(data, boardOffset)); + } + if (productInfoOffset != 0) { + list.add(new ProductInfo(data, productInfoOffset)); + } + if (multiRecordOffset != 0) { + addMultirecords(list, data, multiRecordOffset); + } + } else if (false) { + // TODO: Recognize SPD record (returned from DIMM FRUs) + } else { + throw new IllegalArgumentException("Invalid format version: " + data[0]); + } + + return list; + } + + private static void addMultirecords(ArrayList list, byte[] data, int multiRecordOffset) { + int currentMultirecordOffset = multiRecordOffset; + + while ((TypeConverter.byteToInt(data[currentMultirecordOffset + 1]) & 0x80) == 0) { + list.add(MultiRecordInfo.populateMultiRecord(data, currentMultirecordOffset)); + currentMultirecordOffset += TypeConverter.byteToInt(data[currentMultirecordOffset + 2]) + 5; + } + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/ReadFruDataResponseData.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/ReadFruDataResponseData.java index ed7fc22..2107083 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/ReadFruDataResponseData.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/ReadFruDataResponseData.java @@ -31,13 +31,13 @@ * decoded by {@link ReadFruData#decodeFruData(java.util.List)}. */ public class ReadFruDataResponseData implements ResponseData { - private byte[] fruData; + private byte[] fruData; - public void setFruData(byte[] fruData) { - this.fruData = fruData; - } + public void setFruData(byte[] fruData) { + this.fruData = fruData; + } - public byte[] getFruData() { - return fruData; - } + public byte[] getFruData() { + return fruData; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/BaseCompatibilityInfo.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/BaseCompatibilityInfo.java index 2ae2978..762d0de 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/BaseCompatibilityInfo.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/BaseCompatibilityInfo.java @@ -30,82 +30,84 @@ */ public class BaseCompatibilityInfo extends MultiRecordInfo { - private int manufacturerId; - - private EntityId entityId; - - private int compatibilityBase; - - private int codeStart; - - private byte[] codeRangeMasks; - - /** - * Creates and populates record - * - * @param fruData - * - raw data containing record - * @param offset - * - offset to the record in the data - * @param length - * - length of the record - */ - public BaseCompatibilityInfo(byte[] fruData, int offset, int length) { - super(); - // TODO: Test when server containing such records will be available - - byte[] buffer = new byte[4]; - - System.arraycopy(fruData, offset, buffer, 0, 3); - buffer[3] = 0; - - manufacturerId = TypeConverter.littleEndianByteArrayToInt(buffer); - entityId = EntityId.parseInt(TypeConverter - .byteToInt(fruData[offset + 3])); - compatibilityBase = TypeConverter.byteToInt(fruData[offset + 4]); - codeStart = TypeConverter.byteToInt(fruData[offset + 5]) & 0x7f; - codeRangeMasks = new byte[length - 6]; - System.arraycopy(fruData, 6, codeRangeMasks, 0, length - 6); - } - - public int getManufacturerId() { - return manufacturerId; - } - - public void setManufacturerId(int manufacturerId) { - this.manufacturerId = manufacturerId; - } - - public EntityId getEntityId() { - return entityId; - } - - public void setEntityId(EntityId entityId) { - this.entityId = entityId; - } - - public int getCompatibilityBase() { - return compatibilityBase; - } - - public void setCompatibilityBase(int compatibilityBase) { - this.compatibilityBase = compatibilityBase; - } - - public int getCodeStart() { - return codeStart; - } - - public void setCodeStart(int codeStart) { - this.codeStart = codeStart; - } - - public byte[] getCodeRangeMasks() { - return codeRangeMasks; - } - - public void setCodeRangeMasks(byte[] codeRangeMasks) { - this.codeRangeMasks = codeRangeMasks; - } + private int manufacturerId; + + private EntityId entityId; + + private int compatibilityBase; + + private int codeStart; + + private byte[] codeRangeMasks; + + /** + * Creates and populates record + * + * @param fruData + * - raw data containing record + * @param offset + * - offset to the record in the data + * @param length + * - length of the record + */ + public BaseCompatibilityInfo(byte[] fruData, int offset, int length) { + super(); + // TODO: Test when server containing such records will be available + + byte[] buffer = new byte[4]; + + System.arraycopy(fruData, offset, buffer, 0, 3); + buffer[3] = 0; + + manufacturerId = TypeConverter.littleEndianByteArrayToInt(buffer); + entityId = EntityId + .parseInt( + TypeConverter + .byteToInt(fruData[offset + 3])); + compatibilityBase = TypeConverter.byteToInt(fruData[offset + 4]); + codeStart = TypeConverter.byteToInt(fruData[offset + 5]) & 0x7f; + codeRangeMasks = new byte[length - 6]; + System.arraycopy(fruData, 6, codeRangeMasks, 0, length - 6); + } + + public int getManufacturerId() { + return manufacturerId; + } + + public void setManufacturerId(int manufacturerId) { + this.manufacturerId = manufacturerId; + } + + public EntityId getEntityId() { + return entityId; + } + + public void setEntityId(EntityId entityId) { + this.entityId = entityId; + } + + public int getCompatibilityBase() { + return compatibilityBase; + } + + public void setCompatibilityBase(int compatibilityBase) { + this.compatibilityBase = compatibilityBase; + } + + public int getCodeStart() { + return codeStart; + } + + public void setCodeStart(int codeStart) { + this.codeStart = codeStart; + } + + public byte[] getCodeRangeMasks() { + return codeRangeMasks; + } + + public void setCodeRangeMasks(byte[] codeRangeMasks) { + this.codeRangeMasks = codeRangeMasks; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/BoardInfo.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/BoardInfo.java index 2dd007c..7d630d7 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/BoardInfo.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/BoardInfo.java @@ -40,192 +40,226 @@ */ public class BoardInfo extends FruRecord { - private Date mfgDate; + private Date mfgDate; - private String boardManufacturer = ""; + private String boardManufacturer = ""; - private String boardProductName = ""; + private String boardProductName = ""; - private String boardSerialNumber = ""; - - private String boardPartNumber = ""; - - private byte[] fruFileId = new byte[0]; - - private String[] customBoardInfo = new String[0]; - - private static Logger logger = LoggerFactory.getLogger(BoardInfo.class); - - /** - * Creates and populates record - * - * @param fruData - * - raw data containing record - * @param offset - * - offset to the record in the data - */ - public BoardInfo(final byte[] fruData, final int offset) { - validateFruData(fruData[offset]); - - int languageCode = TypeConverter.byteToInt(fruData[offset + 2]); - - byte[] buffer = new byte[4]; - - buffer[0] = fruData[offset + 3]; - buffer[1] = fruData[offset + 4]; - buffer[2] = fruData[offset + 5]; - buffer[3] = 0; - - DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, - Locale.ENGLISH); - try { - setMfgDate(new Date(df.parse("01/01/96").getTime() - + ((long) TypeConverter.littleEndianByteArrayToInt(buffer)) - * 60000l)); - } catch (ParseException e) { - logger.error(e.getMessage(), e); - } - - int partNumber = TypeConverter.byteToInt(fruData[offset + 6]); - - ArrayList customInfo = readCustomInfo(fruData, languageCode, partNumber, offset + 7); - - customBoardInfo = new String[customInfo.size()]; - customBoardInfo = customInfo.toArray(customBoardInfo); - } - - private void validateFruData(byte fruDatum) { - if (fruDatum != 0x1) { - throw new IllegalArgumentException("Invalid format version"); - } - } - - private ArrayList readCustomInfo(final byte[] fruData, final int languageCode, final int partNumber, final int offset) { - ArrayList customInfo = new ArrayList(); - int index = 0; - - int currentOffset = offset; - int currentPartNumber = partNumber; - - while (currentPartNumber != 0xc1 && currentOffset < fruData.length) { - - int partType = (currentPartNumber & 0xc0) >> 6; - - int partDataLength = (currentPartNumber & 0x3f); - - if (partDataLengthWithinBounds(fruData, currentOffset, partDataLength)) { - - byte[] partNumberData = new byte[partDataLength]; - - System.arraycopy(fruData, currentOffset, partNumberData, 0, - partDataLength); - - currentOffset += partDataLength; - - switch (index) { - case 0: - setBoardManufacturer(FruRecord.decodeString(partType, - partNumberData, languageCode != 0 - && languageCode != 25)); - break; - case 1: - setBoardProductName(FruRecord.decodeString(partType, - partNumberData, languageCode != 0 - && languageCode != 25)); - break; - case 2: - setBoardSerialNumber(FruRecord.decodeString(partType, - partNumberData, true)); - break; - case 3: - setBoardPartNumber(FruRecord.decodeString(partType, - partNumberData, languageCode != 0 - && languageCode != 25)); - break; - case 4: - setFruFileId(partNumberData); - break; - default: - if (partDataLength == 0) { - currentPartNumber = TypeConverter.byteToInt(fruData[currentOffset]); - ++currentOffset; - continue; - } - customInfo.add(FruRecord.decodeString(partType, - partNumberData, languageCode != 0 - && languageCode != 25)); - break; - } - } - - currentPartNumber = TypeConverter.byteToInt(fruData[currentOffset]); - - ++currentOffset; - - ++index; - } - - return customInfo; - } - - private boolean partDataLengthWithinBounds(byte[] fruData, int currentOfset, int partDataLength) { - return partDataLength > 0 && partDataLength + currentOfset < fruData.length; - } - - public Date getMfgDate() { - return mfgDate; - } - - public void setMfgDate(Date mfgDate) { - this.mfgDate = mfgDate; - } - - public String getBoardManufacturer() { - return boardManufacturer; - } - - public void setBoardManufacturer(String boardManufacturer) { - this.boardManufacturer = boardManufacturer; - } - - public String getBoardProductName() { - return boardProductName; - } - - public void setBoardProductName(String boardProductName) { - this.boardProductName = boardProductName; - } - - public String getBoardSerialNumber() { - return boardSerialNumber; - } - - public void setBoardSerialNumber(String boardSerialNumber) { - this.boardSerialNumber = boardSerialNumber; - } - - public String getBoardPartNumber() { - return boardPartNumber; - } - - public void setBoardPartNumber(String boardPartNumber) { - this.boardPartNumber = boardPartNumber; - } - - public byte[] getFruFileId() { - return fruFileId; - } - - public void setFruFileId(byte[] fruFileId) { - this.fruFileId = fruFileId; - } - - public String[] getCustomBoardInfo() { - return customBoardInfo; - } - - public void setCustomBoardInfo(String[] customBoardInfo) { - this.customBoardInfo = customBoardInfo; - } + private String boardSerialNumber = ""; + + private String boardPartNumber = ""; + + private byte[] fruFileId = new byte[0]; + + private String[] customBoardInfo = new String[0]; + + private static Logger logger = LoggerFactory.getLogger(BoardInfo.class); + + /** + * Creates and populates record + * + * @param fruData + * - raw data containing record + * @param offset + * - offset to the record in the data + */ + public BoardInfo(final byte[] fruData, final int offset) { + validateFruData(fruData[offset]); + + int languageCode = TypeConverter.byteToInt(fruData[offset + 2]); + + byte[] buffer = new byte[4]; + + buffer[0] = fruData[offset + 3]; + buffer[1] = fruData[offset + 4]; + buffer[2] = fruData[offset + 5]; + buffer[3] = 0; + + DateFormat df = DateFormat + .getDateInstance( + DateFormat.SHORT, + Locale.ENGLISH); + try { + setMfgDate( + new Date( + df.parse("01/01/96").getTime() + + ((long) TypeConverter.littleEndianByteArrayToInt(buffer)) + * 60000L)); + } catch (ParseException e) { + logger.error(e.getMessage(), e); + } + + int partNumber = TypeConverter.byteToInt(fruData[offset + 6]); + + ArrayList customInfo = readCustomInfo(fruData, languageCode, partNumber, offset + 7); + + customBoardInfo = new String[customInfo.size()]; + customBoardInfo = customInfo.toArray(customBoardInfo); + } + + private void validateFruData(byte fruDatum) { + if (fruDatum != 0x1) { + throw new IllegalArgumentException("Invalid format version"); + } + } + + private ArrayList readCustomInfo( + final byte[] fruData, + final int languageCode, + final int partNumber, + final int offset) { + ArrayList customInfo = new ArrayList(); + int index = 0; + + int currentOffset = offset; + int currentPartNumber = partNumber; + + while (currentPartNumber != 0xc1 && currentOffset < fruData.length) { + + int partType = (currentPartNumber & 0xc0) >> 6; + + int partDataLength = (currentPartNumber & 0x3f); + + if (partDataLengthWithinBounds(fruData, currentOffset, partDataLength)) { + + byte[] partNumberData = new byte[partDataLength]; + + System + .arraycopy( + fruData, + currentOffset, + partNumberData, + 0, + partDataLength); + + currentOffset += partDataLength; + + switch (index) { + case 0: + setBoardManufacturer( + FruRecord + .decodeString( + partType, + partNumberData, + languageCode != 0 + && languageCode != 25)); + break; + case 1: + setBoardProductName( + FruRecord + .decodeString( + partType, + partNumberData, + languageCode != 0 + && languageCode != 25)); + break; + case 2: + setBoardSerialNumber( + FruRecord + .decodeString( + partType, + partNumberData, + true)); + break; + case 3: + setBoardPartNumber( + FruRecord + .decodeString( + partType, + partNumberData, + languageCode != 0 + && languageCode != 25)); + break; + case 4: + setFruFileId(partNumberData); + break; + default: + if (partDataLength == 0) { + currentPartNumber = TypeConverter.byteToInt(fruData[currentOffset]); + ++currentOffset; + continue; + } + customInfo + .add( + FruRecord + .decodeString( + partType, + partNumberData, + languageCode != 0 + && languageCode != 25)); + break; + } + } + + currentPartNumber = TypeConverter.byteToInt(fruData[currentOffset]); + + ++currentOffset; + + ++index; + } + + return customInfo; + } + + private boolean partDataLengthWithinBounds(byte[] fruData, int currentOfset, int partDataLength) { + return partDataLength > 0 && partDataLength + currentOfset < fruData.length; + } + + public Date getMfgDate() { + return mfgDate; + } + + public void setMfgDate(Date mfgDate) { + this.mfgDate = mfgDate; + } + + public String getBoardManufacturer() { + return boardManufacturer; + } + + public void setBoardManufacturer(String boardManufacturer) { + this.boardManufacturer = boardManufacturer; + } + + public String getBoardProductName() { + return boardProductName; + } + + public void setBoardProductName(String boardProductName) { + this.boardProductName = boardProductName; + } + + public String getBoardSerialNumber() { + return boardSerialNumber; + } + + public void setBoardSerialNumber(String boardSerialNumber) { + this.boardSerialNumber = boardSerialNumber; + } + + public String getBoardPartNumber() { + return boardPartNumber; + } + + public void setBoardPartNumber(String boardPartNumber) { + this.boardPartNumber = boardPartNumber; + } + + public byte[] getFruFileId() { + return fruFileId; + } + + public void setFruFileId(byte[] fruFileId) { + this.fruFileId = fruFileId; + } + + public String[] getCustomBoardInfo() { + return customBoardInfo; + } + + public void setCustomBoardInfo(String[] customBoardInfo) { + this.customBoardInfo = customBoardInfo; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/ChassisInfo.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/ChassisInfo.java index 334a4b3..b412b81 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/ChassisInfo.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/ChassisInfo.java @@ -33,111 +33,131 @@ */ public class ChassisInfo extends FruRecord { - private ChassisType chassisType; - - private String chassisPartNumber = ""; - - private String chassisSerialNumber = ""; - - private String[] customChassisInfo = new String[0]; - - /** - * Creates and populates record - * - * @param fruData - * - raw data containing record - * @param offset - * - offset to the record in the data - */ - public ChassisInfo(final byte[] fruData, final int offset) { - super(); - - if (fruData[offset] != 0x1) { - throw new IllegalArgumentException("Invalid format version"); - } - - chassisType = ChassisType.parseInt(TypeConverter - .byteToInt(fruData[offset + 2])); - - int partNumber = TypeConverter.byteToInt(fruData[offset + 3]); - - int currentOffset = offset + 4; - - int index = 0; - - ArrayList customInfo = new ArrayList(); - - while (partNumber != 0xc1 && currentOffset < fruData.length) { - - int partType = (partNumber & 0xc0) >> 6; - - int partDataLength = (partNumber & 0x3f); - - if (partDataLength > 0 && partDataLength + currentOffset < fruData.length) { - - byte[] partNumberData = new byte[partDataLength]; - - System.arraycopy(fruData, currentOffset, partNumberData, 0, - partDataLength); - - currentOffset += partDataLength; - - switch (index) { - case 0: - setChassisPartNumber(FruRecord.decodeString(partType, - partNumberData, true)); - break; - case 1: - setChassisSerialNumber(FruRecord.decodeString(partType, - partNumberData, true)); - break; - default: - if (partDataLength == 0) { - continue; - } - customInfo.add(FruRecord.decodeString(partType, - partNumberData, true)); - break; - } - } - - partNumber = TypeConverter.byteToInt(fruData[currentOffset]); - - ++currentOffset; - - ++index; - } - - customChassisInfo = new String[customInfo.size()]; - customChassisInfo = customInfo.toArray(customChassisInfo); - } - - public ChassisType getChassisType() { - return chassisType; - } - - public void setChassisType(ChassisType chassisType) { - this.chassisType = chassisType; - } - - public String getChassisPartNumber() { - return chassisPartNumber; - } - - public void setChassisPartNumber(String chassisPartNumber) { - this.chassisPartNumber = chassisPartNumber; - } - - public String getChassisSerialNumber() { - return chassisSerialNumber; - } - - public void setChassisSerialNumber(String chassisSerialNumber) { - this.chassisSerialNumber = chassisSerialNumber; - } - - public String[] getCustomChassisInfo() { - return customChassisInfo; - } + private ChassisType chassisType; + + private String chassisPartNumber = ""; + + private String chassisSerialNumber = ""; + + private String[] customChassisInfo = new String[0]; + + /** + * Creates and populates record + * + * @param fruData + * - raw data containing record + * @param offset + * - offset to the record in the data + */ + public ChassisInfo(final byte[] fruData, final int offset) { + super(); + + if (fruData[offset] != 0x1) { + throw new IllegalArgumentException("Invalid format version"); + } + + chassisType = ChassisType + .parseInt( + TypeConverter + .byteToInt(fruData[offset + 2])); + + int partNumber = TypeConverter.byteToInt(fruData[offset + 3]); + + int currentOffset = offset + 4; + + int index = 0; + + ArrayList customInfo = new ArrayList(); + + while (partNumber != 0xc1 && currentOffset < fruData.length) { + + int partType = (partNumber & 0xc0) >> 6; + + int partDataLength = (partNumber & 0x3f); + + if (partDataLength > 0 && partDataLength + currentOffset < fruData.length) { + + byte[] partNumberData = new byte[partDataLength]; + + System + .arraycopy( + fruData, + currentOffset, + partNumberData, + 0, + partDataLength); + + currentOffset += partDataLength; + + switch (index) { + case 0: + setChassisPartNumber( + FruRecord + .decodeString( + partType, + partNumberData, + true)); + break; + case 1: + setChassisSerialNumber( + FruRecord + .decodeString( + partType, + partNumberData, + true)); + break; + default: + if (partDataLength == 0) { + continue; + } + customInfo + .add( + FruRecord + .decodeString( + partType, + partNumberData, + true)); + break; + } + } + + partNumber = TypeConverter.byteToInt(fruData[currentOffset]); + + ++currentOffset; + + ++index; + } + + customChassisInfo = new String[customInfo.size()]; + customChassisInfo = customInfo.toArray(customChassisInfo); + } + + public ChassisType getChassisType() { + return chassisType; + } + + public void setChassisType(ChassisType chassisType) { + this.chassisType = chassisType; + } + + public String getChassisPartNumber() { + return chassisPartNumber; + } + + public void setChassisPartNumber(String chassisPartNumber) { + this.chassisPartNumber = chassisPartNumber; + } + + public String getChassisSerialNumber() { + return chassisSerialNumber; + } + + public void setChassisSerialNumber(String chassisSerialNumber) { + this.chassisSerialNumber = chassisSerialNumber; + } + + public String[] getCustomChassisInfo() { + return customChassisInfo; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/ChassisType.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/ChassisType.java index 35dadfe..98b5cad 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/ChassisType.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/ChassisType.java @@ -30,123 +30,146 @@ */ public enum ChassisType { - Other(ChassisType.OTHER), Notebook(ChassisType.NOTEBOOK), HandHeld(ChassisType.HANDHELD), DockingStation( - ChassisType.DOCKINGSTATION), AllInOne(ChassisType.ALLINONE), SubNotebook(ChassisType.SUBNOTEBOOK), SpaceSaving( - ChassisType.SPACESAVING), LunchBox(ChassisType.LUNCHBOX), MainServerChassis(ChassisType.MAINSERVERCHASSIS), ExpansionChassis( - ChassisType.EXPANSIONCHASSIS), SubChassis(ChassisType.SUBCHASSIS), Unknown(ChassisType.UNKNOWN), BusExpansionChassis( - ChassisType.BUSEXPANSIONCHASSIS), PeripheralChassis(ChassisType.PERIPHERALCHASSIS), RaidChassis( - ChassisType.RAIDCHASSIS), RackMountChassis(ChassisType.RACKMOUNTCHASSIS), Desktop(ChassisType.DESKTOP), Low( - ChassisType.LOW), Pizza(ChassisType.PIZZA), Mini(ChassisType.MINI), Tower(ChassisType.TOWER), Portable( - ChassisType.PORTABLE), LapTop(ChassisType.LAPTOP), ; - private static final int OTHER = 1; - - private static final int NOTEBOOK = 10; - - private static final int HANDHELD = 11; - - private static final int DOCKINGSTATION = 12; - - private static final int ALLINONE = 13; - - private static final int SUBNOTEBOOK = 14; - - private static final int SPACESAVING = 15; - - private static final int LUNCHBOX = 16; - - private static final int MAINSERVERCHASSIS = 17; - - private static final int EXPANSIONCHASSIS = 18; - - private static final int SUBCHASSIS = 19; - - private static final int UNKNOWN = 2; - - private static final int BUSEXPANSIONCHASSIS = 20; - - private static final int PERIPHERALCHASSIS = 21; - - private static final int RAIDCHASSIS = 22; - - private static final int RACKMOUNTCHASSIS = 23; - - private static final int DESKTOP = 3; - - private static final int LOW = 4; - - private static final int PIZZA = 5; - - private static final int MINI = 6; - - private static final int TOWER = 7; - - private static final int PORTABLE = 8; - - private static final int LAPTOP = 9; - - private int code; - - private static Logger logger = LoggerFactory.getLogger(ChassisType.class); - - ChassisType(int code) { - this.code = code; - } - - public int getCode() { - return code; - } - - public static ChassisType parseInt(int value) { - switch (value) { - case OTHER: - return Other; - case NOTEBOOK: - return Notebook; - case HANDHELD: - return HandHeld; - case DOCKINGSTATION: - return DockingStation; - case ALLINONE: - return AllInOne; - case SUBNOTEBOOK: - return SubNotebook; - case SPACESAVING: - return SpaceSaving; - case LUNCHBOX: - return LunchBox; - case MAINSERVERCHASSIS: - return MainServerChassis; - case EXPANSIONCHASSIS: - return ExpansionChassis; - case SUBCHASSIS: - return SubChassis; - case UNKNOWN: - return Unknown; - case BUSEXPANSIONCHASSIS: - return BusExpansionChassis; - case PERIPHERALCHASSIS: - return PeripheralChassis; - case RAIDCHASSIS: - return RaidChassis; - case RACKMOUNTCHASSIS: - return RackMountChassis; - case DESKTOP: - return Desktop; - case LOW: - return Low; - case PIZZA: - return Pizza; - case MINI: - return Mini; - case TOWER: - return Tower; - case PORTABLE: - return Portable; - case LAPTOP: - return LapTop; - default: - logger.error("Invalid value: " + value); - return Other; - } - } + Other(ChassisType.OTHER), + Notebook(ChassisType.NOTEBOOK), + HandHeld(ChassisType.HANDHELD), + DockingStation( + ChassisType.DOCKINGSTATION), + AllInOne(ChassisType.ALLINONE), + SubNotebook(ChassisType.SUBNOTEBOOK), + SpaceSaving( + ChassisType.SPACESAVING), + LunchBox(ChassisType.LUNCHBOX), + MainServerChassis(ChassisType.MAINSERVERCHASSIS), + ExpansionChassis( + ChassisType.EXPANSIONCHASSIS), + SubChassis(ChassisType.SUBCHASSIS), + Unknown(ChassisType.UNKNOWN), + BusExpansionChassis( + ChassisType.BUSEXPANSIONCHASSIS), + PeripheralChassis(ChassisType.PERIPHERALCHASSIS), + RaidChassis( + ChassisType.RAIDCHASSIS), + RackMountChassis(ChassisType.RACKMOUNTCHASSIS), + Desktop(ChassisType.DESKTOP), + Low( + ChassisType.LOW), + Pizza(ChassisType.PIZZA), + Mini(ChassisType.MINI), + Tower(ChassisType.TOWER), + Portable( + ChassisType.PORTABLE), + LapTop(ChassisType.LAPTOP),; + + private static final int OTHER = 1; + + private static final int NOTEBOOK = 10; + + private static final int HANDHELD = 11; + + private static final int DOCKINGSTATION = 12; + + private static final int ALLINONE = 13; + + private static final int SUBNOTEBOOK = 14; + + private static final int SPACESAVING = 15; + + private static final int LUNCHBOX = 16; + + private static final int MAINSERVERCHASSIS = 17; + + private static final int EXPANSIONCHASSIS = 18; + + private static final int SUBCHASSIS = 19; + + private static final int UNKNOWN = 2; + + private static final int BUSEXPANSIONCHASSIS = 20; + + private static final int PERIPHERALCHASSIS = 21; + + private static final int RAIDCHASSIS = 22; + + private static final int RACKMOUNTCHASSIS = 23; + + private static final int DESKTOP = 3; + + private static final int LOW = 4; + + private static final int PIZZA = 5; + + private static final int MINI = 6; + + private static final int TOWER = 7; + + private static final int PORTABLE = 8; + + private static final int LAPTOP = 9; + + private int code; + + private static Logger logger = LoggerFactory.getLogger(ChassisType.class); + + ChassisType(int code) { + this.code = code; + } + + public int getCode() { + return code; + } + + public static ChassisType parseInt(int value) { + switch (value) { + case OTHER: + return Other; + case NOTEBOOK: + return Notebook; + case HANDHELD: + return HandHeld; + case DOCKINGSTATION: + return DockingStation; + case ALLINONE: + return AllInOne; + case SUBNOTEBOOK: + return SubNotebook; + case SPACESAVING: + return SpaceSaving; + case LUNCHBOX: + return LunchBox; + case MAINSERVERCHASSIS: + return MainServerChassis; + case EXPANSIONCHASSIS: + return ExpansionChassis; + case SUBCHASSIS: + return SubChassis; + case UNKNOWN: + return Unknown; + case BUSEXPANSIONCHASSIS: + return BusExpansionChassis; + case PERIPHERALCHASSIS: + return PeripheralChassis; + case RAIDCHASSIS: + return RaidChassis; + case RACKMOUNTCHASSIS: + return RackMountChassis; + case DESKTOP: + return Desktop; + case LOW: + return Low; + case PIZZA: + return Pizza; + case MINI: + return Mini; + case TOWER: + return Tower; + case PORTABLE: + return Portable; + case LAPTOP: + return LapTop; + default: + logger.error("Invalid value: " + value); + return Other; + } + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/DcLoadInfo.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/DcLoadInfo.java index 3306c2b..a9b7768 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/DcLoadInfo.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/DcLoadInfo.java @@ -31,112 +31,112 @@ */ public class DcLoadInfo extends MultiRecordInfo { - private int outputNumber; - - /** - * The unit is 10mV. - */ - private int nominalVoltage; - - /** - * The unit is 10mV. - */ - private int minimumVoltage; - - /** - * The unit is 10mV. - */ - private int maximumVoltage; - - /** - * The unit is 10mA. - */ - private int minimumCurrentLoad; - - /** - * The unit is 10mA. - */ - private int maximumCurrentLoad; - - /** - * Creates and populates record - * - * @param fruData - * - raw data containing record - * @param offset - * - offset to the record in the data - */ - public DcLoadInfo(byte[] fruData, int offset) { - super(); - // TODO: Test when server containing such records will be available - - outputNumber = TypeConverter.byteToInt(fruData[offset]) & 0xf; - - nominalVoltage = TypeConverter.byteToInt(fruData[offset+1]); - nominalVoltage |= TypeConverter.byteToInt(fruData[offset+2]) << 8; - nominalVoltage = TypeConverter.decode2sComplement(nominalVoltage, 15); - - minimumVoltage = TypeConverter.byteToInt(fruData[offset+3]); - minimumVoltage |= TypeConverter.byteToInt(fruData[offset+4]) << 8; - minimumVoltage = TypeConverter.decode2sComplement(minimumVoltage, 15); - - maximumVoltage = TypeConverter.byteToInt(fruData[offset+5]); - maximumVoltage |= TypeConverter.byteToInt(fruData[offset+6]) << 8; - maximumVoltage = TypeConverter.decode2sComplement(maximumVoltage, 15); - - minimumCurrentLoad = TypeConverter.byteToInt(fruData[offset+9]); - minimumCurrentLoad |= TypeConverter.byteToInt(fruData[offset+10]) << 8; - - maximumCurrentLoad = TypeConverter.byteToInt(fruData[offset+11]); - maximumCurrentLoad |= TypeConverter.byteToInt(fruData[offset+12]) << 8; - } - - public int getOutputNumber() { - return outputNumber; - } - - public void setOutputNumber(int outputNumber) { - this.outputNumber = outputNumber; - } - - public int getNominalVoltage() { - return nominalVoltage; - } - - public void setNominalVoltage(int nominalVoltage) { - this.nominalVoltage = nominalVoltage; - } - - public int getMaximumVoltage() { - return maximumVoltage; - } - - public void setMaximumVoltage(int maximumVoltage) { - this.maximumVoltage = maximumVoltage; - } - - public int getMinimumVoltage() { - return minimumVoltage; - } - - public void setMinimumVoltage(int minimumVoltage) { - this.minimumVoltage = minimumVoltage; - } - - public int getMaximumCurrentLoad() { - return maximumCurrentLoad; - } - - public void setMaximumCurrentLoad(int maximumCurrentLoad) { - this.maximumCurrentLoad = maximumCurrentLoad; - } - - public int getMinimumCurrentLoad() { - return minimumCurrentLoad; - } - - public void setMinimumCurrentLoad(int minimumCurrentLoad) { - this.minimumCurrentLoad = minimumCurrentLoad; - } + private int outputNumber; + + /** + * The unit is 10mV. + */ + private int nominalVoltage; + + /** + * The unit is 10mV. + */ + private int minimumVoltage; + + /** + * The unit is 10mV. + */ + private int maximumVoltage; + + /** + * The unit is 10mA. + */ + private int minimumCurrentLoad; + + /** + * The unit is 10mA. + */ + private int maximumCurrentLoad; + + /** + * Creates and populates record + * + * @param fruData + * - raw data containing record + * @param offset + * - offset to the record in the data + */ + public DcLoadInfo(byte[] fruData, int offset) { + super(); + // TODO: Test when server containing such records will be available + + outputNumber = TypeConverter.byteToInt(fruData[offset]) & 0xf; + + nominalVoltage = TypeConverter.byteToInt(fruData[offset + 1]); + nominalVoltage |= TypeConverter.byteToInt(fruData[offset + 2]) << 8; + nominalVoltage = TypeConverter.decode2sComplement(nominalVoltage, 15); + + minimumVoltage = TypeConverter.byteToInt(fruData[offset + 3]); + minimumVoltage |= TypeConverter.byteToInt(fruData[offset + 4]) << 8; + minimumVoltage = TypeConverter.decode2sComplement(minimumVoltage, 15); + + maximumVoltage = TypeConverter.byteToInt(fruData[offset + 5]); + maximumVoltage |= TypeConverter.byteToInt(fruData[offset + 6]) << 8; + maximumVoltage = TypeConverter.decode2sComplement(maximumVoltage, 15); + + minimumCurrentLoad = TypeConverter.byteToInt(fruData[offset + 9]); + minimumCurrentLoad |= TypeConverter.byteToInt(fruData[offset + 10]) << 8; + + maximumCurrentLoad = TypeConverter.byteToInt(fruData[offset + 11]); + maximumCurrentLoad |= TypeConverter.byteToInt(fruData[offset + 12]) << 8; + } + + public int getOutputNumber() { + return outputNumber; + } + + public void setOutputNumber(int outputNumber) { + this.outputNumber = outputNumber; + } + + public int getNominalVoltage() { + return nominalVoltage; + } + + public void setNominalVoltage(int nominalVoltage) { + this.nominalVoltage = nominalVoltage; + } + + public int getMaximumVoltage() { + return maximumVoltage; + } + + public void setMaximumVoltage(int maximumVoltage) { + this.maximumVoltage = maximumVoltage; + } + + public int getMinimumVoltage() { + return minimumVoltage; + } + + public void setMinimumVoltage(int minimumVoltage) { + this.minimumVoltage = minimumVoltage; + } + + public int getMaximumCurrentLoad() { + return maximumCurrentLoad; + } + + public void setMaximumCurrentLoad(int maximumCurrentLoad) { + this.maximumCurrentLoad = maximumCurrentLoad; + } + + public int getMinimumCurrentLoad() { + return minimumCurrentLoad; + } + + public void setMinimumCurrentLoad(int minimumCurrentLoad) { + this.minimumCurrentLoad = minimumCurrentLoad; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/DcOutputInfo.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/DcOutputInfo.java index 67b253b..32bb850 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/DcOutputInfo.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/DcOutputInfo.java @@ -29,80 +29,80 @@ */ public class DcOutputInfo extends MultiRecordInfo { - private int outputNumber; - - /** - * The unit is 10mV. - */ - private int nominalVoltage; - - /** - * The unit is 10mV. - */ - private int maximumNegativeDeviation; - - /** - * The unit is 10mV. - */ - private int maximumPositiveDeviation; - - /** - * Creates and populates record - * - * @param fruData - * - raw data containing record - * @param offset - * - offset to the record in the data - */ - public DcOutputInfo(byte[] fruData, int offset) { - super(); - // TODO: Test when server containing such records will be available - - outputNumber = TypeConverter.byteToInt(fruData[offset]) & 0xf; - - nominalVoltage = TypeConverter.byteToInt(fruData[offset+1]); - nominalVoltage |= TypeConverter.byteToInt(fruData[offset+2]) << 8; - nominalVoltage = TypeConverter.decode2sComplement(nominalVoltage, 15); - - maximumNegativeDeviation = TypeConverter.byteToInt(fruData[offset+3]); - maximumNegativeDeviation |= TypeConverter.byteToInt(fruData[offset+4]) << 8; - maximumNegativeDeviation = TypeConverter.decode2sComplement(maximumNegativeDeviation, 15); - - maximumPositiveDeviation = TypeConverter.byteToInt(fruData[offset+5]); - maximumPositiveDeviation |= TypeConverter.byteToInt(fruData[offset+6]) << 8; - maximumPositiveDeviation = TypeConverter.decode2sComplement(maximumPositiveDeviation, 15); - } - - public int getOutputNumber() { - return outputNumber; - } - - public void setOutputNumber(int outputNumber) { - this.outputNumber = outputNumber; - } - - public int getNominalVoltage() { - return nominalVoltage; - } - - public void setNominalVoltage(int nominalVoltage) { - this.nominalVoltage = nominalVoltage; - } - - public int getMaximumNegativeDeviation() { - return maximumNegativeDeviation; - } - - public void setMaximumNegativeDeviation(int maximumNegativeDeviation) { - this.maximumNegativeDeviation = maximumNegativeDeviation; - } - - public int getMaximumPositiveDeviation() { - return maximumPositiveDeviation; - } - - public void setMaximumPositiveDeviation(int maximumPositiveDeviation) { - this.maximumPositiveDeviation = maximumPositiveDeviation; - } + private int outputNumber; + + /** + * The unit is 10mV. + */ + private int nominalVoltage; + + /** + * The unit is 10mV. + */ + private int maximumNegativeDeviation; + + /** + * The unit is 10mV. + */ + private int maximumPositiveDeviation; + + /** + * Creates and populates record + * + * @param fruData + * - raw data containing record + * @param offset + * - offset to the record in the data + */ + public DcOutputInfo(byte[] fruData, int offset) { + super(); + // TODO: Test when server containing such records will be available + + outputNumber = TypeConverter.byteToInt(fruData[offset]) & 0xf; + + nominalVoltage = TypeConverter.byteToInt(fruData[offset + 1]); + nominalVoltage |= TypeConverter.byteToInt(fruData[offset + 2]) << 8; + nominalVoltage = TypeConverter.decode2sComplement(nominalVoltage, 15); + + maximumNegativeDeviation = TypeConverter.byteToInt(fruData[offset + 3]); + maximumNegativeDeviation |= TypeConverter.byteToInt(fruData[offset + 4]) << 8; + maximumNegativeDeviation = TypeConverter.decode2sComplement(maximumNegativeDeviation, 15); + + maximumPositiveDeviation = TypeConverter.byteToInt(fruData[offset + 5]); + maximumPositiveDeviation |= TypeConverter.byteToInt(fruData[offset + 6]) << 8; + maximumPositiveDeviation = TypeConverter.decode2sComplement(maximumPositiveDeviation, 15); + } + + public int getOutputNumber() { + return outputNumber; + } + + public void setOutputNumber(int outputNumber) { + this.outputNumber = outputNumber; + } + + public int getNominalVoltage() { + return nominalVoltage; + } + + public void setNominalVoltage(int nominalVoltage) { + this.nominalVoltage = nominalVoltage; + } + + public int getMaximumNegativeDeviation() { + return maximumNegativeDeviation; + } + + public void setMaximumNegativeDeviation(int maximumNegativeDeviation) { + this.maximumNegativeDeviation = maximumNegativeDeviation; + } + + public int getMaximumPositiveDeviation() { + return maximumPositiveDeviation; + } + + public void setMaximumPositiveDeviation(int maximumPositiveDeviation) { + this.maximumPositiveDeviation = maximumPositiveDeviation; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/ExtendedCompatibilityInfo.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/ExtendedCompatibilityInfo.java index 96e772c..36dece4 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/ExtendedCompatibilityInfo.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/ExtendedCompatibilityInfo.java @@ -29,19 +29,19 @@ */ public class ExtendedCompatibilityInfo extends BaseCompatibilityInfo { - /** - * Creates and populates record - * - * @param fruData - * - raw data containing record - * @param offset - * - offset to the record in the data - * @param length - * - length of the record - */ - public ExtendedCompatibilityInfo(byte[] fruData, int offset, int length) { - super(fruData, offset, length); - // TODO: Test when server containing such records will be available - } + /** + * Creates and populates record + * + * @param fruData + * - raw data containing record + * @param offset + * - offset to the record in the data + * @param length + * - length of the record + */ + public ExtendedCompatibilityInfo(byte[] fruData, int offset, int length) { + super(fruData, offset, length); + // TODO: Test when server containing such records will be available + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/FruMultiRecordType.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/FruMultiRecordType.java index d586a4f..28d048d 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/FruMultiRecordType.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/FruMultiRecordType.java @@ -29,59 +29,67 @@ * Identifies type of the information stored in FRU's MultiRecord Area entry. */ public enum FruMultiRecordType { - PowerSupplyInformation(FruMultiRecordType.POWERSUPPLYINFORMATION), DcOutput(FruMultiRecordType.DCOUTPUT), OemRecord( - FruMultiRecordType.OEMRECORD), DcLoad(FruMultiRecordType.DCLOAD), ManagementAccessRecord( - FruMultiRecordType.MANAGEMENTACCESSRECORD), BaseCompatibilityRecord( - FruMultiRecordType.BASECOMPATIBILITYRECORD), ExtendedCompatibilityRecord( - FruMultiRecordType.EXTENDEDCOMPATIBILITYRECORD), Unspecified(FruMultiRecordType.UNSPECIFIED), ; - private static final int POWERSUPPLYINFORMATION = 0; - - private static final int DCOUTPUT = 1; - - private static final int OEMRECORD = 192; - - private static final int DCLOAD = 2; - - private static final int MANAGEMENTACCESSRECORD = 3; - - private static final int BASECOMPATIBILITYRECORD = 4; - - private static final int EXTENDEDCOMPATIBILITYRECORD = 5; - - private static final int UNSPECIFIED = -1; - - private int code; - - private static Logger logger = LoggerFactory.getLogger(FruMultiRecordType.class); - - FruMultiRecordType(int code) { - this.code = code; - } - - public int getCode() { - return code; - } - - public static FruMultiRecordType parseInt(int value) { - if (value >= OEMRECORD) { - return OemRecord; - } - switch (value) { - case POWERSUPPLYINFORMATION: - return PowerSupplyInformation; - case DCOUTPUT: - return DcOutput; - case DCLOAD: - return DcLoad; - case MANAGEMENTACCESSRECORD: - return ManagementAccessRecord; - case BASECOMPATIBILITYRECORD: - return BaseCompatibilityRecord; - case EXTENDEDCOMPATIBILITYRECORD: - return ExtendedCompatibilityRecord; - default: - logger.error("Invalid value: " + value); - return Unspecified; - } - } + PowerSupplyInformation(FruMultiRecordType.POWERSUPPLYINFORMATION), + DcOutput(FruMultiRecordType.DCOUTPUT), + OemRecord( + FruMultiRecordType.OEMRECORD), + DcLoad(FruMultiRecordType.DCLOAD), + ManagementAccessRecord( + FruMultiRecordType.MANAGEMENTACCESSRECORD), + BaseCompatibilityRecord( + FruMultiRecordType.BASECOMPATIBILITYRECORD), + ExtendedCompatibilityRecord( + FruMultiRecordType.EXTENDEDCOMPATIBILITYRECORD), + Unspecified(FruMultiRecordType.UNSPECIFIED),; + + private static final int POWERSUPPLYINFORMATION = 0; + + private static final int DCOUTPUT = 1; + + private static final int OEMRECORD = 192; + + private static final int DCLOAD = 2; + + private static final int MANAGEMENTACCESSRECORD = 3; + + private static final int BASECOMPATIBILITYRECORD = 4; + + private static final int EXTENDEDCOMPATIBILITYRECORD = 5; + + private static final int UNSPECIFIED = -1; + + private int code; + + private static Logger logger = LoggerFactory.getLogger(FruMultiRecordType.class); + + FruMultiRecordType(int code) { + this.code = code; + } + + public int getCode() { + return code; + } + + public static FruMultiRecordType parseInt(int value) { + if (value >= OEMRECORD) { + return OemRecord; + } + switch (value) { + case POWERSUPPLYINFORMATION: + return PowerSupplyInformation; + case DCOUTPUT: + return DcOutput; + case DCLOAD: + return DcLoad; + case MANAGEMENTACCESSRECORD: + return ManagementAccessRecord; + case BASECOMPATIBILITYRECORD: + return BaseCompatibilityRecord; + case EXTENDEDCOMPATIBILITYRECORD: + return ExtendedCompatibilityRecord; + default: + logger.error("Invalid value: " + value); + return Unspecified; + } + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/FruRecord.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/FruRecord.java index e0bf655..6490258 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/FruRecord.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/FruRecord.java @@ -31,50 +31,52 @@ */ public abstract class FruRecord { - /** - * Decodes string using the type/length field specification. - * - * @param typeFormat - * - 00 - binary or unspecified 01 - BCD plus (see below) 10 - - * 6-bit ASCII, packed (overrides Language Codes) 11 - - * Interpretation depends on Language Codes. 11b indicates 8-bit - * ASCII + Latin 1 if the Language Code is English for the area - * or record containing the field, or 2-byte UNICODE (least - * significant byte first) if the Language Code is not English. - * @param data - * - encoded data - * @param isEnglishLanguageCode - * - true if the Language Code is English - * @return - decoded string - */ - protected static String decodeString(int typeFormat, byte[] data, - boolean isEnglishLanguageCode) { - // TODO: Test different encoding types - switch (typeFormat) { - case 0: - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < data.length; ++i) { - int num = TypeConverter.byteToInt(data[i]); - if (num < 0x10) { - sb.append("0"); - } - sb.append(Integer.toHexString(num)); - } + /** + * Decodes string using the type/length field specification. + * + * @param typeFormat + * - 00 - binary or unspecified 01 - BCD plus (see below) 10 - + * 6-bit ASCII, packed (overrides Language Codes) 11 - + * Interpretation depends on Language Codes. 11b indicates 8-bit + * ASCII + Latin 1 if the Language Code is English for the area + * or record containing the field, or 2-byte UNICODE (least + * significant byte first) if the Language Code is not English. + * @param data + * - encoded data + * @param isEnglishLanguageCode + * - true if the Language Code is English + * @return - decoded string + */ + protected static String decodeString( + int typeFormat, + byte[] data, + boolean isEnglishLanguageCode) { + // TODO: Test different encoding types + switch (typeFormat) { + case 0: + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < data.length; ++i) { + int num = TypeConverter.byteToInt(data[i]); + if (num < 0x10) { + sb.append("0"); + } + sb.append(Integer.toHexString(num)); + } - return sb.toString(); - case 1: - return TypeConverter.decodeBcdPlus(data); - case 2: - return TypeConverter.decode6bitAscii(data); - case 3: - System.arraycopy(data, 0, data, 0, data.length); - if (isEnglishLanguageCode) { - return new String(data, Charset.forName("ISO-8859-1")).trim(); - } else { - return new String(data, Charset.forName("UTF-8")).trim(); - } - default: - throw new IllegalArgumentException("Invalid type format"); - } - } + return sb.toString(); + case 1: + return TypeConverter.decodeBcdPlus(data); + case 2: + return TypeConverter.decode6bitAscii(data); + case 3: + System.arraycopy(data, 0, data, 0, data.length); + if (isEnglishLanguageCode) { + return new String(data, Charset.forName("ISO-8859-1")).trim(); + } else { + return new String(data, Charset.forName("UTF-8")).trim(); + } + default: + throw new IllegalArgumentException("Invalid type format"); + } + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/ManagementAccessInfo.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/ManagementAccessInfo.java index 5ea1bba..a1620b1 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/ManagementAccessInfo.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/ManagementAccessInfo.java @@ -29,48 +29,50 @@ */ public class ManagementAccessInfo extends MultiRecordInfo { - private ManagementAccessRecordType recordType; + private ManagementAccessRecordType recordType; - private String accessInfo; + private String accessInfo; - /** - * Creates and populates record - * - * @param fruData - * - raw data containing record - * @param offset - * - offset to the record in the data - * @param length - * - length of the record - */ - public ManagementAccessInfo(byte[] fruData, int offset, int length) { - super(); - // TODO: Test when server containing such records will be available + /** + * Creates and populates record + * + * @param fruData + * - raw data containing record + * @param offset + * - offset to the record in the data + * @param length + * - length of the record + */ + public ManagementAccessInfo(byte[] fruData, int offset, int length) { + super(); + // TODO: Test when server containing such records will be available - recordType = ManagementAccessRecordType.parseInt(TypeConverter - .byteToInt(fruData[offset])); + recordType = ManagementAccessRecordType + .parseInt( + TypeConverter + .byteToInt(fruData[offset])); - byte[] buffer = new byte[length - 1]; + byte[] buffer = new byte[length - 1]; - System.arraycopy(fruData, offset + 1, buffer, 0, length - 1); + System.arraycopy(fruData, offset + 1, buffer, 0, length - 1); - accessInfo = new String(buffer); - } + accessInfo = new String(buffer); + } - public ManagementAccessRecordType getRecordType() { - return recordType; - } + public ManagementAccessRecordType getRecordType() { + return recordType; + } - public void setRecordType(ManagementAccessRecordType recordType) { - this.recordType = recordType; - } + public void setRecordType(ManagementAccessRecordType recordType) { + this.recordType = recordType; + } - public String getAccessInfo() { - return accessInfo; - } + public String getAccessInfo() { + return accessInfo; + } - public void setAccessInfo(String accessInfo) { - this.accessInfo = accessInfo; - } + public void setAccessInfo(String accessInfo) { + this.accessInfo = accessInfo; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/ManagementAccessRecordType.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/ManagementAccessRecordType.java index ce9eab9..ae276bb 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/ManagementAccessRecordType.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/ManagementAccessRecordType.java @@ -26,44 +26,49 @@ import org.slf4j.LoggerFactory; public enum ManagementAccessRecordType { - SystemManagementUrl(ManagementAccessRecordType.SYSTEMMANAGEMENTURL), SystemName( - ManagementAccessRecordType.SYSTEMNAME), SystemPingAddress(ManagementAccessRecordType.SYSTEMPINGADDRESS), ComponentManagementURL( - ManagementAccessRecordType.COMPONENTMANAGEMENTURL), Unspecified(ManagementAccessRecordType.UNSPECIFIED), ; - private static final int SYSTEMMANAGEMENTURL = 1; + SystemManagementUrl(ManagementAccessRecordType.SYSTEMMANAGEMENTURL), + SystemName( + ManagementAccessRecordType.SYSTEMNAME), + SystemPingAddress(ManagementAccessRecordType.SYSTEMPINGADDRESS), + ComponentManagementURL( + ManagementAccessRecordType.COMPONENTMANAGEMENTURL), + Unspecified(ManagementAccessRecordType.UNSPECIFIED),; - private static final int SYSTEMNAME = 2; + private static final int SYSTEMMANAGEMENTURL = 1; - private static final int SYSTEMPINGADDRESS = 3; + private static final int SYSTEMNAME = 2; - private static final int COMPONENTMANAGEMENTURL = 4; + private static final int SYSTEMPINGADDRESS = 3; - private static final int UNSPECIFIED = 0; + private static final int COMPONENTMANAGEMENTURL = 4; - private static Logger logger = LoggerFactory.getLogger(ManagementAccessRecordType.class); + private static final int UNSPECIFIED = 0; - private int code; + private static Logger logger = LoggerFactory.getLogger(ManagementAccessRecordType.class); - ManagementAccessRecordType(int code) { - this.code = code; - } + private int code; - public int getCode() { - return code; - } + ManagementAccessRecordType(int code) { + this.code = code; + } - public static ManagementAccessRecordType parseInt(int value) { - switch (value) { - case SYSTEMMANAGEMENTURL: - return SystemManagementUrl; - case SYSTEMNAME: - return SystemName; - case SYSTEMPINGADDRESS: - return SystemPingAddress; - case COMPONENTMANAGEMENTURL: - return ComponentManagementURL; - default: - logger.error("Invalid value: " + value); - return Unspecified; - } - } + public int getCode() { + return code; + } + + public static ManagementAccessRecordType parseInt(int value) { + switch (value) { + case SYSTEMMANAGEMENTURL: + return SystemManagementUrl; + case SYSTEMNAME: + return SystemName; + case SYSTEMPINGADDRESS: + return SystemPingAddress; + case COMPONENTMANAGEMENTURL: + return ComponentManagementURL; + default: + logger.error("Invalid value: " + value); + return Unspecified; + } + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/MultiRecordInfo.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/MultiRecordInfo.java index ac6da34..ac25a39 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/MultiRecordInfo.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/MultiRecordInfo.java @@ -29,60 +29,60 @@ */ public abstract class MultiRecordInfo extends FruRecord { - public MultiRecordInfo() { - super(); - } + public MultiRecordInfo() { + super(); + } - /** - * Creates and populates record - * - * @param fruData - * - raw data containing record - * @param offset - * - offset to the record in the data - */ - public static MultiRecordInfo populateMultiRecord(final byte[] fruData, final int offset) { - MultiRecordInfo recordInfo = null; + /** + * Creates and populates record + * + * @param fruData + * - raw data containing record + * @param offset + * - offset to the record in the data + */ + public static MultiRecordInfo populateMultiRecord(final byte[] fruData, final int offset) { + MultiRecordInfo recordInfo = null; - // TODO: Test when server containing such records will be available + // TODO: Test when server containing such records will be available - if ((TypeConverter.byteToInt(fruData[offset + 1]) & 0xf) != 0x2) { - throw new IllegalArgumentException("Invalid FRU record version"); - } + if ((TypeConverter.byteToInt(fruData[offset + 1]) & 0xf) != 0x2) { + throw new IllegalArgumentException("Invalid FRU record version"); + } - FruMultiRecordType recordType = FruMultiRecordType - .parseInt(TypeConverter.byteToInt(fruData[offset])); + FruMultiRecordType recordType = FruMultiRecordType + .parseInt(TypeConverter.byteToInt(fruData[offset])); - int length = TypeConverter.byteToInt(fruData[offset + 2]); + int length = TypeConverter.byteToInt(fruData[offset + 2]); - int currentOffset = offset + 5; + int currentOffset = offset + 5; - switch (recordType) { - case PowerSupplyInformation: - recordInfo = new PowerSupplyInfo(fruData, currentOffset); - break; - case DcOutput: - recordInfo = new DcOutputInfo(fruData, currentOffset); - break; - case DcLoad: - recordInfo = new DcLoadInfo(fruData, currentOffset); - break; - case ManagementAccessRecord: - recordInfo = new ManagementAccessInfo(fruData, currentOffset, length); - break; - case BaseCompatibilityRecord: - recordInfo = new BaseCompatibilityInfo(fruData, currentOffset, length); - break; - case ExtendedCompatibilityRecord: - recordInfo = new ExtendedCompatibilityInfo(fruData, currentOffset, length); - break; - case OemRecord: - recordInfo = new OemInfo(fruData, currentOffset, length); - break; - default: - throw new IllegalArgumentException("Unsupported record type"); - } + switch (recordType) { + case PowerSupplyInformation: + recordInfo = new PowerSupplyInfo(fruData, currentOffset); + break; + case DcOutput: + recordInfo = new DcOutputInfo(fruData, currentOffset); + break; + case DcLoad: + recordInfo = new DcLoadInfo(fruData, currentOffset); + break; + case ManagementAccessRecord: + recordInfo = new ManagementAccessInfo(fruData, currentOffset, length); + break; + case BaseCompatibilityRecord: + recordInfo = new BaseCompatibilityInfo(fruData, currentOffset, length); + break; + case ExtendedCompatibilityRecord: + recordInfo = new ExtendedCompatibilityInfo(fruData, currentOffset, length); + break; + case OemRecord: + recordInfo = new OemInfo(fruData, currentOffset, length); + break; + default: + throw new IllegalArgumentException("Unsupported record type"); + } - return recordInfo; - } + return recordInfo; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/OemInfo.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/OemInfo.java index 05eaead..7ab66c6 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/OemInfo.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/OemInfo.java @@ -29,51 +29,51 @@ */ public class OemInfo extends MultiRecordInfo { - private int manufacturerId; + private int manufacturerId; - private byte[] oemData; + private byte[] oemData; - /** - * Creates and populates record - * - * @param fruData - * - raw data containing record - * @param offset - * - offset to the record in the data - * @param length - * - length of the record - */ - public OemInfo(byte[] fruData, int offset, int length) { - super(); - // TODO: Test when server containing such records will be available + /** + * Creates and populates record + * + * @param fruData + * - raw data containing record + * @param offset + * - offset to the record in the data + * @param length + * - length of the record + */ + public OemInfo(byte[] fruData, int offset, int length) { + super(); + // TODO: Test when server containing such records will be available - byte[] buffer = new byte[4]; + byte[] buffer = new byte[4]; - System.arraycopy(fruData, offset, buffer, 0, 3); - buffer[3] = 0; + System.arraycopy(fruData, offset, buffer, 0, 3); + buffer[3] = 0; - manufacturerId = TypeConverter.littleEndianByteArrayToInt(buffer); + manufacturerId = TypeConverter.littleEndianByteArrayToInt(buffer); - oemData = new byte[length - 3]; + oemData = new byte[length - 3]; - System.arraycopy(fruData, offset+3, oemData, 0, length-3); + System.arraycopy(fruData, offset + 3, oemData, 0, length - 3); - } + } - public int getManufacturerId() { - return manufacturerId; - } + public int getManufacturerId() { + return manufacturerId; + } - public void setManufacturerId(int manufacturerId) { - this.manufacturerId = manufacturerId; - } + public void setManufacturerId(int manufacturerId) { + this.manufacturerId = manufacturerId; + } - public byte[] getOemData() { - return oemData; - } + public byte[] getOemData() { + return oemData; + } - public void setOemData(byte[] oemData) { - this.oemData = oemData; - } + public void setOemData(byte[] oemData) { + this.oemData = oemData; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/PowerSupplyInfo.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/PowerSupplyInfo.java index d17bf8f..9c97df9 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/PowerSupplyInfo.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/PowerSupplyInfo.java @@ -29,175 +29,175 @@ */ public class PowerSupplyInfo extends MultiRecordInfo { - /** - * Overall Capacity in Watts - */ - private int capacity; - - /** - * The highest instantaneous VA value that this supply draws during - * operation. - */ - private int peakVa; - - /** - * Maximum inrush of current, in Amps, into the power supply. - */ - private int maximumInrush; - - /** - * This specifies the low end of acceptable voltage into the power supply. - * The units are 10mV. - */ - private int lowEndInputVoltage1; - - /** - * This specifies the high end of acceptable voltage into the power supply. - * The units are 10mV. - */ - private int highEndInputVoltage1; - - /** - * This specifies the low end of acceptable voltage into the power supply. - * This field would be used if the power supply did not support autoswitch. - * Range 1 would define the 110V range, while range 2 would be used for - * 220V. The units are 10mV. - */ - private int lowEndInputVoltage2; - - /** - * This specifies the high end of acceptable voltage into the power supply. - * This field would be used if the power supply did not support autoswitch. - * Range 1 would define the 110V range, while range 2 would be used for - * 220V. The units are 10mV. - */ - private int highEndInputVoltage2; - - /** - * This specifies the low end of acceptable frequency range into the power - * supply. - */ - private int lowEndInputFrequencyRange; - - /** - * This specifies the high end of acceptable frequency range into the power - * supply. - */ - private int highEndInputFrequencyRange; - - /** - * Creates and populates record - * - * @param fruData - * - raw data containing record - * @param offset - * - offset to the record in the data - */ - public PowerSupplyInfo(byte[] fruData, int offset) { - super(); - - // TODO: Test when server containing such records will be available - - capacity = TypeConverter.byteToInt(fruData[offset]) & 0xf; - capacity |= TypeConverter.byteToInt(fruData[offset + 1]) << 4; - - peakVa = TypeConverter.byteToInt(fruData[offset + 2]); - peakVa |= TypeConverter.byteToInt(fruData[offset + 3]) << 8; - - if (peakVa == 0xffff) { - peakVa = -1; - } - - maximumInrush = TypeConverter.byteToInt(fruData[offset + 4]); - - lowEndInputVoltage1 = TypeConverter.byteToInt(fruData[offset + 6]); - lowEndInputVoltage1 |= TypeConverter.byteToInt(fruData[offset + 7]) << 8; - - highEndInputVoltage1 = TypeConverter.byteToInt(fruData[offset + 8]); - highEndInputVoltage1 |= TypeConverter.byteToInt(fruData[offset + 9]) << 8; - - lowEndInputVoltage2 = TypeConverter.byteToInt(fruData[offset + 10]); - lowEndInputVoltage2 |= TypeConverter.byteToInt(fruData[offset + 11]) << 8; - - highEndInputVoltage2 = TypeConverter.byteToInt(fruData[offset + 12]); - highEndInputVoltage2 |= TypeConverter.byteToInt(fruData[offset + 13]) << 8; - - lowEndInputFrequencyRange = TypeConverter - .byteToInt(fruData[offset + 14]); - highEndInputFrequencyRange = TypeConverter - .byteToInt(fruData[offset + 15]); - } - - public int getCapacity() { - return capacity; - } - - public void setCapacity(int capacity) { - this.capacity = capacity; - } - - public int getPeakVa() { - return peakVa; - } - - public void setPeakVa(int peakVa) { - this.peakVa = peakVa; - } - - public int getMaximumInrush() { - return maximumInrush; - } - - public void setMaximumInrush(int maximumInrush) { - this.maximumInrush = maximumInrush; - } - - public int getLowEndInputVoltage1() { - return lowEndInputVoltage1; - } - - public void setLowEndInputVoltage1(int lowEndInputVoltage1) { - this.lowEndInputVoltage1 = lowEndInputVoltage1; - } - - public int getHighEndInputVoltage1() { - return highEndInputVoltage1; - } - - public void setHighEndInputVoltage1(int highEndInputVoltage1) { - this.highEndInputVoltage1 = highEndInputVoltage1; - } - - public int getLowEndInputVoltage2() { - return lowEndInputVoltage2; - } - - public void setLowEndInputVoltage2(int lowEndInputVoltage2) { - this.lowEndInputVoltage2 = lowEndInputVoltage2; - } - - public int getHighEndInputVoltage2() { - return highEndInputVoltage2; - } - - public void setHighEndInputVoltage2(int highEndInputVoltage2) { - this.highEndInputVoltage2 = highEndInputVoltage2; - } + /** + * Overall Capacity in Watts + */ + private int capacity; + + /** + * The highest instantaneous VA value that this supply draws during + * operation. + */ + private int peakVa; + + /** + * Maximum inrush of current, in Amps, into the power supply. + */ + private int maximumInrush; + + /** + * This specifies the low end of acceptable voltage into the power supply. + * The units are 10mV. + */ + private int lowEndInputVoltage1; + + /** + * This specifies the high end of acceptable voltage into the power supply. + * The units are 10mV. + */ + private int highEndInputVoltage1; + + /** + * This specifies the low end of acceptable voltage into the power supply. + * This field would be used if the power supply did not support autoswitch. + * Range 1 would define the 110V range, while range 2 would be used for + * 220V. The units are 10mV. + */ + private int lowEndInputVoltage2; + + /** + * This specifies the high end of acceptable voltage into the power supply. + * This field would be used if the power supply did not support autoswitch. + * Range 1 would define the 110V range, while range 2 would be used for + * 220V. The units are 10mV. + */ + private int highEndInputVoltage2; + + /** + * This specifies the low end of acceptable frequency range into the power + * supply. + */ + private int lowEndInputFrequencyRange; + + /** + * This specifies the high end of acceptable frequency range into the power + * supply. + */ + private int highEndInputFrequencyRange; + + /** + * Creates and populates record + * + * @param fruData + * - raw data containing record + * @param offset + * - offset to the record in the data + */ + public PowerSupplyInfo(byte[] fruData, int offset) { + super(); + + // TODO: Test when server containing such records will be available + + capacity = TypeConverter.byteToInt(fruData[offset]) & 0xf; + capacity |= TypeConverter.byteToInt(fruData[offset + 1]) << 4; + + peakVa = TypeConverter.byteToInt(fruData[offset + 2]); + peakVa |= TypeConverter.byteToInt(fruData[offset + 3]) << 8; + + if (peakVa == 0xffff) { + peakVa = -1; + } + + maximumInrush = TypeConverter.byteToInt(fruData[offset + 4]); + + lowEndInputVoltage1 = TypeConverter.byteToInt(fruData[offset + 6]); + lowEndInputVoltage1 |= TypeConverter.byteToInt(fruData[offset + 7]) << 8; + + highEndInputVoltage1 = TypeConverter.byteToInt(fruData[offset + 8]); + highEndInputVoltage1 |= TypeConverter.byteToInt(fruData[offset + 9]) << 8; + + lowEndInputVoltage2 = TypeConverter.byteToInt(fruData[offset + 10]); + lowEndInputVoltage2 |= TypeConverter.byteToInt(fruData[offset + 11]) << 8; + + highEndInputVoltage2 = TypeConverter.byteToInt(fruData[offset + 12]); + highEndInputVoltage2 |= TypeConverter.byteToInt(fruData[offset + 13]) << 8; + + lowEndInputFrequencyRange = TypeConverter + .byteToInt(fruData[offset + 14]); + highEndInputFrequencyRange = TypeConverter + .byteToInt(fruData[offset + 15]); + } + + public int getCapacity() { + return capacity; + } + + public void setCapacity(int capacity) { + this.capacity = capacity; + } + + public int getPeakVa() { + return peakVa; + } + + public void setPeakVa(int peakVa) { + this.peakVa = peakVa; + } + + public int getMaximumInrush() { + return maximumInrush; + } + + public void setMaximumInrush(int maximumInrush) { + this.maximumInrush = maximumInrush; + } + + public int getLowEndInputVoltage1() { + return lowEndInputVoltage1; + } + + public void setLowEndInputVoltage1(int lowEndInputVoltage1) { + this.lowEndInputVoltage1 = lowEndInputVoltage1; + } + + public int getHighEndInputVoltage1() { + return highEndInputVoltage1; + } + + public void setHighEndInputVoltage1(int highEndInputVoltage1) { + this.highEndInputVoltage1 = highEndInputVoltage1; + } + + public int getLowEndInputVoltage2() { + return lowEndInputVoltage2; + } + + public void setLowEndInputVoltage2(int lowEndInputVoltage2) { + this.lowEndInputVoltage2 = lowEndInputVoltage2; + } + + public int getHighEndInputVoltage2() { + return highEndInputVoltage2; + } + + public void setHighEndInputVoltage2(int highEndInputVoltage2) { + this.highEndInputVoltage2 = highEndInputVoltage2; + } - public int getLowEndInputFrequencyRange() { - return lowEndInputFrequencyRange; - } + public int getLowEndInputFrequencyRange() { + return lowEndInputFrequencyRange; + } - public void setLowEndInputFrequencyRange(int lowEndInputFrequencyRange) { - this.lowEndInputFrequencyRange = lowEndInputFrequencyRange; - } + public void setLowEndInputFrequencyRange(int lowEndInputFrequencyRange) { + this.lowEndInputFrequencyRange = lowEndInputFrequencyRange; + } - public int getHighEndInputFrequencyRange() { - return highEndInputFrequencyRange; - } + public int getHighEndInputFrequencyRange() { + return highEndInputFrequencyRange; + } - public void setHighEndInputFrequencyRange(int highEndInputFrequencyRange) { - this.highEndInputFrequencyRange = highEndInputFrequencyRange; - } + public void setHighEndInputFrequencyRange(int highEndInputFrequencyRange) { + this.highEndInputFrequencyRange = highEndInputFrequencyRange; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/ProductInfo.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/ProductInfo.java index e509fbf..105abb9 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/ProductInfo.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/ProductInfo.java @@ -35,189 +35,227 @@ */ public class ProductInfo extends FruRecord { - private String manufacturerName = ""; - - private String productName = ""; - - private String productModelNumber = ""; - - private String productVersion = ""; - - private String productSerialNumber = ""; - - private String assetTag = ""; - - private byte[] fruFileId = new byte[0]; - - private String[] customProductInfo = new String[0]; - - /** - * Creates and populates record - * - * @param fruData - * - raw data containing record - * @param offset - * - offset to the record in the data - */ - public ProductInfo(final byte[] fruData, final int offset) { - super(); - - if (fruData[offset] != 0x1) { - throw new IllegalArgumentException("Invalid format version"); - } - - int languageCode = TypeConverter.byteToInt(fruData[offset + 2]); - - int partNumber = TypeConverter.byteToInt(fruData[offset + 3]); - - ArrayList customInfo = readCustomInfo(fruData, languageCode, partNumber, offset + 4); - - customProductInfo = new String[customInfo.size()]; - customProductInfo = customInfo.toArray(customProductInfo); - } - - private ArrayList readCustomInfo(final byte[] fruData, final int languageCode, final int partNumber, final int offset) { - int index = 0; - - ArrayList customInfo = new ArrayList(); - - int currentOffset = offset; - int currentPartNumber = partNumber; - - while (currentPartNumber != 0xc1 && currentOffset < fruData.length) { - - int partType = (currentPartNumber & 0xc0) >> 6; - - int partDataLength = (currentPartNumber & 0x3f); - - if (partDataLengthWithinBounds(fruData, currentOffset, partDataLength)) { - - byte[] partNumberData = new byte[partDataLength]; - - System.arraycopy(fruData, currentOffset, partNumberData, 0, - partDataLength); - - currentOffset += partDataLength; - - switch (index) { - case 0: - setManufacturerName(FruRecord.decodeString(partType, - partNumberData, isEnglishLanguageCode(languageCode))); - break; - case 1: - setProductName(FruRecord.decodeString(partType, - partNumberData, isEnglishLanguageCode(languageCode))); - break; - case 2: - setProductModelNumber(FruRecord.decodeString(partType, - partNumberData, isEnglishLanguageCode(languageCode))); - break; - case 3: - setProductVersion(FruRecord.decodeString(partType, - partNumberData, isEnglishLanguageCode(languageCode))); - break; - case 4: - setProductSerialNumber(FruRecord.decodeString(partType, - partNumberData, true)); - break; - case 5: - setAssetTag(FruRecord.decodeString(partType, - partNumberData, isEnglishLanguageCode(languageCode))); - break; - case 6: - setFruFileId(partNumberData); - break; - default: - if (partDataLength == 0) { - currentPartNumber = TypeConverter.byteToInt(fruData[currentOffset]); - ++currentOffset; - continue; - } - customInfo.add(FruRecord.decodeString(partType, - partNumberData, isEnglishLanguageCode(languageCode))); - break; - } - } - - currentPartNumber = TypeConverter.byteToInt(fruData[currentOffset]); - - ++currentOffset; - - ++index; - } - return customInfo; - } - - private boolean isEnglishLanguageCode(int languageCode) { - return languageCode != 0 && languageCode != 25; - } - - private boolean partDataLengthWithinBounds(byte[] fruData, int currentOffset, int partDataLength) { - return partDataLength > 0 && partDataLength + currentOffset < fruData.length; - } - - public String getManufacturerName() { - return manufacturerName; - } - - public void setManufacturerName(String manufacturerName) { - this.manufacturerName = manufacturerName; - } - - public String getProductName() { - return productName; - } - - public void setProductName(String productName) { - this.productName = productName; - } - - public String getProductModelNumber() { - return productModelNumber; - } - - public void setProductModelNumber(String productModelNumber) { - this.productModelNumber = productModelNumber; - } - - public String getProductVersion() { - return productVersion; - } - - public void setProductVersion(String productVersion) { - this.productVersion = productVersion; - } - - public void setProductSerialNumber(String productSerialNumber) { - this.productSerialNumber = productSerialNumber; - } - - public String getProductSerialNumber() { - return productSerialNumber; - } - - public String getAssetTag() { - return assetTag; - } - - public void setAssetTag(String assetTag) { - this.assetTag = assetTag; - } - - public byte[] getFruFileId() { - return fruFileId; - } - - public void setFruFileId(byte[] fruFileId) { - this.fruFileId = fruFileId; - } - - public String[] getCustomProductInfo() { - return customProductInfo; - } - - public void setCustomProductInfo(String[] customProductInfo) { - this.customProductInfo = customProductInfo; - } + private String manufacturerName = ""; + + private String productName = ""; + + private String productModelNumber = ""; + + private String productVersion = ""; + + private String productSerialNumber = ""; + + private String assetTag = ""; + + private byte[] fruFileId = new byte[0]; + + private String[] customProductInfo = new String[0]; + + /** + * Creates and populates record + * + * @param fruData + * - raw data containing record + * @param offset + * - offset to the record in the data + */ + public ProductInfo(final byte[] fruData, final int offset) { + super(); + + if (fruData[offset] != 0x1) { + throw new IllegalArgumentException("Invalid format version"); + } + + int languageCode = TypeConverter.byteToInt(fruData[offset + 2]); + + int partNumber = TypeConverter.byteToInt(fruData[offset + 3]); + + ArrayList customInfo = readCustomInfo(fruData, languageCode, partNumber, offset + 4); + + customProductInfo = new String[customInfo.size()]; + customProductInfo = customInfo.toArray(customProductInfo); + } + + private ArrayList readCustomInfo( + final byte[] fruData, + final int languageCode, + final int partNumber, + final int offset) { + int index = 0; + + ArrayList customInfo = new ArrayList(); + + int currentOffset = offset; + int currentPartNumber = partNumber; + + while (currentPartNumber != 0xc1 && currentOffset < fruData.length) { + + int partType = (currentPartNumber & 0xc0) >> 6; + + int partDataLength = (currentPartNumber & 0x3f); + + if (partDataLengthWithinBounds(fruData, currentOffset, partDataLength)) { + + byte[] partNumberData = new byte[partDataLength]; + + System + .arraycopy( + fruData, + currentOffset, + partNumberData, + 0, + partDataLength); + + currentOffset += partDataLength; + + switch (index) { + case 0: + setManufacturerName( + FruRecord + .decodeString( + partType, + partNumberData, + isEnglishLanguageCode(languageCode))); + break; + case 1: + setProductName( + FruRecord + .decodeString( + partType, + partNumberData, + isEnglishLanguageCode(languageCode))); + break; + case 2: + setProductModelNumber( + FruRecord + .decodeString( + partType, + partNumberData, + isEnglishLanguageCode(languageCode))); + break; + case 3: + setProductVersion( + FruRecord + .decodeString( + partType, + partNumberData, + isEnglishLanguageCode(languageCode))); + break; + case 4: + setProductSerialNumber( + FruRecord + .decodeString( + partType, + partNumberData, + true)); + break; + case 5: + setAssetTag( + FruRecord + .decodeString( + partType, + partNumberData, + isEnglishLanguageCode(languageCode))); + break; + case 6: + setFruFileId(partNumberData); + break; + default: + if (partDataLength == 0) { + currentPartNumber = TypeConverter.byteToInt(fruData[currentOffset]); + ++currentOffset; + continue; + } + customInfo + .add( + FruRecord + .decodeString( + partType, + partNumberData, + isEnglishLanguageCode(languageCode))); + break; + } + } + + currentPartNumber = TypeConverter.byteToInt(fruData[currentOffset]); + + ++currentOffset; + + ++index; + } + return customInfo; + } + + private boolean isEnglishLanguageCode(int languageCode) { + return languageCode != 0 && languageCode != 25; + } + + private boolean partDataLengthWithinBounds(byte[] fruData, int currentOffset, int partDataLength) { + return partDataLength > 0 && partDataLength + currentOffset < fruData.length; + } + + public String getManufacturerName() { + return manufacturerName; + } + + public void setManufacturerName(String manufacturerName) { + this.manufacturerName = manufacturerName; + } + + public String getProductName() { + return productName; + } + + public void setProductName(String productName) { + this.productName = productName; + } + + public String getProductModelNumber() { + return productModelNumber; + } + + public void setProductModelNumber(String productModelNumber) { + this.productModelNumber = productModelNumber; + } + + public String getProductVersion() { + return productVersion; + } + + public void setProductVersion(String productVersion) { + this.productVersion = productVersion; + } + + public void setProductSerialNumber(String productSerialNumber) { + this.productSerialNumber = productSerialNumber; + } + + public String getProductSerialNumber() { + return productSerialNumber; + } + + public String getAssetTag() { + return assetTag; + } + + public void setAssetTag(String assetTag) { + this.assetTag = assetTag; + } + + public byte[] getFruFileId() { + return fruFileId; + } + + public void setFruFileId(byte[] fruFileId) { + this.fruFileId = fruFileId; + } + + public String[] getCustomProductInfo() { + return customProductInfo; + } + + public void setCustomProductInfo(String[] customProductInfo) { + this.customProductInfo = customProductInfo; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/SpdInfo.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/SpdInfo.java index 850ecb2..d3e51cb 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/SpdInfo.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/fru/record/SpdInfo.java @@ -27,8 +27,8 @@ */ public class SpdInfo extends FruRecord { - public SpdInfo(byte[] fruData, int offset) { - super(); - } - // TODO: Implement + public SpdInfo(byte[] fruData, int offset) { + super(); + } + // TODO: Implement } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/package-info.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/package-info.java index 9603e10..cf21ad6 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/package-info.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/package-info.java @@ -1,6 +1,7 @@ /** - * The package containing command wrappers. These include command encoders and decoders. - * To add custom IPMI command extend {@link org.metricshub.ipmi.core.coding.PayloadCoder} class and implement {@link org.metricshub.ipmi.core.api.async.messages.IpmiResponseData} interface. + * The package containing command wrappers. These include command encoders and decoders. + * To add custom IPMI command extend {@link org.metricshub.ipmi.core.coding.PayloadCoder} class and implement + * {@link org.metricshub.ipmi.core.api.async.messages.IpmiResponseData} interface. */ package org.metricshub.ipmi.core.coding.commands; /*- diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/payload/ActivatePayload.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/payload/ActivatePayload.java index 07e0271..a26eeb1 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/payload/ActivatePayload.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/payload/ActivatePayload.java @@ -44,141 +44,151 @@ import java.security.NoSuchAlgorithmException; /** - * An abstract wrapper class for Activate Payload Command. Every {@link PayloadType} should have it's own concrete implementation. + * An abstract wrapper class for Activate Payload Command. Every {@link PayloadType} should have it's own concrete + * implementation. */ public abstract class ActivatePayload extends IpmiCommandCoder { - /** - * Length (in bytes) of request data payload. - */ - private static final int REQUEST_DATA_LENGTH = 6; - - /** - * Length (in bytes) of auxilary data field in request/response payload. - */ - private static final int AUXILARY_DATA_LENGTH = 4; - - /** - * Length (in bytes) of inbound payload size field in response payload. - */ - private static final int INBOUND_PAYLOAD_SIZE_LENGTH = 2; - - /** - * Length (in bytes) of outbound data field response payload. - */ - private static final int OUTBOUND_PAYLOAD_SIZE_LENGTH = 2; - - /** - * Length (in bytes) of udp port number field in response payload. - */ - private static final int PAYLOAD_UDP_PORT_NUMBER_DATA_LENGTH = 2; - - /** - * Length (in bytes) of VLAN number field in response payload. - */ - private static final int PAYLOAD_VLAN_NUMBER_DATA_LENGTH = 2; - - /** - * Number of payload instance to use when activating. - */ - private final int payloadInstance; - - /** - * @return type of the payload activated by this command. - */ - public abstract PayloadType getPayloadType(); - - protected ActivatePayload(IpmiVersion ipmiVersion, CipherSuite cipherSuite, AuthenticationType authenticationType, int payloadInstance) { - super(ipmiVersion, cipherSuite, authenticationType); - - this.payloadInstance = payloadInstance; - } - - @Override - public byte getCommandCode() { - return CommandCodes.ACTIVATE_PAYLOAD; - } - - @Override - public NetworkFunction getNetworkFunction() { - return NetworkFunction.ApplicationRequest; - } - - @Override - protected IpmiPayload preparePayload(int sequenceNumber) throws NoSuchAlgorithmException, InvalidKeyException { - byte[] message = MessageComposer.get(REQUEST_DATA_LENGTH) - .appendField(TypeConverter.intToByte(getPayloadType().getCode())) - .appendField(TypeConverter.intToByte(payloadInstance)) - .appendField(prepareAuxilaryRequestData()) - .getMessage(); - - return new IpmiLanRequest(getNetworkFunction(), getCommandCode(), message, TypeConverter.intToByte(sequenceNumber)); - } - - /** - * Prepares Auxilary Data field for the request payload. - * - * @return Auxilary Data bytes. - */ - protected abstract byte[] prepareAuxilaryRequestData(); - - @Override - public ResponseData getResponseData(IpmiMessage message) throws IPMIException, NoSuchAlgorithmException, InvalidKeyException { - if (!isCommandResponse(message)) { - throw new IllegalArgumentException("This is not a response for Activate Payload command"); - } - - if (!(message.getPayload() instanceof IpmiLanResponse)) { - throw new IllegalArgumentException("Invalid response payload"); - } - - if (((IpmiLanResponse) message.getPayload()).getCompletionCode() != CompletionCode.Ok) { - throw new IPMIException(((IpmiLanResponse) message.getPayload()).getCompletionCode()); - } - - MessageReader messageReader = new MessageReader(message.getPayload().getData()); - - ActivatePayloadResponseData responseData = createEmptyResponse(); - - responseData.setAuxilaryInformationData(messageReader.readNextField(AUXILARY_DATA_LENGTH)); - responseData.setInboundPayloadSize(messageReader.readNextField(INBOUND_PAYLOAD_SIZE_LENGTH)); - responseData.setOutboundPayloadSize(messageReader.readNextField(OUTBOUND_PAYLOAD_SIZE_LENGTH)); - responseData.setPayloadUdpPortNumber(messageReader.readNextField(PAYLOAD_UDP_PORT_NUMBER_DATA_LENGTH)); - responseData.setPayloadVlanNumber(messageReader.readNextField(PAYLOAD_VLAN_NUMBER_DATA_LENGTH)); - - return responseData; - } - - /** - * Creates empty {@link ResponseData} object. - * - * @return created {@link ActivatePayloadResponseData} instance. - */ - protected abstract ActivatePayloadResponseData createEmptyResponse(); - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - ActivatePayload that = (ActivatePayload) o; - - if (payloadInstance != that.payloadInstance) { - return false; - } - - if (getPayloadType() != that.getPayloadType()) { - return false; - } - - return getCipherSuite().equals(that.getCipherSuite()); - } - - @Override - public int hashCode() { - int result = payloadInstance; - result = 31 * result + getPayloadType().getCode(); - result = 31 * result + (getCipherSuite() != null ? getCipherSuite().hashCode() : 0); - return result; - } + /** + * Length (in bytes) of request data payload. + */ + private static final int REQUEST_DATA_LENGTH = 6; + + /** + * Length (in bytes) of auxilary data field in request/response payload. + */ + private static final int AUXILARY_DATA_LENGTH = 4; + + /** + * Length (in bytes) of inbound payload size field in response payload. + */ + private static final int INBOUND_PAYLOAD_SIZE_LENGTH = 2; + + /** + * Length (in bytes) of outbound data field response payload. + */ + private static final int OUTBOUND_PAYLOAD_SIZE_LENGTH = 2; + + /** + * Length (in bytes) of udp port number field in response payload. + */ + private static final int PAYLOAD_UDP_PORT_NUMBER_DATA_LENGTH = 2; + + /** + * Length (in bytes) of VLAN number field in response payload. + */ + private static final int PAYLOAD_VLAN_NUMBER_DATA_LENGTH = 2; + + /** + * Number of payload instance to use when activating. + */ + private final int payloadInstance; + + /** + * @return type of the payload activated by this command. + */ + public abstract PayloadType getPayloadType(); + + protected ActivatePayload(IpmiVersion ipmiVersion, CipherSuite cipherSuite, AuthenticationType authenticationType, + int payloadInstance) { + super(ipmiVersion, cipherSuite, authenticationType); + + this.payloadInstance = payloadInstance; + } + + @Override + public byte getCommandCode() { + return CommandCodes.ACTIVATE_PAYLOAD; + } + + @Override + public NetworkFunction getNetworkFunction() { + return NetworkFunction.ApplicationRequest; + } + + @Override + protected IpmiPayload preparePayload(int sequenceNumber) throws NoSuchAlgorithmException, InvalidKeyException { + byte[] message = MessageComposer + .get(REQUEST_DATA_LENGTH) + .appendField(TypeConverter.intToByte(getPayloadType().getCode())) + .appendField(TypeConverter.intToByte(payloadInstance)) + .appendField(prepareAuxilaryRequestData()) + .getMessage(); + + return new IpmiLanRequest(getNetworkFunction(), getCommandCode(), message, TypeConverter.intToByte(sequenceNumber)); + } + + /** + * Prepares Auxilary Data field for the request payload. + * + * @return Auxilary Data bytes. + */ + protected abstract byte[] prepareAuxilaryRequestData(); + + @Override + public ResponseData getResponseData(IpmiMessage message) + throws IPMIException, + NoSuchAlgorithmException, + InvalidKeyException { + if (!isCommandResponse(message)) { + throw new IllegalArgumentException("This is not a response for Activate Payload command"); + } + + if (!(message.getPayload() instanceof IpmiLanResponse)) { + throw new IllegalArgumentException("Invalid response payload"); + } + + if (((IpmiLanResponse) message.getPayload()).getCompletionCode() != CompletionCode.Ok) { + throw new IPMIException(((IpmiLanResponse) message.getPayload()).getCompletionCode()); + } + + MessageReader messageReader = new MessageReader(message.getPayload().getData()); + + ActivatePayloadResponseData responseData = createEmptyResponse(); + + responseData.setAuxilaryInformationData(messageReader.readNextField(AUXILARY_DATA_LENGTH)); + responseData.setInboundPayloadSize(messageReader.readNextField(INBOUND_PAYLOAD_SIZE_LENGTH)); + responseData.setOutboundPayloadSize(messageReader.readNextField(OUTBOUND_PAYLOAD_SIZE_LENGTH)); + responseData.setPayloadUdpPortNumber(messageReader.readNextField(PAYLOAD_UDP_PORT_NUMBER_DATA_LENGTH)); + responseData.setPayloadVlanNumber(messageReader.readNextField(PAYLOAD_VLAN_NUMBER_DATA_LENGTH)); + + return responseData; + } + + /** + * Creates empty {@link ResponseData} object. + * + * @return created {@link ActivatePayloadResponseData} instance. + */ + protected abstract ActivatePayloadResponseData createEmptyResponse(); + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + ActivatePayload that = (ActivatePayload) o; + + if (payloadInstance != that.payloadInstance) { + return false; + } + + if (getPayloadType() != that.getPayloadType()) { + return false; + } + + return getCipherSuite().equals(that.getCipherSuite()); + } + + @Override + public int hashCode() { + int result = payloadInstance; + result = 31 * result + getPayloadType().getCode(); + result = 31 * result + (getCipherSuite() != null ? getCipherSuite().hashCode() : 0); + return result; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/payload/ActivatePayloadResponseData.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/payload/ActivatePayloadResponseData.java index 1640ffe..ee5691d 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/payload/ActivatePayloadResponseData.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/payload/ActivatePayloadResponseData.java @@ -30,105 +30,105 @@ */ public abstract class ActivatePayloadResponseData implements ResponseData { - /** - * Maximum size of a payload data field from remote console to BMC. - * Excludes size of confidentiality header and trailer fields, if any. - */ - private int inboundPayloadSize; - - /** - * Maximum size of a payload data field from BMC to remote console. - * Excludes size of confidentiality header and trailer fields, if any. - */ - private int outboundPayloadSize; - - /** - * UDP port number that payload can be transferred over. - */ - private int payloadUdpPortNumber; - - /** - * Payload VLAN number. FFFFh if VLAN addressing is not used. - */ - private int payloadVlanNumber; - - /** - * Set auxiliary information data - * - * @param auxilaryInformationData auxiliary information in bytes - */ - public abstract void setAuxilaryInformationData(byte[] auxilaryInformationData); - - /** - * Get inbound payload size - * - * @return int value - */ - public int getInboundPayloadSize() { - return inboundPayloadSize; - } - - /** - * Set inbound payload size - * - * @param inboundPayloadSizeData byte array of inbound payload size data - */ - public void setInboundPayloadSize(byte[] inboundPayloadSizeData) { - this.inboundPayloadSize = TypeConverter.littleEndianWordToInt(inboundPayloadSizeData); - } - - /** - * Get outbound payload size - * - * @return int value - */ - public int getOutboundPayloadSize() { - return outboundPayloadSize; - } - - /** - * Set outbound payload size - * - * @param outboundPayloadSizeData byte array of outbound payload size data - */ - public void setOutboundPayloadSize(byte[] outboundPayloadSizeData) { - this.outboundPayloadSize = TypeConverter.littleEndianWordToInt(outboundPayloadSizeData); - } - - /** - * Get payload udp port number - * - * @return Udp port number as int value - */ - public int getPayloadUdpPortNumber() { - return payloadUdpPortNumber; - } - - /** - * Set payload udp port number - * - * @param payloadUdpPortNumberData byte array of payload udp port number data - */ - public void setPayloadUdpPortNumber(byte[] payloadUdpPortNumberData) { - this.payloadUdpPortNumber = TypeConverter.littleEndianWordToInt(payloadUdpPortNumberData); - } - - /** - * Get payload vlan number - * - * @return vlan number data as int - */ - public int getPayloadVlanNumber() { - return payloadVlanNumber; - } - - /** - * Set payload vlan number - * - * @param payloadVlanNumberData byte array of payload vlan number data - */ - public void setPayloadVlanNumber(byte[] payloadVlanNumberData) { - this.payloadVlanNumber = TypeConverter.littleEndianWordToInt(payloadVlanNumberData); - } + /** + * Maximum size of a payload data field from remote console to BMC. + * Excludes size of confidentiality header and trailer fields, if any. + */ + private int inboundPayloadSize; + + /** + * Maximum size of a payload data field from BMC to remote console. + * Excludes size of confidentiality header and trailer fields, if any. + */ + private int outboundPayloadSize; + + /** + * UDP port number that payload can be transferred over. + */ + private int payloadUdpPortNumber; + + /** + * Payload VLAN number. FFFFh if VLAN addressing is not used. + */ + private int payloadVlanNumber; + + /** + * Set auxiliary information data + * + * @param auxilaryInformationData auxiliary information in bytes + */ + public abstract void setAuxilaryInformationData(byte[] auxilaryInformationData); + + /** + * Get inbound payload size + * + * @return int value + */ + public int getInboundPayloadSize() { + return inboundPayloadSize; + } + + /** + * Set inbound payload size + * + * @param inboundPayloadSizeData byte array of inbound payload size data + */ + public void setInboundPayloadSize(byte[] inboundPayloadSizeData) { + this.inboundPayloadSize = TypeConverter.littleEndianWordToInt(inboundPayloadSizeData); + } + + /** + * Get outbound payload size + * + * @return int value + */ + public int getOutboundPayloadSize() { + return outboundPayloadSize; + } + + /** + * Set outbound payload size + * + * @param outboundPayloadSizeData byte array of outbound payload size data + */ + public void setOutboundPayloadSize(byte[] outboundPayloadSizeData) { + this.outboundPayloadSize = TypeConverter.littleEndianWordToInt(outboundPayloadSizeData); + } + + /** + * Get payload udp port number + * + * @return Udp port number as int value + */ + public int getPayloadUdpPortNumber() { + return payloadUdpPortNumber; + } + + /** + * Set payload udp port number + * + * @param payloadUdpPortNumberData byte array of payload udp port number data + */ + public void setPayloadUdpPortNumber(byte[] payloadUdpPortNumberData) { + this.payloadUdpPortNumber = TypeConverter.littleEndianWordToInt(payloadUdpPortNumberData); + } + + /** + * Get payload vlan number + * + * @return vlan number data as int + */ + public int getPayloadVlanNumber() { + return payloadVlanNumber; + } + + /** + * Set payload vlan number + * + * @param payloadVlanNumberData byte array of payload vlan number data + */ + public void setPayloadVlanNumber(byte[] payloadVlanNumberData) { + this.payloadVlanNumber = TypeConverter.littleEndianWordToInt(payloadVlanNumberData); + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/payload/ActivateSolPayload.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/payload/ActivateSolPayload.java index 89e8497..b5cbd16 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/payload/ActivateSolPayload.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/payload/ActivateSolPayload.java @@ -36,46 +36,51 @@ public class ActivateSolPayload extends ActivatePayload { /** * Instantiate a new {@link ActivateSolPayload} - * @param cipherSuite Provides cipher suite (authentication, confidentiality - * and integrity algorithms used during the session). + * + * @param cipherSuite Provides cipher suite (authentication, confidentiality + * and integrity algorithms used during the session). * @param payloadInstance Paylaod instance as int */ - public ActivateSolPayload(CipherSuite cipherSuite, int payloadInstance) { - super(IpmiVersion.V20, cipherSuite, AuthenticationType.RMCPPlus, payloadInstance); - } + public ActivateSolPayload(CipherSuite cipherSuite, int payloadInstance) { + super(IpmiVersion.V20, cipherSuite, AuthenticationType.RMCPPlus, payloadInstance); + } - @Override - public PayloadType getPayloadType() { - return PayloadType.Sol; - } + @Override + public PayloadType getPayloadType() { + return PayloadType.Sol; + } - @Override - protected byte[] prepareAuxilaryRequestData() { - byte[] result = new byte[4]; + @Override + protected byte[] prepareAuxilaryRequestData() { + byte[] result = new byte[4]; - boolean isAuthenticationEnabled = getCipherSuite().getAuthenticationAlgorithm().getCode() != SecurityConstants.AA_RAKP_NONE; - boolean isEncryptionEnabled = getCipherSuite().getConfidentialityAlgorithm().getCode() != SecurityConstants.CA_NONE; + boolean isAuthenticationEnabled = getCipherSuite() + .getAuthenticationAlgorithm() + .getCode() != SecurityConstants.AA_RAKP_NONE; + boolean isEncryptionEnabled = getCipherSuite().getConfidentialityAlgorithm().getCode() != SecurityConstants.CA_NONE; - if (isEncryptionEnabled) { - //encryption bit - result[0] = TypeConverter.setBitOnPosition(7, result[0]); - } + if (isEncryptionEnabled) { + // encryption bit + result[0] = TypeConverter.setBitOnPosition(7, result[0]); + } - if (isAuthenticationEnabled) { - //authentication bit - result[0] = TypeConverter.setBitOnPosition(6, result[0]); - } + if (isAuthenticationEnabled) { + // authentication bit + result[0] = TypeConverter.setBitOnPosition(6, result[0]); + } - /*The following settings determine what happens to serial alerts - if IPMI over Serial and SOL are sharing the same baseboard serial controller. - Bit 2 set and bit 3 reset mean, that serial/modem alerts are deferred while SOL active*/ - result[0] = TypeConverter.setBitOnPosition(2, result[0]); + /* + * The following settings determine what happens to serial alerts + * if IPMI over Serial and SOL are sharing the same baseboard serial controller. + * Bit 2 set and bit 3 reset mean, that serial/modem alerts are deferred while SOL active + */ + result[0] = TypeConverter.setBitOnPosition(2, result[0]); - return result; - } + return result; + } - @Override - protected ActivatePayloadResponseData createEmptyResponse() { - return new ActivateSolPayloadResponseData(); - } + @Override + protected ActivatePayloadResponseData createEmptyResponse() { + return new ActivateSolPayloadResponseData(); + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/payload/ActivateSolPayloadResponseData.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/payload/ActivateSolPayloadResponseData.java index 909c1f1..380d2e7 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/payload/ActivateSolPayloadResponseData.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/payload/ActivateSolPayloadResponseData.java @@ -25,29 +25,29 @@ import org.metricshub.ipmi.core.common.TypeConverter; /** - * Concrete implementation of {@link ActivatePayloadResponseData} for {@link org.metricshub.ipmi.core.coding.protocol.PayloadType#SOL}. + * Concrete implementation of {@link ActivatePayloadResponseData} for + * {@link org.metricshub.ipmi.core.coding.protocol.PayloadType#SOL}. */ public class ActivateSolPayloadResponseData extends ActivatePayloadResponseData { - /** - * Information whether test mode is enabled or not. - */ - private boolean testMode; + /** + * Information whether test mode is enabled or not. + */ + private boolean testMode; - @Override - public void setAuxilaryInformationData(byte[] auxilaryInformationData) { - if (auxilaryInformationData == null || auxilaryInformationData.length < 1 || auxilaryInformationData.length > 4) { - throw new IllegalArgumentException("Auxilary information data must consists of 1 to 4 bytes"); - } + @Override + public void setAuxilaryInformationData(byte[] auxilaryInformationData) { + if (auxilaryInformationData == null || auxilaryInformationData.length < 1 || auxilaryInformationData.length > 4) { + throw new IllegalArgumentException("Auxilary information data must consists of 1 to 4 bytes"); + } - this.testMode = TypeConverter.isBitSetOnPosition(0, auxilaryInformationData[0]); - } + this.testMode = TypeConverter.isBitSetOnPosition(0, auxilaryInformationData[0]); + } - /** - * - * @return true if the test mode is enabled otherwise false - */ - public boolean isTestMode() { - return testMode; - } + /** + * @return true if the test mode is enabled otherwise false + */ + public boolean isTestMode() { + return testMode; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/payload/DeactivatePayload.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/payload/DeactivatePayload.java index 48d6236..5146065 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/payload/DeactivatePayload.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/payload/DeactivatePayload.java @@ -50,106 +50,116 @@ */ public class DeactivatePayload extends IpmiCommandCoder { - private static final Logger logger = LoggerFactory.getLogger(DeactivatePayload.class); - - private static final int REQUEST_DATA_LENGTH = 6; - - /** - * Payload type to be deactivated by this command. - */ - private final PayloadType payloadType; - - /** - * Number of payload instance to use when activating. - */ - private final int payloadInstance; - - public DeactivatePayload(CipherSuite cipherSuite, PayloadType payloadType, int payloadInstance) { - super(IpmiVersion.V20, cipherSuite, AuthenticationType.RMCPPlus); - this.payloadType = payloadType; - this.payloadInstance = payloadInstance; - } - - @Override - public byte getCommandCode() { - return CommandCodes.DEACTIVATE_PAYLOAD; - } - - /** - * Creates new instance of the {@link DeactivatePayload} command for deactivating given {@link PayloadType}. - * - * @param payloadType - * payload to be deactivated. - */ - public DeactivatePayload(PayloadType payloadType, int payloadInstance) { - this.payloadType = payloadType; - this.payloadInstance = payloadInstance; - } - - @Override - public NetworkFunction getNetworkFunction() { - return NetworkFunction.ApplicationRequest; - } - - @Override - protected IpmiPayload preparePayload(int sequenceNumber) throws NoSuchAlgorithmException, InvalidKeyException { - //We put just 2 bytes into the 6-bytes array, as specification for this command says to leave the rest 4 bytes as zeros - byte[] message = MessageComposer.get(REQUEST_DATA_LENGTH) - .appendField(TypeConverter.intToByte(payloadType.getCode())) - .appendField(TypeConverter.intToByte(payloadInstance)) - .getMessage(); - - return new IpmiLanRequest(getNetworkFunction(), getCommandCode(), message, TypeConverter.intToByte(sequenceNumber)); - } - - @Override - public ResponseData getResponseData(IpmiMessage message) throws IPMIException, NoSuchAlgorithmException, InvalidKeyException { - if (!isCommandResponse(message)) { - throw new IllegalArgumentException("This is not a response for Deactivate Payload command"); - } - - if (!(message.getPayload() instanceof IpmiLanResponse)) { - throw new IllegalArgumentException("Invalid response payload"); - } - - CompletionCode completionCode = ((IpmiLanResponse) message.getPayload()).getCompletionCode(); - - if (completionCode != CompletionCode.Ok) { - DeactivatePayloadCompletionCode specificCompletionCode = DeactivatePayloadCompletionCode.parseInt(completionCode.getCode()); - - if (specificCompletionCode == DeactivatePayloadCompletionCode.PAYLOAD_ALREADY_DEACTIVATED) { - logger.warn(specificCompletionCode.getMessage()); - } else { - throw new IPMIException(((IpmiLanResponse) message.getPayload()).getCompletionCode()); - } - } - - return new DeactivatePayloadResponseData(); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - DeactivatePayload that = (DeactivatePayload) o; - - if (payloadInstance != that.payloadInstance) { - return false; - } - - if (payloadType != that.payloadType) { - return false; - } - - return getCipherSuite().equals(that.getCipherSuite()); - } - - @Override - public int hashCode() { - int result = payloadInstance; - result = 31 * result + payloadType.getCode(); - result = 31 * result + (getCipherSuite() == null ? 0 : getCipherSuite().hashCode()); - return result; - } + private static final Logger LOGGER = LoggerFactory.getLogger(DeactivatePayload.class); + + private static final int REQUEST_DATA_LENGTH = 6; + + /** + * Payload type to be deactivated by this command. + */ + private final PayloadType payloadType; + + /** + * Number of payload instance to use when activating. + */ + private final int payloadInstance; + + public DeactivatePayload(CipherSuite cipherSuite, PayloadType payloadType, int payloadInstance) { + super(IpmiVersion.V20, cipherSuite, AuthenticationType.RMCPPlus); + this.payloadType = payloadType; + this.payloadInstance = payloadInstance; + } + + @Override + public byte getCommandCode() { + return CommandCodes.DEACTIVATE_PAYLOAD; + } + + /** + * Creates new instance of the {@link DeactivatePayload} command for deactivating given {@link PayloadType}. + * + * @param payloadType + * payload to be deactivated. + */ + public DeactivatePayload(PayloadType payloadType, int payloadInstance) { + this.payloadType = payloadType; + this.payloadInstance = payloadInstance; + } + + @Override + public NetworkFunction getNetworkFunction() { + return NetworkFunction.ApplicationRequest; + } + + @Override + protected IpmiPayload preparePayload(int sequenceNumber) throws NoSuchAlgorithmException, InvalidKeyException { + // We put just 2 bytes into the 6-bytes array, as specification for this command says to leave the rest 4 bytes as + // zeros + byte[] message = MessageComposer + .get(REQUEST_DATA_LENGTH) + .appendField(TypeConverter.intToByte(payloadType.getCode())) + .appendField(TypeConverter.intToByte(payloadInstance)) + .getMessage(); + + return new IpmiLanRequest(getNetworkFunction(), getCommandCode(), message, TypeConverter.intToByte(sequenceNumber)); + } + + @Override + public ResponseData getResponseData(IpmiMessage message) + throws IPMIException, + NoSuchAlgorithmException, + InvalidKeyException { + if (!isCommandResponse(message)) { + throw new IllegalArgumentException("This is not a response for Deactivate Payload command"); + } + + if (!(message.getPayload() instanceof IpmiLanResponse)) { + throw new IllegalArgumentException("Invalid response payload"); + } + + CompletionCode completionCode = ((IpmiLanResponse) message.getPayload()).getCompletionCode(); + + if (completionCode != CompletionCode.Ok) { + DeactivatePayloadCompletionCode specificCompletionCode = DeactivatePayloadCompletionCode + .parseInt(completionCode.getCode()); + + if (specificCompletionCode == DeactivatePayloadCompletionCode.PAYLOAD_ALREADY_DEACTIVATED) { + LOGGER.warn(specificCompletionCode.getMessage()); + } else { + throw new IPMIException(((IpmiLanResponse) message.getPayload()).getCompletionCode()); + } + } + + return new DeactivatePayloadResponseData(); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + DeactivatePayload that = (DeactivatePayload) o; + + if (payloadInstance != that.payloadInstance) { + return false; + } + + if (payloadType != that.payloadType) { + return false; + } + + return getCipherSuite().equals(that.getCipherSuite()); + } + + @Override + public int hashCode() { + int result = payloadInstance; + result = 31 * result + payloadType.getCode(); + result = 31 * result + (getCipherSuite() == null ? 0 : getCipherSuite().hashCode()); + return result; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/payload/DeactivatePayloadCompletionCode.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/payload/DeactivatePayloadCompletionCode.java index 8ebd924..c095a1e 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/payload/DeactivatePayloadCompletionCode.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/payload/DeactivatePayloadCompletionCode.java @@ -27,33 +27,32 @@ */ public enum DeactivatePayloadCompletionCode { - PAYLOAD_ALREADY_DEACTIVATED(0x80, "Payload already deactivated"), - PAYLOAD_TYPE_IS_DISABLED(0x81, "Given payload type is not configured to be enabled for activation"); - - - private final int code; - private final String message; - - DeactivatePayloadCompletionCode(int code, String message) { - this.code = code; - this.message = message; - } - - public int getCode() { - return code; - } - - public String getMessage() { - return message; - } - - public static DeactivatePayloadCompletionCode parseInt(int code) { - for (DeactivatePayloadCompletionCode completionCode : values()) { - if (completionCode.getCode() == code) { - return completionCode; - } - } - - return null; - } + PAYLOAD_ALREADY_DEACTIVATED(0x80, "Payload already deactivated"), + PAYLOAD_TYPE_IS_DISABLED(0x81, "Given payload type is not configured to be enabled for activation"); + + private final int code; + private final String message; + + DeactivatePayloadCompletionCode(int code, String message) { + this.code = code; + this.message = message; + } + + public int getCode() { + return code; + } + + public String getMessage() { + return message; + } + + public static DeactivatePayloadCompletionCode parseInt(int code) { + for (DeactivatePayloadCompletionCode completionCode : values()) { + if (completionCode.getCode() == code) { + return completionCode; + } + } + + return null; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/payload/GetChannelPayloadSupport.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/payload/GetChannelPayloadSupport.java index 018ab86..434dbe9 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/payload/GetChannelPayloadSupport.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/payload/GetChannelPayloadSupport.java @@ -46,109 +46,118 @@ */ public class GetChannelPayloadSupport extends IpmiCommandCoder { - private byte channelNumber; - - /** - * Initiates class for decoding. - */ - public GetChannelPayloadSupport() { - super(IpmiVersion.V20, new CipherSuite((byte) 0, (byte) 0, (byte) 0, (byte) 0), AuthenticationType.RMCPPlus); - } - - /** - * Initiates class for both encoding and decoding. - * - * @param channelNumber - * - must be 0h-Bh or Eh-Fh
- * Eh = retrieve information for channel this request was issued - * on - */ - public GetChannelPayloadSupport(byte channelNumber) { - super(IpmiVersion.V20, new CipherSuite((byte) 0, (byte) 0, (byte) 0, (byte) 0), AuthenticationType.RMCPPlus); - setChannelNumber(channelNumber); - } - - /** - * Initiates class for both encoding and decoding. - * - * @param channelNumber - * - must be 0h-Bh or Eh-Fh
- * Eh = retrieve information for channel this request was issued - * on - * @param cipherSuite - * - {@link CipherSuite} containing authentication, - * confidentiality and integrity algorithms for this session. - * @param authenticationType - * - Type of authentication used. Must be RMCPPlus for IPMI v2.0. - */ - public GetChannelPayloadSupport(byte channelNumber, CipherSuite cipherSuite, AuthenticationType authenticationType) { - super(IpmiVersion.V20, cipherSuite, authenticationType); - setChannelNumber(channelNumber); - } - - public byte getChannelNumber() { - return channelNumber; - } - - /** - * Sets the channel number that will be put into IPMI command. - * - * @param channelNumber - * - must be 0h-Bh or Eh-Fh
- * Eh = retrieve information for channel this request was issued - * on - * @throws IllegalArgumentException - */ - public void setChannelNumber(int channelNumber) { - if (channelNumber < 0 || channelNumber > 0xF || channelNumber == 0xC - || channelNumber == 0xD) { - throw new IllegalArgumentException("Invalid channel number"); - } - this.channelNumber = TypeConverter.intToByte(channelNumber); - } - - @Override - public byte getCommandCode() { - return GET_CHANNEL_PAYLOAD_SUPPORT; - } - - @Override - public NetworkFunction getNetworkFunction() { - return NetworkFunction.ApplicationRequest; - } - - @Override - protected IpmiPayload preparePayload(int sequenceNumber) throws NoSuchAlgorithmException, InvalidKeyException { - byte[] requestData = new byte[1]; - - requestData[0] = channelNumber; - - return new IpmiLanRequest(getNetworkFunction(), getCommandCode(), requestData, TypeConverter.intToByte(sequenceNumber)); - } - - @Override - public ResponseData getResponseData(IpmiMessage message) throws IPMIException, NoSuchAlgorithmException, InvalidKeyException { - if (!isCommandResponse(message)) { - throw new IllegalArgumentException("This is not a response for Get Payload Info command"); - } - - if (!(message.getPayload() instanceof IpmiLanResponse)) { - throw new IllegalArgumentException("Invalid response payload"); - } - - if (((IpmiLanResponse) message.getPayload()).getCompletionCode() != CompletionCode.Ok) { - throw new IPMIException(((IpmiLanResponse) message.getPayload()).getCompletionCode()); - } - - GetChannelPayloadSupportResponseData data = new GetChannelPayloadSupportResponseData(); - - byte[] responseData = message.getPayload().getData(); - - data.setStandardPayloads(responseData[0]); - data.setSessionSetupPayloads(responseData[1]); - data.setOemPayloads(responseData[2]); - - return data; - } + private byte channelNumber; + + /** + * Initiates class for decoding. + */ + public GetChannelPayloadSupport() { + super(IpmiVersion.V20, new CipherSuite((byte) 0, (byte) 0, (byte) 0, (byte) 0), AuthenticationType.RMCPPlus); + } + + /** + * Initiates class for both encoding and decoding. + * + * @param channelNumber + * - must be 0h-Bh or Eh-Fh
+ * Eh = retrieve information for channel this request was issued + * on + */ + public GetChannelPayloadSupport(byte channelNumber) { + super(IpmiVersion.V20, new CipherSuite((byte) 0, (byte) 0, (byte) 0, (byte) 0), AuthenticationType.RMCPPlus); + setChannelNumber(channelNumber); + } + + /** + * Initiates class for both encoding and decoding. + * + * @param channelNumber + * - must be 0h-Bh or Eh-Fh
+ * Eh = retrieve information for channel this request was issued + * on + * @param cipherSuite + * - {@link CipherSuite} containing authentication, + * confidentiality and integrity algorithms for this session. + * @param authenticationType + * - Type of authentication used. Must be RMCPPlus for IPMI v2.0. + */ + public GetChannelPayloadSupport(byte channelNumber, CipherSuite cipherSuite, AuthenticationType authenticationType) { + super(IpmiVersion.V20, cipherSuite, authenticationType); + setChannelNumber(channelNumber); + } + + public byte getChannelNumber() { + return channelNumber; + } + + /** + * Sets the channel number that will be put into IPMI command. + * + * @param channelNumber + * - must be 0h-Bh or Eh-Fh
+ * Eh = retrieve information for channel this request was issued + * on + * @throws IllegalArgumentException + */ + public void setChannelNumber(int channelNumber) { + if (channelNumber < 0 + || channelNumber > 0xF + || channelNumber == 0xC + || channelNumber == 0xD) { + throw new IllegalArgumentException("Invalid channel number"); + } + this.channelNumber = TypeConverter.intToByte(channelNumber); + } + + @Override + public byte getCommandCode() { + return GET_CHANNEL_PAYLOAD_SUPPORT; + } + + @Override + public NetworkFunction getNetworkFunction() { + return NetworkFunction.ApplicationRequest; + } + + @Override + protected IpmiPayload preparePayload(int sequenceNumber) throws NoSuchAlgorithmException, InvalidKeyException { + byte[] requestData = new byte[1]; + + requestData[0] = channelNumber; + + return new IpmiLanRequest( + getNetworkFunction(), + getCommandCode(), + requestData, + TypeConverter.intToByte(sequenceNumber)); + } + + @Override + public ResponseData getResponseData(IpmiMessage message) + throws IPMIException, + NoSuchAlgorithmException, + InvalidKeyException { + if (!isCommandResponse(message)) { + throw new IllegalArgumentException("This is not a response for Get Payload Info command"); + } + + if (!(message.getPayload() instanceof IpmiLanResponse)) { + throw new IllegalArgumentException("Invalid response payload"); + } + + if (((IpmiLanResponse) message.getPayload()).getCompletionCode() != CompletionCode.Ok) { + throw new IPMIException(((IpmiLanResponse) message.getPayload()).getCompletionCode()); + } + + GetChannelPayloadSupportResponseData data = new GetChannelPayloadSupportResponseData(); + + byte[] responseData = message.getPayload().getData(); + + data.setStandardPayloads(responseData[0]); + data.setSessionSetupPayloads(responseData[1]); + data.setOemPayloads(responseData[2]); + + return data; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/payload/GetChannelPayloadSupportResponseData.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/payload/GetChannelPayloadSupportResponseData.java index d19b388..e471041 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/payload/GetChannelPayloadSupportResponseData.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/payload/GetChannelPayloadSupportResponseData.java @@ -34,74 +34,89 @@ */ public class GetChannelPayloadSupportResponseData implements ResponseData { - /** - * Byte that carries information about supported Standard Payload Types. - */ - private byte standardPayloads; - - /** - * Byte that carries information about supported Session Setup Payload Types. - */ - private byte sessionSetupPayloads; - - /** - * Byte that carries information about supported OEM Payload Types. - */ - private byte oemPayloads; - - /** - * Set of supported {@link PayloadType}s. - */ - private Set supportedPayloads; - - public void setStandardPayloads(byte standardPayloads) { - this.standardPayloads = standardPayloads; - } - - public void setSessionSetupPayloads(byte sessionSetupPayloads) { - this.sessionSetupPayloads = sessionSetupPayloads; - } - - public void setOemPayloads(byte oemPayloads) { - this.oemPayloads = oemPayloads; - } - - public Set getSupportedPayloads() { - if (supportedPayloads == null) { - initializeSupportedPayloads(); - } - - return supportedPayloads; - } - - /** - * Reads raw data from standardPayloads, sessionSetupPayloads and oemPayloads bytes and converts it to the {@link Set} - * of supported {@link PayloadType}s - */ - private void initializeSupportedPayloads() { - supportedPayloads = new HashSet(); - - lookForGivenPayloads(standardPayloads, PayloadType.Ipmi, PayloadType.Sol, PayloadType.Oem); - lookForGivenPayloads(sessionSetupPayloads, PayloadType.RmcpOpenSessionRequest, PayloadType.RmcpOpenSessionResponse, - PayloadType.Rakp1, PayloadType.Rakp2, PayloadType.Rakp3, PayloadType.Rakp4); - lookForGivenPayloads(oemPayloads, PayloadType.Oem0, PayloadType.Oem1, PayloadType.Oem2, - PayloadType.Oem3, PayloadType.Oem4, PayloadType.Oem5, PayloadType.Oem6, PayloadType.Oem7); - } - - /** - * Checks if given payload types are enabled into given byte. If some of them is, adds this type to the output supportedPayloads. - * - * @param payloadsByte - * - byte carrying information about specific enabled payload types - * @param types - * - array of types that we want to search in given byte - */ - private void lookForGivenPayloads(byte payloadsByte, PayloadType... types) { - for (int i = 0; i < types.length; i++) { - if (TypeConverter.isBitSetOnPosition(i, payloadsByte)) { - supportedPayloads.add(types[i]); - } - } - } + /** + * Byte that carries information about supported Standard Payload Types. + */ + private byte standardPayloads; + + /** + * Byte that carries information about supported Session Setup Payload Types. + */ + private byte sessionSetupPayloads; + + /** + * Byte that carries information about supported OEM Payload Types. + */ + private byte oemPayloads; + + /** + * Set of supported {@link PayloadType}s. + */ + private Set supportedPayloads; + + public void setStandardPayloads(byte standardPayloads) { + this.standardPayloads = standardPayloads; + } + + public void setSessionSetupPayloads(byte sessionSetupPayloads) { + this.sessionSetupPayloads = sessionSetupPayloads; + } + + public void setOemPayloads(byte oemPayloads) { + this.oemPayloads = oemPayloads; + } + + public Set getSupportedPayloads() { + if (supportedPayloads == null) { + initializeSupportedPayloads(); + } + + return supportedPayloads; + } + + /** + * Reads raw data from standardPayloads, sessionSetupPayloads and oemPayloads bytes and converts it to the {@link Set} + * of supported {@link PayloadType}s + */ + private void initializeSupportedPayloads() { + supportedPayloads = new HashSet(); + + lookForGivenPayloads(standardPayloads, PayloadType.Ipmi, PayloadType.Sol, PayloadType.Oem); + lookForGivenPayloads( + sessionSetupPayloads, + PayloadType.RmcpOpenSessionRequest, + PayloadType.RmcpOpenSessionResponse, + PayloadType.Rakp1, + PayloadType.Rakp2, + PayloadType.Rakp3, + PayloadType.Rakp4); + lookForGivenPayloads( + oemPayloads, + PayloadType.Oem0, + PayloadType.Oem1, + PayloadType.Oem2, + PayloadType.Oem3, + PayloadType.Oem4, + PayloadType.Oem5, + PayloadType.Oem6, + PayloadType.Oem7); + } + + /** + * Checks if given payload types are enabled into given byte. If some of them is, adds this type to the output + * supportedPayloads. + * + * @param payloadsByte + * - byte carrying information about specific enabled payload types + * @param types + * - array of types that we want to search in given byte + */ + private void lookForGivenPayloads(byte payloadsByte, PayloadType... types) { + for (int i = 0; i < types.length; i++) { + if (TypeConverter.isBitSetOnPosition(i, payloadsByte)) { + supportedPayloads.add(types[i]); + } + } + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/payload/GetPayloadActivationStatus.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/payload/GetPayloadActivationStatus.java index 2243bbe..3319eed 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/payload/GetPayloadActivationStatus.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/payload/GetPayloadActivationStatus.java @@ -48,85 +48,93 @@ */ public class GetPayloadActivationStatus extends IpmiCommandCoder { - private static final int REQUEST_DATA_LENGTH = 1; - private static final int INSTANCE_CAPACITY_FIELD_LENGTH = 1; - private static final int AVAILABLE_INSTANCES_FIELD_LENGTH = 2; - - private final PayloadType payloadType; - - public GetPayloadActivationStatus(CipherSuite cipherSuite, PayloadType payloadType) { - super(IpmiVersion.V20, cipherSuite, AuthenticationType.RMCPPlus); - this.payloadType = payloadType; - } - - public GetPayloadActivationStatus(PayloadType payloadType) { - this.payloadType = payloadType; - } - - @Override - public byte getCommandCode() { - return CommandCodes.GET_PAYLOAD_ACTIVATION_STATUS; - } - - @Override - public NetworkFunction getNetworkFunction() { - return NetworkFunction.ApplicationRequest; - } - - @Override - protected IpmiPayload preparePayload(int sequenceNumber) throws NoSuchAlgorithmException, InvalidKeyException { - byte[] message = MessageComposer.get(REQUEST_DATA_LENGTH) - .appendField(TypeConverter.intToByte(payloadType.getCode())) - .getMessage(); - - return new IpmiLanRequest(getNetworkFunction(), getCommandCode(), message, TypeConverter.intToByte(sequenceNumber)); - } - - @Override - public ResponseData getResponseData(IpmiMessage message) throws IPMIException, NoSuchAlgorithmException, InvalidKeyException { - if (!isCommandResponse(message)) { - throw new IllegalArgumentException("This is not a response for Get Payload Activation Status"); - } - - if (!(message.getPayload() instanceof IpmiLanResponse)) { - throw new IllegalArgumentException("Invalid response payload"); - } - - if (((IpmiLanResponse) message.getPayload()).getCompletionCode() != CompletionCode.Ok) { - throw new IPMIException(((IpmiLanResponse) message.getPayload()).getCompletionCode()); - } - - MessageReader messageReader = new MessageReader(message.getPayload().getData()); - - GetPayloadActivationStatusResponseData responseData = new GetPayloadActivationStatusResponseData(); - - byte instaceCapacity = messageReader.readNextField(INSTANCE_CAPACITY_FIELD_LENGTH)[0]; - responseData.setInstanceCapacity(instaceCapacity); - - byte[] availableInstancesData = messageReader.readNextField(AVAILABLE_INSTANCES_FIELD_LENGTH); - responseData.setAvailableInstances(availableInstancesData); - - return responseData; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - GetPayloadActivationStatus that = (GetPayloadActivationStatus) o; - - if (payloadType != that.payloadType) { - return false; - } - - return getCipherSuite().equals(that.getCipherSuite()); - } - - @Override - public int hashCode() { - int result = payloadType.getCode(); - result = 31 * result + (getCipherSuite() != null ? getCipherSuite().hashCode() : 0); - return result; - } + private static final int REQUEST_DATA_LENGTH = 1; + private static final int INSTANCE_CAPACITY_FIELD_LENGTH = 1; + private static final int AVAILABLE_INSTANCES_FIELD_LENGTH = 2; + + private final PayloadType payloadType; + + public GetPayloadActivationStatus(CipherSuite cipherSuite, PayloadType payloadType) { + super(IpmiVersion.V20, cipherSuite, AuthenticationType.RMCPPlus); + this.payloadType = payloadType; + } + + public GetPayloadActivationStatus(PayloadType payloadType) { + this.payloadType = payloadType; + } + + @Override + public byte getCommandCode() { + return CommandCodes.GET_PAYLOAD_ACTIVATION_STATUS; + } + + @Override + public NetworkFunction getNetworkFunction() { + return NetworkFunction.ApplicationRequest; + } + + @Override + protected IpmiPayload preparePayload(int sequenceNumber) throws NoSuchAlgorithmException, InvalidKeyException { + byte[] message = MessageComposer + .get(REQUEST_DATA_LENGTH) + .appendField(TypeConverter.intToByte(payloadType.getCode())) + .getMessage(); + + return new IpmiLanRequest(getNetworkFunction(), getCommandCode(), message, TypeConverter.intToByte(sequenceNumber)); + } + + @Override + public ResponseData getResponseData(IpmiMessage message) + throws IPMIException, + NoSuchAlgorithmException, + InvalidKeyException { + if (!isCommandResponse(message)) { + throw new IllegalArgumentException("This is not a response for Get Payload Activation Status"); + } + + if (!(message.getPayload() instanceof IpmiLanResponse)) { + throw new IllegalArgumentException("Invalid response payload"); + } + + if (((IpmiLanResponse) message.getPayload()).getCompletionCode() != CompletionCode.Ok) { + throw new IPMIException(((IpmiLanResponse) message.getPayload()).getCompletionCode()); + } + + MessageReader messageReader = new MessageReader(message.getPayload().getData()); + + GetPayloadActivationStatusResponseData responseData = new GetPayloadActivationStatusResponseData(); + + byte instaceCapacity = messageReader.readNextField(INSTANCE_CAPACITY_FIELD_LENGTH)[0]; + responseData.setInstanceCapacity(instaceCapacity); + + byte[] availableInstancesData = messageReader.readNextField(AVAILABLE_INSTANCES_FIELD_LENGTH); + responseData.setAvailableInstances(availableInstancesData); + + return responseData; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + GetPayloadActivationStatus that = (GetPayloadActivationStatus) o; + + if (payloadType != that.payloadType) { + return false; + } + + return getCipherSuite().equals(that.getCipherSuite()); + } + + @Override + public int hashCode() { + int result = payloadType.getCode(); + result = 31 * result + (getCipherSuite() != null ? getCipherSuite().hashCode() : 0); + return result; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/payload/GetPayloadActivationStatusResponseData.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/payload/GetPayloadActivationStatusResponseData.java index bf3be86..284d0c4 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/payload/GetPayloadActivationStatusResponseData.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/payload/GetPayloadActivationStatusResponseData.java @@ -33,69 +33,69 @@ */ public class GetPayloadActivationStatusResponseData implements ResponseData { - /** - * Number of instances of given payload type that can be simultaneously activated on BMC. - */ - private byte instanceCapacity; - - /** - * List of instance ID's that are still available (not activated). - */ - private List availableInstances; - - public byte getInstanceCapacity() { - return instanceCapacity; - } - - public void setInstanceCapacity(byte instanceCapacity) { - this.instanceCapacity = instanceCapacity; - } - - public List getAvailableInstances() { - List actuallyAvailableInstances = new LinkedList(); - - for (Byte instanceId : availableInstances) { - if (instanceId <= instanceCapacity) { - actuallyAvailableInstances.add(instanceId); - } - } - - return actuallyAvailableInstances; - } - - public void setAvailableInstances(byte[] availableInstancesData) { - this.availableInstances = getAvailableInstancesFromBytes(availableInstancesData); - } - - private List getAvailableInstancesFromBytes(byte[] availableInstancesData) { - List result = new LinkedList(); - - List instancesFromFirstByte = checkForAvailableInstancesInByte(availableInstancesData[0], 0); - List instancesFromSecondByte = checkForAvailableInstancesInByte(availableInstancesData[1], 8); - - result.addAll(instancesFromFirstByte); - result.addAll(instancesFromSecondByte); - - return result; - } - - private List checkForAvailableInstancesInByte(byte availableInstancesByte, int instanceIdOffset) { - List result = new LinkedList(); - - for (int i = 0; i < 8; ++i) { - if (!TypeConverter.isBitSetOnPosition(i, availableInstancesByte)) { - result.add((byte) (i + 1 + instanceIdOffset)); - } - } - - return result; - } - - @Override - public String toString() { - return "GetPayloadActivationStatusResponseData{" + - "instanceCapacity=" + getInstanceCapacity() + - ", availableInstances=" + getAvailableInstances() + - '}'; - } + /** + * Number of instances of given payload type that can be simultaneously activated on BMC. + */ + private byte instanceCapacity; + + /** + * List of instance ID's that are still available (not activated). + */ + private List availableInstances; + + public byte getInstanceCapacity() { + return instanceCapacity; + } + + public void setInstanceCapacity(byte instanceCapacity) { + this.instanceCapacity = instanceCapacity; + } + + public List getAvailableInstances() { + List actuallyAvailableInstances = new LinkedList(); + + for (Byte instanceId : availableInstances) { + if (instanceId <= instanceCapacity) { + actuallyAvailableInstances.add(instanceId); + } + } + + return actuallyAvailableInstances; + } + + public void setAvailableInstances(byte[] availableInstancesData) { + this.availableInstances = getAvailableInstancesFromBytes(availableInstancesData); + } + + private List getAvailableInstancesFromBytes(byte[] availableInstancesData) { + List result = new LinkedList(); + + List instancesFromFirstByte = checkForAvailableInstancesInByte(availableInstancesData[0], 0); + List instancesFromSecondByte = checkForAvailableInstancesInByte(availableInstancesData[1], 8); + + result.addAll(instancesFromFirstByte); + result.addAll(instancesFromSecondByte); + + return result; + } + + private List checkForAvailableInstancesInByte(byte availableInstancesByte, int instanceIdOffset) { + List result = new LinkedList(); + + for (int i = 0; i < 8; ++i) { + if (!TypeConverter.isBitSetOnPosition(i, availableInstancesByte)) { + result.add((byte) (i + 1 + instanceIdOffset)); + } + } + + return result; + } + + @Override + public String toString() { + return "GetPayloadActivationStatusResponseData{" + + "instanceCapacity=" + getInstanceCapacity() + + ", availableInstances=" + getAvailableInstances() + + '}'; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/GetSdr.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/GetSdr.java index 419699c..512c761 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/GetSdr.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/GetSdr.java @@ -45,141 +45,156 @@ */ public class GetSdr extends IpmiCommandCoder { - private int reservationId; - - private int recordId; - - private int offset; - - private int bytesToRead; - - /** - * Initiates GetSdr for both encoding and decoding. 'Offset info record' and - * 'bytes to read' fields are set to read whole record. - * - * @param version - * - IPMI version of the command. - * @param cipherSuite - * - {@link CipherSuite} containing authentication, - * confidentiality and integrity algorithms for this session. - * @param authenticationType - * - Type of authentication used. Must be RMCPPlus for IPMI v2.0. - * @param reservationId - * - SDR reservation ID received via {@link ReserveSdrRepository} - * command - * @param recordId - * - ID of the record to get - */ - public GetSdr(IpmiVersion version, CipherSuite cipherSuite, - AuthenticationType authenticationType, int reservationId, - int recordId) { - this(version, cipherSuite, authenticationType, reservationId, recordId, - 0, 0xFF); - } - - /** - * Initiates GetSdr for both encoding and decoding. - * - * @param version - * - IPMI version of the command. - * @param cipherSuite - * - {@link CipherSuite} containing authentication, - * confidentiality and integrity algorithms for this session. - * @param authenticationType - * - Type of authentication used. Must be RMCPPlus for IPMI v2.0. - * @param reservationId - * - SDR reservation ID received via {@link ReserveSdrRepository} - * command - * @param recordId - * - ID of the record to get - * @param offset - * - the offset into record, at which reading should be started - * @param bytesToRead - * - number of bytes to read - */ - public GetSdr(IpmiVersion version, CipherSuite cipherSuite, - AuthenticationType authenticationType, int reservationId, - int recordId, int offset, int bytesToRead) { - super(version, cipherSuite, authenticationType); - this.recordId = recordId; - this.reservationId = reservationId; - this.offset = offset; - this.bytesToRead = bytesToRead; - } - - @Override - public byte getCommandCode() { - return CommandCodes.GET_SDR; - } - - @Override - public NetworkFunction getNetworkFunction() { - return NetworkFunction.StorageRequest; - } - - @Override - protected IpmiPayload preparePayload(int sequenceNumber) - throws NoSuchAlgorithmException, InvalidKeyException { - byte[] payload = new byte[6]; - - byte[] buffer = TypeConverter.intToByteArray(reservationId); - - payload[0] = buffer[3]; - payload[1] = buffer[2]; // reservation ID - - buffer = TypeConverter.intToByteArray(recordId); - - payload[2] = buffer[3]; - payload[3] = buffer[2]; // record ID - - payload[4] = TypeConverter.intToByte(offset); - payload[5] = TypeConverter.intToByte(bytesToRead); - - return new IpmiLanRequest(getNetworkFunction(), getCommandCode(), - payload, TypeConverter.intToByte(sequenceNumber)); - } - - @Override - public ResponseData getResponseData(IpmiMessage message) throws IPMIException, NoSuchAlgorithmException, InvalidKeyException { - if (!isCommandResponse(message)) { - throw new IllegalArgumentException( - "This is not a response for Get SDR command"); - } - if (!(message.getPayload() instanceof IpmiLanResponse)) { - throw new IllegalArgumentException("Invalid response payload"); - } - if (((IpmiLanResponse) message.getPayload()).getCompletionCode() != CompletionCode.Ok) { - throw new IPMIException( - ((IpmiLanResponse) message.getPayload()) - .getCompletionCode()); - } - - byte[] raw = message.getPayload().getIpmiCommandData(); - - if (raw == null || raw.length < 3) { - throw new IllegalArgumentException( - "Invalid response payload length"); - } - - GetSdrResponseData responseData = new GetSdrResponseData(); - - byte[] buffer = new byte[4]; - - buffer[0] = raw[0]; - buffer[1] = raw[1]; - buffer[2] = 0; - buffer[3] = 0; - - responseData.setNextRecordId(TypeConverter - .littleEndianByteArrayToInt(buffer)); - - byte[] recordData = new byte[raw.length - 2]; - - System.arraycopy(raw, 2, recordData, 0, recordData.length); - - responseData.setSensorRecordData(recordData); - - return responseData; - } + private int reservationId; + + private int recordId; + + private int offset; + + private int bytesToRead; + + /** + * Initiates GetSdr for both encoding and decoding. 'Offset info record' and + * 'bytes to read' fields are set to read whole record. + * + * @param version + * - IPMI version of the command. + * @param cipherSuite + * - {@link CipherSuite} containing authentication, + * confidentiality and integrity algorithms for this session. + * @param authenticationType + * - Type of authentication used. Must be RMCPPlus for IPMI v2.0. + * @param reservationId + * - SDR reservation ID received via {@link ReserveSdrRepository} + * command + * @param recordId + * - ID of the record to get + */ + public GetSdr(IpmiVersion version, CipherSuite cipherSuite, + AuthenticationType authenticationType, int reservationId, + int recordId) { + this( + version, + cipherSuite, + authenticationType, + reservationId, + recordId, + 0, + 0xFF); + } + + /** + * Initiates GetSdr for both encoding and decoding. + * + * @param version + * - IPMI version of the command. + * @param cipherSuite + * - {@link CipherSuite} containing authentication, + * confidentiality and integrity algorithms for this session. + * @param authenticationType + * - Type of authentication used. Must be RMCPPlus for IPMI v2.0. + * @param reservationId + * - SDR reservation ID received via {@link ReserveSdrRepository} + * command + * @param recordId + * - ID of the record to get + * @param offset + * - the offset into record, at which reading should be started + * @param bytesToRead + * - number of bytes to read + */ + public GetSdr(IpmiVersion version, CipherSuite cipherSuite, + AuthenticationType authenticationType, int reservationId, + int recordId, int offset, int bytesToRead) { + super(version, cipherSuite, authenticationType); + this.recordId = recordId; + this.reservationId = reservationId; + this.offset = offset; + this.bytesToRead = bytesToRead; + } + + @Override + public byte getCommandCode() { + return CommandCodes.GET_SDR; + } + + @Override + public NetworkFunction getNetworkFunction() { + return NetworkFunction.StorageRequest; + } + + @Override + protected IpmiPayload preparePayload(int sequenceNumber) + throws NoSuchAlgorithmException, + InvalidKeyException { + byte[] payload = new byte[6]; + + byte[] buffer = TypeConverter.intToByteArray(reservationId); + + payload[0] = buffer[3]; + payload[1] = buffer[2]; // reservation ID + + buffer = TypeConverter.intToByteArray(recordId); + + payload[2] = buffer[3]; + payload[3] = buffer[2]; // record ID + + payload[4] = TypeConverter.intToByte(offset); + payload[5] = TypeConverter.intToByte(bytesToRead); + + return new IpmiLanRequest( + getNetworkFunction(), + getCommandCode(), + payload, + TypeConverter.intToByte(sequenceNumber)); + } + + @Override + public ResponseData getResponseData(IpmiMessage message) + throws IPMIException, + NoSuchAlgorithmException, + InvalidKeyException { + if (!isCommandResponse(message)) { + throw new IllegalArgumentException( + "This is not a response for Get SDR command"); + } + if (!(message.getPayload() instanceof IpmiLanResponse)) { + throw new IllegalArgumentException("Invalid response payload"); + } + if (((IpmiLanResponse) message.getPayload()).getCompletionCode() != CompletionCode.Ok) { + throw new IPMIException( + ((IpmiLanResponse) message.getPayload()) + .getCompletionCode()); + } + + byte[] raw = message.getPayload().getIpmiCommandData(); + + if (raw == null || raw.length < 3) { + throw new IllegalArgumentException( + "Invalid response payload length"); + } + + GetSdrResponseData responseData = new GetSdrResponseData(); + + byte[] buffer = new byte[4]; + + buffer[0] = raw[0]; + buffer[1] = raw[1]; + buffer[2] = 0; + buffer[3] = 0; + + responseData + .setNextRecordId( + TypeConverter + .littleEndianByteArrayToInt(buffer)); + + byte[] recordData = new byte[raw.length - 2]; + + System.arraycopy(raw, 2, recordData, 0, recordData.length); + + responseData.setSensorRecordData(recordData); + + return responseData; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/GetSdrRepositoryInfo.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/GetSdrRepositoryInfo.java index 94c3d44..d25bd09 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/GetSdrRepositoryInfo.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/GetSdrRepositoryInfo.java @@ -47,90 +47,105 @@ */ public class GetSdrRepositoryInfo extends IpmiCommandCoder { - /** - * Initiates GetSdrRepositoryInfo for both encoding and decoding. - * - * @param version - * - IPMI version of the command. - * @param cipherSuite - * - {@link CipherSuite} containing authentication, - * confidentiality and integrity algorithms for this session. - * @param authenticationType - * - Type of authentication used. Must be RMCPPlus for IPMI v2.0. - */ - public GetSdrRepositoryInfo(IpmiVersion version, CipherSuite cipherSuite, - AuthenticationType authenticationType) { - super(version, cipherSuite, authenticationType); - } - - @Override - public byte getCommandCode() { - return CommandCodes.GET_SDR_REPOSITORY_INFO; - } - - @Override - public NetworkFunction getNetworkFunction() { - return NetworkFunction.StorageRequest; - } - - @Override - protected IpmiPayload preparePayload(int sequenceNumber) - throws NoSuchAlgorithmException, InvalidKeyException { - return new IpmiLanRequest(getNetworkFunction(), getCommandCode(), null, - TypeConverter.intToByte(sequenceNumber)); - } - - @Override - public ResponseData getResponseData(IpmiMessage message) throws IPMIException, NoSuchAlgorithmException, InvalidKeyException { - if (!isCommandResponse(message)) { - throw new IllegalArgumentException( - "This is not a response for Get SDR Repository Info command"); - } - if (!(message.getPayload() instanceof IpmiLanResponse)) { - throw new IllegalArgumentException("Invalid response payload"); - } - if (((IpmiLanResponse) message.getPayload()).getCompletionCode() != CompletionCode.Ok) { - throw new IPMIException( - ((IpmiLanResponse) message.getPayload()) - .getCompletionCode()); - } - - byte[] raw = message.getPayload().getIpmiCommandData(); - - if (raw == null || raw.length != 14) { - throw new IllegalArgumentException( - "Invalid response payload length"); - } - - GetSdrRepositoryInfoResponseData responseData = new GetSdrRepositoryInfoResponseData(); - - responseData.setSdrVersion(TypeConverter - .littleEndianBcdByteToInt(raw[0])); - - byte[] buffer = new byte[4]; - - buffer[0] = raw[1]; - buffer[1] = raw[2]; - buffer[2] = 0; - buffer[3] = 0; - - responseData.setRecordCount(TypeConverter - .littleEndianByteArrayToInt(buffer)); - - System.arraycopy(raw, 5, buffer, 0, 4); - - responseData.setAddTimestamp(TypeConverter - .littleEndianByteArrayToInt(buffer)); - - System.arraycopy(raw, 9, buffer, 0, 4); - - responseData.setDelTimestamp(TypeConverter - .littleEndianByteArrayToInt(buffer)); - - responseData - .setReserveSupported((TypeConverter.byteToInt(raw[13]) & 0x2) != 0); - - return responseData; - } + /** + * Initiates GetSdrRepositoryInfo for both encoding and decoding. + * + * @param version + * - IPMI version of the command. + * @param cipherSuite + * - {@link CipherSuite} containing authentication, + * confidentiality and integrity algorithms for this session. + * @param authenticationType + * - Type of authentication used. Must be RMCPPlus for IPMI v2.0. + */ + public GetSdrRepositoryInfo(IpmiVersion version, CipherSuite cipherSuite, + AuthenticationType authenticationType) { + super(version, cipherSuite, authenticationType); + } + + @Override + public byte getCommandCode() { + return CommandCodes.GET_SDR_REPOSITORY_INFO; + } + + @Override + public NetworkFunction getNetworkFunction() { + return NetworkFunction.StorageRequest; + } + + @Override + protected IpmiPayload preparePayload(int sequenceNumber) + throws NoSuchAlgorithmException, + InvalidKeyException { + return new IpmiLanRequest( + getNetworkFunction(), + getCommandCode(), + null, + TypeConverter.intToByte(sequenceNumber)); + } + + @Override + public ResponseData getResponseData(IpmiMessage message) + throws IPMIException, + NoSuchAlgorithmException, + InvalidKeyException { + if (!isCommandResponse(message)) { + throw new IllegalArgumentException( + "This is not a response for Get SDR Repository Info command"); + } + if (!(message.getPayload() instanceof IpmiLanResponse)) { + throw new IllegalArgumentException("Invalid response payload"); + } + if (((IpmiLanResponse) message.getPayload()).getCompletionCode() != CompletionCode.Ok) { + throw new IPMIException( + ((IpmiLanResponse) message.getPayload()) + .getCompletionCode()); + } + + byte[] raw = message.getPayload().getIpmiCommandData(); + + if (raw == null || raw.length != 14) { + throw new IllegalArgumentException( + "Invalid response payload length"); + } + + GetSdrRepositoryInfoResponseData responseData = new GetSdrRepositoryInfoResponseData(); + + responseData + .setSdrVersion( + TypeConverter + .littleEndianBcdByteToInt(raw[0])); + + byte[] buffer = new byte[4]; + + buffer[0] = raw[1]; + buffer[1] = raw[2]; + buffer[2] = 0; + buffer[3] = 0; + + responseData + .setRecordCount( + TypeConverter + .littleEndianByteArrayToInt(buffer)); + + System.arraycopy(raw, 5, buffer, 0, 4); + + responseData + .setAddTimestamp( + TypeConverter + .littleEndianByteArrayToInt(buffer)); + + System.arraycopy(raw, 9, buffer, 0, 4); + + responseData + .setDelTimestamp( + TypeConverter + .littleEndianByteArrayToInt(buffer)); + + responseData + .setReserveSupported((TypeConverter.byteToInt(raw[13]) & 0x2) != 0); + + return responseData; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/GetSdrRepositoryInfoResponseData.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/GetSdrRepositoryInfoResponseData.java index f1a3e5b..a20d6e7 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/GetSdrRepositoryInfoResponseData.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/GetSdrRepositoryInfoResponseData.java @@ -28,70 +28,69 @@ * Wrapper for Get SDR Repository Info response. */ public class GetSdrRepositoryInfoResponseData implements ResponseData { - /** - * Version number of the SDR command set for the SDR Device. - */ - private int sdrVersion; - - /** - * Number of records in the SDR Repository - */ - private int recordCount; - - /** - * Most recent addition timestamp. - */ - private int addTimestamp; - - /** - * Most recent erase (delete or clear) timestamp. - */ - private int delTimestamp; - - /** - * Reserve SDR Repository command supported - */ - private boolean reserveSupported; - - public void setSdrVersion(int sdrVersion) { - this.sdrVersion = sdrVersion; - } - - public int getSdrVersion() { - return sdrVersion; - } - - public void setRecordCount(int recordCount) { - this.recordCount = recordCount; - } - - public int getRecordCount() { - return recordCount; - } - - public void setAddTimestamp(int addTimestamp) { - this.addTimestamp = addTimestamp; - } - - public int getAddTimestamp() { - return addTimestamp; - } - - public void setDelTimestamp(int delTimestamp) { - this.delTimestamp = delTimestamp; - } - - public int getDelTimestamp() { - return delTimestamp; - } - - public void setReserveSupported(boolean reserveSupported) { - this.reserveSupported = reserveSupported; - } - - public boolean isReserveSupported() { - return reserveSupported; - } - + /** + * Version number of the SDR command set for the SDR Device. + */ + private int sdrVersion; + + /** + * Number of records in the SDR Repository + */ + private int recordCount; + + /** + * Most recent addition timestamp. + */ + private int addTimestamp; + + /** + * Most recent erase (delete or clear) timestamp. + */ + private int delTimestamp; + + /** + * Reserve SDR Repository command supported + */ + private boolean reserveSupported; + + public void setSdrVersion(int sdrVersion) { + this.sdrVersion = sdrVersion; + } + + public int getSdrVersion() { + return sdrVersion; + } + + public void setRecordCount(int recordCount) { + this.recordCount = recordCount; + } + + public int getRecordCount() { + return recordCount; + } + + public void setAddTimestamp(int addTimestamp) { + this.addTimestamp = addTimestamp; + } + + public int getAddTimestamp() { + return addTimestamp; + } + + public void setDelTimestamp(int delTimestamp) { + this.delTimestamp = delTimestamp; + } + + public int getDelTimestamp() { + return delTimestamp; + } + + public void setReserveSupported(boolean reserveSupported) { + this.reserveSupported = reserveSupported; + } + + public boolean isReserveSupported() { + return reserveSupported; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/GetSdrResponseData.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/GetSdrResponseData.java index 05e9e97..5628ba4 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/GetSdrResponseData.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/GetSdrResponseData.java @@ -30,34 +30,34 @@ */ public class GetSdrResponseData implements ResponseData { - /** - * ID of the next record in the repository. - */ - private int nextRecordId; - - /** - * Sensor record data - */ - private byte[] sensorRecordData; - - public void setNextRecordId(int nextRecordId) { - this.nextRecordId = nextRecordId; - } - - public int getNextRecordId() { - return nextRecordId; - } - - public void setSensorRecordData(byte[] sensorRecordData) { - this.sensorRecordData = sensorRecordData; - } - - /** - * @return Unparsed sensor record data. Might contain only part of the - * record, depending on offset and size specified in the request. To - * parse data use {@link SensorRecord#populateSensorRecord(byte[])}. - */ - public byte[] getSensorRecordData() { - return sensorRecordData; - } + /** + * ID of the next record in the repository. + */ + private int nextRecordId; + + /** + * Sensor record data + */ + private byte[] sensorRecordData; + + public void setNextRecordId(int nextRecordId) { + this.nextRecordId = nextRecordId; + } + + public int getNextRecordId() { + return nextRecordId; + } + + public void setSensorRecordData(byte[] sensorRecordData) { + this.sensorRecordData = sensorRecordData; + } + + /** + * @return Unparsed sensor record data. Might contain only part of the + * record, depending on offset and size specified in the request. To + * parse data use {@link SensorRecord#populateSensorRecord(byte[])}. + */ + public byte[] getSensorRecordData() { + return sensorRecordData; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/GetSensorReading.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/GetSensorReading.java index aa164de..8ab710b 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/GetSensorReading.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/GetSensorReading.java @@ -44,104 +44,115 @@ */ public class GetSensorReading extends IpmiCommandCoder { - private byte sensorId; - - /** - * Initiates class for both encoding and decoding. - * - * @param version - * - IPMI version of the command. - * @param cipherSuite - * - {@link CipherSuite} containing authentication, - * confidentiality and integrity algorithms for this session. - * @param authenticationType - * - Type of authentication used. Must be RMCPPlus for IPMI v2.0. - * @param sensorId - * - ID of the sensor which reading is to be retrieved - */ - public GetSensorReading(IpmiVersion version, CipherSuite cipherSuite, - AuthenticationType authenticationType, int sensorId) { - super(version, cipherSuite, authenticationType); - this.sensorId = TypeConverter.intToByte(sensorId); - } - - @Override - public byte getCommandCode() { - return 0x2d; - } - - @Override - public NetworkFunction getNetworkFunction() { - return NetworkFunction.SensorRequest; - } - - @Override - protected IpmiPayload preparePayload(int sequenceNumber) - throws NoSuchAlgorithmException, InvalidKeyException { - byte[] payloadData = new byte[] { sensorId }; - return new IpmiLanRequest(getNetworkFunction(), getCommandCode(), - payloadData, TypeConverter.intToByte(sequenceNumber)); - } - - @Override - public ResponseData getResponseData(IpmiMessage message) throws IPMIException, NoSuchAlgorithmException, InvalidKeyException { - - if (!isCommandResponse(message)) { - throw new IllegalArgumentException( - "This is not a response for Get Sensor Reading command"); - } - if (!(message.getPayload() instanceof IpmiLanResponse)) { - throw new IllegalArgumentException("Invalid response payload"); - } - if (((IpmiLanResponse) message.getPayload()).getCompletionCode() != CompletionCode.Ok) { - throw new IPMIException( - ((IpmiLanResponse) message.getPayload()) - .getCompletionCode()); - } - - byte[] raw = message.getPayload().getIpmiCommandData(); - - if (raw.length < 2) { - throw new IllegalStateException("Invalid data length"); - } - - GetSensorReadingResponseData responseData = new GetSensorReadingResponseData(); - - responseData.setRaw(raw); - - responseData.setSensorReading(raw[0]); - - responseData - .setSensorStateValid((TypeConverter.byteToInt(raw[1]) & 0x20) == 0); - - if (raw.length >= 3) { - responseData.setSensorState(SensorState.parseInt((TypeConverter - .byteToInt(raw[2])) & 0x3f)); - - boolean[] states = null; - - if (raw.length > 3) { - states = new boolean[16]; - } else { - states = new boolean[8]; - } - - for (int i = 0; i < 8; ++i) { - states[i] = (TypeConverter.byteToInt(raw[2]) & (0x1 << i)) != 0; - } - - if (raw.length > 3) { - for (int i = 0; i < 7; ++i) { - states[i + 8] = (TypeConverter.byteToInt(raw[3]) & (0x1 << i)) != 0; - } - states[15] = false; - } - - responseData.setStatesAsserted(states); - - } - - return responseData; - } + private byte sensorId; + + /** + * Initiates class for both encoding and decoding. + * + * @param version + * - IPMI version of the command. + * @param cipherSuite + * - {@link CipherSuite} containing authentication, + * confidentiality and integrity algorithms for this session. + * @param authenticationType + * - Type of authentication used. Must be RMCPPlus for IPMI v2.0. + * @param sensorId + * - ID of the sensor which reading is to be retrieved + */ + public GetSensorReading(IpmiVersion version, CipherSuite cipherSuite, + AuthenticationType authenticationType, int sensorId) { + super(version, cipherSuite, authenticationType); + this.sensorId = TypeConverter.intToByte(sensorId); + } + + @Override + public byte getCommandCode() { + return 0x2d; + } + + @Override + public NetworkFunction getNetworkFunction() { + return NetworkFunction.SensorRequest; + } + + @Override + protected IpmiPayload preparePayload(int sequenceNumber) + throws NoSuchAlgorithmException, + InvalidKeyException { + byte[] payloadData = new byte[] { sensorId }; + return new IpmiLanRequest( + getNetworkFunction(), + getCommandCode(), + payloadData, + TypeConverter.intToByte(sequenceNumber)); + } + + @Override + public ResponseData getResponseData(IpmiMessage message) + throws IPMIException, + NoSuchAlgorithmException, + InvalidKeyException { + + if (!isCommandResponse(message)) { + throw new IllegalArgumentException( + "This is not a response for Get Sensor Reading command"); + } + if (!(message.getPayload() instanceof IpmiLanResponse)) { + throw new IllegalArgumentException("Invalid response payload"); + } + if (((IpmiLanResponse) message.getPayload()).getCompletionCode() != CompletionCode.Ok) { + throw new IPMIException( + ((IpmiLanResponse) message.getPayload()) + .getCompletionCode()); + } + + byte[] raw = message.getPayload().getIpmiCommandData(); + + if (raw.length < 2) { + throw new IllegalStateException("Invalid data length"); + } + + GetSensorReadingResponseData responseData = new GetSensorReadingResponseData(); + + responseData.setRaw(raw); + + responseData.setSensorReading(raw[0]); + + responseData + .setSensorStateValid((TypeConverter.byteToInt(raw[1]) & 0x20) == 0); + + if (raw.length >= 3) { + responseData + .setSensorState( + SensorState + .parseInt( + (TypeConverter + .byteToInt(raw[2])) & 0x3f)); + + boolean[] states = null; + + if (raw.length > 3) { + states = new boolean[16]; + } else { + states = new boolean[8]; + } + + for (int i = 0; i < 8; ++i) { + states[i] = (TypeConverter.byteToInt(raw[2]) & (0x1 << i)) != 0; + } + + if (raw.length > 3) { + for (int i = 0; i < 7; ++i) { + states[i + 8] = (TypeConverter.byteToInt(raw[3]) & (0x1 << i)) != 0; + } + states[15] = false; + } + + responseData.setStatesAsserted(states); + + } + + return responseData; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/GetSensorReadingResponseData.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/GetSensorReadingResponseData.java index 86ae5b9..bc60468 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/GetSensorReadingResponseData.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/GetSensorReadingResponseData.java @@ -37,66 +37,66 @@ * Wrapper for Get Sensor Reading response. */ public class GetSensorReadingResponseData implements ResponseData { - private byte sensorReading; - - /** - * This bit is set to indicate that a 're-arm' or 'Set Event Receiver' - * command has been used to request an update of the sensor status, and that - * update has not occurred yet. Software should use this bit to avoid - * getting an incorrect status while the first sensor update is in progress. - */ - private boolean sensorStateValid; - - /** - * Contains state of the sensor if it is threshold-based. - */ - private SensorState sensorState; - - /** - * Contains state of the sensor if it is discrete. - */ - private boolean[] statesAsserted; - - /** - * Contains raw IPMI command data. - */ - private byte[] raw; - - public double getSensorReading(FullSensorRecord sensorRecord) { - return sensorRecord.calcFormula(TypeConverter.byteToInt(sensorReading)); - } - - public double getPlainSensorReading() { - return TypeConverter.byteToInt(sensorReading); - } - - public void setSensorReading(byte sensorReading) { - this.sensorReading = sensorReading; - } - - public boolean isSensorStateValid() { - return sensorStateValid; - } - - public void setSensorStateValid(boolean sensorStateValid) { - this.sensorStateValid = sensorStateValid; - } - - /** - * Contains state of the sensor if it is threshold-based. - */ - public SensorState getSensorState() { - return sensorState; - } - - public void setSensorState(SensorState sensorState) { - this.sensorState = sensorState; - } - - /** - * Contains raw IPMI command data. - */ - public byte[] getRaw() { + private byte sensorReading; + + /** + * This bit is set to indicate that a 're-arm' or 'Set Event Receiver' + * command has been used to request an update of the sensor status, and that + * update has not occurred yet. Software should use this bit to avoid + * getting an incorrect status while the first sensor update is in progress. + */ + private boolean sensorStateValid; + + /** + * Contains state of the sensor if it is threshold-based. + */ + private SensorState sensorState; + + /** + * Contains state of the sensor if it is discrete. + */ + private boolean[] statesAsserted; + + /** + * Contains raw IPMI command data. + */ + private byte[] raw; + + public double getSensorReading(FullSensorRecord sensorRecord) { + return sensorRecord.calcFormula(TypeConverter.byteToInt(sensorReading)); + } + + public double getPlainSensorReading() { + return TypeConverter.byteToInt(sensorReading); + } + + public void setSensorReading(byte sensorReading) { + this.sensorReading = sensorReading; + } + + public boolean isSensorStateValid() { + return sensorStateValid; + } + + public void setSensorStateValid(boolean sensorStateValid) { + this.sensorStateValid = sensorStateValid; + } + + /** + * Contains state of the sensor if it is threshold-based. + */ + public SensorState getSensorState() { + return sensorState; + } + + public void setSensorState(SensorState sensorState) { + this.sensorState = sensorState; + } + + /** + * Contains raw IPMI command data. + */ + public byte[] getRaw() { return raw; } @@ -104,28 +104,34 @@ public void setRaw(byte[] raw) { this.raw = raw; } - /** - * Contains state of the sensor if it is discrete. - * - * @param sensorEventReadingType - * - value received via - * {@link FullSensorRecord#getEventReadingType()}, - * {@link CompactSensorRecord#getEventReadingType()} or - * {@link EventOnlyRecord#getEventReadingType()} - */ - public List getStatesAsserted(SensorType sensorType, - int sensorEventReadingType) { - ArrayList list = new ArrayList(); - for (int i = 0; i < statesAsserted.length; ++i) { - if (statesAsserted[i]) { - list.add(ReadingType.parseInt(sensorType, - sensorEventReadingType, i)); - } - } - return list; - } - - public void setStatesAsserted(boolean[] statesAsserted) { - this.statesAsserted = statesAsserted; - } + /** + * Contains state of the sensor if it is discrete. + * + * @param sensorEventReadingType + * - value received via + * {@link FullSensorRecord#getEventReadingType()}, + * {@link CompactSensorRecord#getEventReadingType()} or + * {@link EventOnlyRecord#getEventReadingType()} + */ + public List getStatesAsserted( + SensorType sensorType, + int sensorEventReadingType) { + ArrayList list = new ArrayList(); + for (int i = 0; i < statesAsserted.length; ++i) { + if (statesAsserted[i]) { + list + .add( + ReadingType + .parseInt( + sensorType, + sensorEventReadingType, + i)); + } + } + return list; + } + + public void setStatesAsserted(boolean[] statesAsserted) { + this.statesAsserted = statesAsserted; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/ReserveSdrRepository.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/ReserveSdrRepository.java index 3e5735f..6dd2ae6 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/ReserveSdrRepository.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/ReserveSdrRepository.java @@ -45,75 +45,83 @@ */ public class ReserveSdrRepository extends IpmiCommandCoder { - /** - * Initiates ReserveSdrRepository for both encoding and decoding. - * - * @param version - * - IPMI version of the command. - * @param cipherSuite - * - {@link CipherSuite} containing authentication, - * confidentiality and integrity algorithms for this session. - * @param authenticationType - * - Type of authentication used. Must be RMCPPlus for IPMI v2.0. - */ - public ReserveSdrRepository(IpmiVersion version, CipherSuite cipherSuite, - AuthenticationType authenticationType) { - super(version, cipherSuite, authenticationType); - } - - @Override - public byte getCommandCode() { - return CommandCodes.RESERVE_SDR_REPOSITORY; - } - - @Override - public NetworkFunction getNetworkFunction() { - return NetworkFunction.StorageRequest; - } - - @Override - protected IpmiPayload preparePayload(int sequenceNumber) - throws NoSuchAlgorithmException, InvalidKeyException { - return new IpmiLanRequest(getNetworkFunction(), getCommandCode(), null, - TypeConverter.intToByte(sequenceNumber)); - } - - @Override - public ResponseData getResponseData(IpmiMessage message) throws IPMIException, - NoSuchAlgorithmException, InvalidKeyException { - if (!isCommandResponse(message)) { - throw new IllegalArgumentException( - "This is not a response for Reserve SDR Repository command"); - } - if (!(message.getPayload() instanceof IpmiLanResponse)) { - throw new IllegalArgumentException("Invalid response payload"); - } - if (((IpmiLanResponse) message.getPayload()).getCompletionCode() != CompletionCode.Ok) { - throw new IPMIException( - ((IpmiLanResponse) message.getPayload()) - .getCompletionCode()); - } - - byte[] raw = message.getPayload().getIpmiCommandData(); - - if (raw == null || raw.length != 2) { - throw new IllegalArgumentException( - "Invalid response payload length"); - } - - ReserveSdrRepositoryResponseData responseData = new ReserveSdrRepositoryResponseData(); - - byte[] buffer = new byte[4]; - - buffer[0] = raw[0]; - buffer[1] = raw[1]; - buffer[2] = 0; - buffer[3] = 0; - - responseData.setReservationId(TypeConverter - .littleEndianByteArrayToInt(buffer)); - - return responseData; - } + /** + * Initiates ReserveSdrRepository for both encoding and decoding. + * + * @param version + * - IPMI version of the command. + * @param cipherSuite + * - {@link CipherSuite} containing authentication, + * confidentiality and integrity algorithms for this session. + * @param authenticationType + * - Type of authentication used. Must be RMCPPlus for IPMI v2.0. + */ + public ReserveSdrRepository(IpmiVersion version, CipherSuite cipherSuite, + AuthenticationType authenticationType) { + super(version, cipherSuite, authenticationType); + } + + @Override + public byte getCommandCode() { + return CommandCodes.RESERVE_SDR_REPOSITORY; + } + + @Override + public NetworkFunction getNetworkFunction() { + return NetworkFunction.StorageRequest; + } + + @Override + protected IpmiPayload preparePayload(int sequenceNumber) + throws NoSuchAlgorithmException, + InvalidKeyException { + return new IpmiLanRequest( + getNetworkFunction(), + getCommandCode(), + null, + TypeConverter.intToByte(sequenceNumber)); + } + + @Override + public ResponseData getResponseData(IpmiMessage message) + throws IPMIException, + NoSuchAlgorithmException, + InvalidKeyException { + if (!isCommandResponse(message)) { + throw new IllegalArgumentException( + "This is not a response for Reserve SDR Repository command"); + } + if (!(message.getPayload() instanceof IpmiLanResponse)) { + throw new IllegalArgumentException("Invalid response payload"); + } + if (((IpmiLanResponse) message.getPayload()).getCompletionCode() != CompletionCode.Ok) { + throw new IPMIException( + ((IpmiLanResponse) message.getPayload()) + .getCompletionCode()); + } + + byte[] raw = message.getPayload().getIpmiCommandData(); + + if (raw == null || raw.length != 2) { + throw new IllegalArgumentException( + "Invalid response payload length"); + } + + ReserveSdrRepositoryResponseData responseData = new ReserveSdrRepositoryResponseData(); + + byte[] buffer = new byte[4]; + + buffer[0] = raw[0]; + buffer[1] = raw[1]; + buffer[2] = 0; + buffer[3] = 0; + + responseData + .setReservationId( + TypeConverter + .littleEndianByteArrayToInt(buffer)); + + return responseData; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/ReserveSdrRepositoryResponseData.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/ReserveSdrRepositoryResponseData.java index db82da1..8d2e3d9 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/ReserveSdrRepositoryResponseData.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/ReserveSdrRepositoryResponseData.java @@ -29,18 +29,18 @@ */ public class ReserveSdrRepositoryResponseData implements ResponseData { - /** - * This value is required in other requests, such as the 'Delete SDR' - * command. These commands will not execute unless the correct Reservation - * ID value is provided. - */ - private int reservationId; + /** + * This value is required in other requests, such as the 'Delete SDR' + * command. These commands will not execute unless the correct Reservation + * ID value is provided. + */ + private int reservationId; - public void setReservationId(int reservationId) { - this.reservationId = reservationId; - } + public void setReservationId(int reservationId) { + this.reservationId = reservationId; + } - public int getReservationId() { - return reservationId; - } + public int getReservationId() { + return reservationId; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/SensorState.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/SensorState.java index 0d3f339..cb0e708 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/SensorState.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/SensorState.java @@ -26,54 +26,62 @@ * Represents state of threshold-based sensor. */ public enum SensorState { - BelowLowerNonRecoverable(SensorState.BELOWLOWERNONRECOVERABLE), AboveUpperNonCritical( - SensorState.ABOVEUPPERNONCRITICAL), AboveUpperNonRecoverable( - SensorState.ABOVEUPPERNONRECOVERABLE), BelowLowerNonCritical( - SensorState.BELOWLOWERNONCRITICAL), BelowLowerCritical( - SensorState.BELOWLOWERCRITICAL), AboveUpperCritical( - SensorState.ABOVEUPPERCRITICAL), Ok(SensorState.OK), Invalid( - SensorState.INVALID); - private static final int BELOWLOWERNONRECOVERABLE = 4; - private static final int ABOVEUPPERNONCRITICAL = 8; - private static final int ABOVEUPPERNONRECOVERABLE = 32; - private static final int BELOWLOWERNONCRITICAL = 1; - private static final int BELOWLOWERCRITICAL = 2; - private static final int ABOVEUPPERCRITICAL = 16; - private static final int OK = 0; - private static final int INVALID = -1; + BelowLowerNonRecoverable(SensorState.BELOWLOWERNONRECOVERABLE), + AboveUpperNonCritical( + SensorState.ABOVEUPPERNONCRITICAL), + AboveUpperNonRecoverable( + SensorState.ABOVEUPPERNONRECOVERABLE), + BelowLowerNonCritical( + SensorState.BELOWLOWERNONCRITICAL), + BelowLowerCritical( + SensorState.BELOWLOWERCRITICAL), + AboveUpperCritical( + SensorState.ABOVEUPPERCRITICAL), + Ok(SensorState.OK), + Invalid( + SensorState.INVALID); - private int code; + private static final int BELOWLOWERNONRECOVERABLE = 4; + private static final int ABOVEUPPERNONCRITICAL = 8; + private static final int ABOVEUPPERNONRECOVERABLE = 32; + private static final int BELOWLOWERNONCRITICAL = 1; + private static final int BELOWLOWERCRITICAL = 2; + private static final int ABOVEUPPERCRITICAL = 16; + private static final int OK = 0; + private static final int INVALID = -1; - SensorState(int code) { - this.code = code; - } + private int code; - public int getCode() { - return code; - } + SensorState(int code) { + this.code = code; + } - public static SensorState parseInt(int value) { - if ((value & BELOWLOWERNONRECOVERABLE) != 0) { - return BelowLowerNonRecoverable; - } - if ((value & BELOWLOWERCRITICAL) != 0) { - return BelowLowerCritical; - } - if ((value & ABOVEUPPERNONCRITICAL) != 0) { - return BelowLowerNonCritical; - } - if ((value & ABOVEUPPERNONRECOVERABLE) != 0) { - return AboveUpperNonRecoverable; - } - if ((value & ABOVEUPPERCRITICAL) != 0) { - return AboveUpperCritical; - } - if ((value & ABOVEUPPERNONCRITICAL) != 0) { - return AboveUpperNonCritical; - } - if (value == OK) { - return Ok; - } - return Invalid; - } + public int getCode() { + return code; + } + + public static SensorState parseInt(int value) { + if ((value & BELOWLOWERNONRECOVERABLE) != 0) { + return BelowLowerNonRecoverable; + } + if ((value & BELOWLOWERCRITICAL) != 0) { + return BelowLowerCritical; + } + if ((value & ABOVEUPPERNONCRITICAL) != 0) { + return BelowLowerNonCritical; + } + if ((value & ABOVEUPPERNONRECOVERABLE) != 0) { + return AboveUpperNonRecoverable; + } + if ((value & ABOVEUPPERCRITICAL) != 0) { + return AboveUpperCritical; + } + if ((value & ABOVEUPPERNONCRITICAL) != 0) { + return AboveUpperNonCritical; + } + if (value == OK) { + return Ok; + } + return Invalid; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/AddressType.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/AddressType.java index dd56efa..d06a744 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/AddressType.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/AddressType.java @@ -29,47 +29,50 @@ public enum AddressType { /** * IPMB Slave Address */ - IpmbSlaveAddress(AddressType.IPMBSLAVEADDRESS), - /** - * System Software ID - */ - SystemSoftwareId(AddressType.SYSTEMSOFTWAREID), - ; - private static final int IPMBSLAVEADDRESS = 0; - private static final int SYSTEMSOFTWAREID = 1; + IpmbSlaveAddress(AddressType.IPMBSLAVEADDRESS), + /** + * System Software ID + */ + SystemSoftwareId(AddressType.SYSTEMSOFTWAREID), + ; - private int code; + private static final int IPMBSLAVEADDRESS = 0; + private static final int SYSTEMSOFTWAREID = 1; - /** - * Creates a new {@link AddressType} - * @param code address type code - */ - AddressType(int code) { - this.code = code; - } + private int code; - /** - * Get address code - * @return int value - */ - public int getCode() { - return code; - } + /** + * Creates a new {@link AddressType} + * + * @param code address type code + */ + AddressType(int code) { + this.code = code; + } - /** - * Parse the given int value and return the corresponding {@link AddressType} - * - * @param value address type value as int - * @return {@link AddressType} instance - */ - public static AddressType parseInt(int value) { - switch(value) { - case IPMBSLAVEADDRESS: - return IpmbSlaveAddress; - case SYSTEMSOFTWAREID: - return SystemSoftwareId; - default: - throw new IllegalArgumentException("Invalid value: " + value); - } - } + /** + * Get address code + * + * @return int value + */ + public int getCode() { + return code; + } + + /** + * Parse the given int value and return the corresponding {@link AddressType} + * + * @param value address type value as int + * @return {@link AddressType} instance + */ + public static AddressType parseInt(int value) { + switch (value) { + case IPMBSLAVEADDRESS: + return IpmbSlaveAddress; + case SYSTEMSOFTWAREID: + return SystemSoftwareId; + default: + throw new IllegalArgumentException("Invalid value: " + value); + } + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/BmcMessageChannelInfoRecord.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/BmcMessageChannelInfoRecord.java index 75adf8d..3bda5c0 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/BmcMessageChannelInfoRecord.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/BmcMessageChannelInfoRecord.java @@ -31,9 +31,9 @@ @Deprecated public class BmcMessageChannelInfoRecord extends SensorRecord { - @Override - protected void populateTypeSpecficValues(byte[] recordData, SensorRecord record) { - // No specific values for this record type - } + @Override + protected void populateTypeSpecficValues(byte[] recordData, SensorRecord record) { + // No specific values for this record type + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/CompactSensorRecord.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/CompactSensorRecord.java index b41ec90..a45ddbe 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/CompactSensorRecord.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/CompactSensorRecord.java @@ -29,326 +29,369 @@ */ public class CompactSensorRecord extends SensorRecord { - private byte sensorOwnerId; + private byte sensorOwnerId; - private AddressType addressType; + private AddressType addressType; - private byte channelNumber; + private byte channelNumber; - private byte sensorOwnerLun; + private byte sensorOwnerLun; - private byte sensorNumber; + private byte sensorNumber; - private EntityId entityId; + private EntityId entityId; - /** - * Entity is physical if true, logical otherwise. - */ - private boolean entityPhysical; + /** + * Entity is physical if true, logical otherwise. + */ + private boolean entityPhysical; - private byte entityInstanceNumber; + private byte entityInstanceNumber; - private boolean hysteresisReadable; + private boolean hysteresisReadable; - private boolean thresholdsReadable; + private boolean thresholdsReadable; - private SensorType sensorType; + private SensorType sensorType; - private int eventReadingType; + private int eventReadingType; - private RateUnit rateUnit; + private RateUnit rateUnit; - private ModifierUnitUsage modifierUnitUsage; + private ModifierUnitUsage modifierUnitUsage; - private SensorUnit sensorBaseUnit; + private SensorUnit sensorBaseUnit; - private SensorUnit sensorModifierUnit; + private SensorUnit sensorModifierUnit; - private SensorDirection sensorDirection; + private SensorDirection sensorDirection; - private String name; + private String name; - /** - * The instance modifier is a character(s) that software can append to the - * end of the ID String. This field selects whether the appended - * character(s) will be numeric or alpha. - */ - private InstanceModifierType idInstanceModifierType; + /** + * The instance modifier is a character(s) that software can append to the + * end of the ID String. This field selects whether the appended + * character(s) will be numeric or alpha. + */ + private InstanceModifierType idInstanceModifierType; - /** - * Sensor numbers sharing this record are sequential starting with the - * sensor number specified by the Sensor Number field for this record. - */ - private int shareCount; + /** + * Sensor numbers sharing this record are sequential starting with the + * sensor number specified by the Sensor Number field for this record. + */ + private int shareCount; - private boolean entityInstanceIncrements; + private boolean entityInstanceIncrements; - /** - * Suppose sensor ID is 'Temp' for 'Temperature Sensor', share count = 3, ID - * string instance modifier = numeric, instance modifier offset = 5 - then - * the sensors could be identified as: Temp 5, Temp 6, Temp 7
- * If the modifier = alpha, offset=0 corresponds to 'A', offset=25 - * corresponds to 'Z', and offset = 26 corresponds to 'AA', thus, for - * offset=26 the sensors could be identified as: Temp AA, Temp AB, Temp AC - */ - private int idInstanceModifierOffset; + /** + * Suppose sensor ID is 'Temp' for 'Temperature Sensor', share count = 3, ID + * string instance modifier = numeric, instance modifier offset = 5 - then + * the sensors could be identified as: Temp 5, Temp 6, Temp 7
+ * If the modifier = alpha, offset=0 corresponds to 'A', offset=25 + * corresponds to 'Z', and offset = 26 corresponds to 'AA', thus, for + * offset=26 the sensors could be identified as: Temp AA, Temp AB, Temp AC + */ + private int idInstanceModifierOffset; + + @Override + protected void populateTypeSpecficValues( + byte[] recordData, + SensorRecord record) { + setSensorOwnerId( + TypeConverter + .intToByte( + (TypeConverter + .byteToInt(recordData[5]) + & 0xfe) >> 1)); - @Override - protected void populateTypeSpecficValues(byte[] recordData, - SensorRecord record) { - setSensorOwnerId(TypeConverter.intToByte((TypeConverter - .byteToInt(recordData[5]) & 0xfe) >> 1)); + setAddressType( + AddressType + .parseInt( + TypeConverter + .byteToInt(recordData[5]) + & 0x01)); - setAddressType(AddressType.parseInt(TypeConverter - .byteToInt(recordData[5]) & 0x01)); + setChannelNumber( + TypeConverter + .intToByte( + (TypeConverter + .byteToInt(recordData[6]) + & 0xf0) >> 4)); - setChannelNumber(TypeConverter.intToByte((TypeConverter - .byteToInt(recordData[6]) & 0xf0) >> 4)); + setSensorOwnerLun( + TypeConverter + .intToByte( + TypeConverter + .byteToInt(recordData[6]) + & 0x3)); - setSensorOwnerLun(TypeConverter.intToByte(TypeConverter - .byteToInt(recordData[6]) & 0x3)); + setSensorNumber(recordData[7]); - setSensorNumber(recordData[7]); + setEntityId(EntityId.parseInt(TypeConverter.byteToInt(recordData[8]))); - setEntityId(EntityId.parseInt(TypeConverter.byteToInt(recordData[8]))); + setEntityPhysical((TypeConverter.byteToInt(recordData[9]) & 0x80) == 0); - setEntityPhysical((TypeConverter.byteToInt(recordData[9]) & 0x80) == 0); + setEntityInstanceNumber( + TypeConverter + .intToByte( + TypeConverter + .byteToInt(recordData[9]) + & 0x7f)); + + int hysteresis = (TypeConverter.byteToInt(recordData[11]) & 0x30) >> 4; + + if (hysteresis == 1 /* hysteresis readable */ + || hysteresis == 2 /* hysteresis readable & settable */) { + setHysteresisReadable(true); + } else { + setHysteresisReadable(false); + } + + int thresholds = (TypeConverter.byteToInt(recordData[11]) & 0xc) >> 2; + + if (thresholds == 1 /* thresholds readable */ + || thresholds == 2 /* thresholds readable & settable */) { + setThresholdsReadable(true); + } else { + setThresholdsReadable(false); + } + + setSensorType( + SensorType + .parseInt( + TypeConverter + .byteToInt(recordData[12]))); + + setEventReadingType(TypeConverter.byteToInt(recordData[13])); + + setRateUnit( + RateUnit + .parseInt((TypeConverter.byteToInt(recordData[20]) & 0x38) >> 3)); + + setModifierUnitUsage( + ModifierUnitUsage + .parseInt( + (TypeConverter + .byteToInt(recordData[20]) + & 0x6) >> 1)); + + setSensorBaseUnit( + SensorUnit + .parseInt( + TypeConverter + .byteToInt(recordData[21]))); + + setSensorModifierUnit( + SensorUnit + .parseInt( + TypeConverter + .byteToInt(recordData[22]))); + + setSensorDirection( + SensorDirection + .parseInt( + (TypeConverter + .byteToInt(recordData[23]) + & 0xc0) >> 6)); + + setIdInstanceModifierType( + InstanceModifierType + .parseInt( + (TypeConverter + .byteToInt(recordData[23]) + & 0x30) >> 4)); + + setShareCount(TypeConverter.byteToInt(recordData[23]) & 0xf); + + setEntityInstanceIncrements((TypeConverter.byteToInt(recordData[24]) & 0x80) != 0); + + setIdInstanceModifierOffset(TypeConverter.byteToInt(recordData[24]) & 0x7f); + + if (recordData.length >= 32) { + byte[] nameData = new byte[recordData.length - 32]; + + System.arraycopy(recordData, 32, nameData, 0, nameData.length); + + setName(decodeName(recordData[31], nameData)); + } + } + + public byte getSensorOwnerId() { + return sensorOwnerId; + } + + public void setSensorOwnerId(byte sensorOwnerId) { + this.sensorOwnerId = sensorOwnerId; + } - setEntityInstanceNumber(TypeConverter.intToByte(TypeConverter - .byteToInt(recordData[9]) & 0x7f)); + public AddressType getAddressType() { + return addressType; + } + + public void setAddressType(AddressType addressType) { + this.addressType = addressType; + } + + public byte getChannelNumber() { + return channelNumber; + } + + public void setChannelNumber(byte channelNumber) { + this.channelNumber = channelNumber; + } + + public byte getSensorOwnerLun() { + return sensorOwnerLun; + } + + public void setSensorOwnerLun(byte sensorOwnerLun) { + this.sensorOwnerLun = sensorOwnerLun; + } + + public byte getSensorNumber() { + return sensorNumber; + } + + public void setSensorNumber(byte sensorNumber) { + this.sensorNumber = sensorNumber; + } - int hysteresis = (TypeConverter.byteToInt(recordData[11]) & 0x30) >> 4; + public EntityId getEntityId() { + return entityId; + } + + public void setEntityId(EntityId entityId) { + this.entityId = entityId; + } + + public boolean isEntityPhysical() { + return entityPhysical; + } + + public void setEntityPhysical(boolean entityPhysical) { + this.entityPhysical = entityPhysical; + } + + public byte getEntityInstanceNumber() { + return entityInstanceNumber; + } + + public void setEntityInstanceNumber(byte entityInstanceNumber) { + this.entityInstanceNumber = entityInstanceNumber; + } - if (hysteresis == 1 /* hysteresis readable */ - || hysteresis == 2 /* hysteresis readable & settable */) { - setHysteresisReadable(true); - } else { - setHysteresisReadable(false); - } + public boolean isHysteresisReadable() { + return hysteresisReadable; + } - int thresholds = (TypeConverter.byteToInt(recordData[11]) & 0xc) >> 2; + public void setHysteresisReadable(boolean hysteresisReadable) { + this.hysteresisReadable = hysteresisReadable; + } - if (thresholds == 1 /* thresholds readable */ - || thresholds == 2 /* thresholds readable & settable */) { - setThresholdsReadable(true); - } else { - setThresholdsReadable(false); - } + public boolean isThresholdsReadable() { + return thresholdsReadable; + } - setSensorType(SensorType.parseInt(TypeConverter - .byteToInt(recordData[12]))); + public void setThresholdsReadable(boolean thresholdsReadable) { + this.thresholdsReadable = thresholdsReadable; + } - setEventReadingType(TypeConverter.byteToInt(recordData[13])); + public SensorType getSensorType() { + return sensorType; + } - setRateUnit(RateUnit - .parseInt((TypeConverter.byteToInt(recordData[20]) & 0x38) >> 3)); + public void setSensorType(SensorType sensorType) { + this.sensorType = sensorType; + } - setModifierUnitUsage(ModifierUnitUsage.parseInt((TypeConverter - .byteToInt(recordData[20]) & 0x6) >> 1)); + public int getEventReadingType() { + return eventReadingType; + } - setSensorBaseUnit(SensorUnit.parseInt(TypeConverter - .byteToInt(recordData[21]))); + public void setEventReadingType(int eventReadingType) { + this.eventReadingType = eventReadingType; + } - setSensorModifierUnit(SensorUnit.parseInt(TypeConverter - .byteToInt(recordData[22]))); + public RateUnit getRateUnit() { + return rateUnit; + } - setSensorDirection(SensorDirection.parseInt((TypeConverter - .byteToInt(recordData[23]) & 0xc0) >> 6)); + public void setRateUnit(RateUnit rateUnit) { + this.rateUnit = rateUnit; + } - setIdInstanceModifierType(InstanceModifierType.parseInt((TypeConverter - .byteToInt(recordData[23]) & 0x30) >> 4)); + public ModifierUnitUsage getModifierUnitUsage() { + return modifierUnitUsage; + } - setShareCount(TypeConverter.byteToInt(recordData[23]) & 0xf); + public void setModifierUnitUsage(ModifierUnitUsage modifierUnitUsage) { + this.modifierUnitUsage = modifierUnitUsage; + } - setEntityInstanceIncrements((TypeConverter.byteToInt(recordData[24]) & 0x80) != 0); + public SensorUnit getSensorBaseUnit() { + return sensorBaseUnit; + } - setIdInstanceModifierOffset(TypeConverter.byteToInt(recordData[24]) & 0x7f); + public void setSensorBaseUnit(SensorUnit sensorBaseUnit) { + this.sensorBaseUnit = sensorBaseUnit; + } - if (recordData.length >= 32) { - byte[] nameData = new byte[recordData.length - 32]; + public SensorUnit getSensorModifierUnit() { + return sensorModifierUnit; + } - System.arraycopy(recordData, 32, nameData, 0, nameData.length); + public void setSensorModifierUnit(SensorUnit sensorModifierUnit) { + this.sensorModifierUnit = sensorModifierUnit; + } - setName(decodeName(recordData[31], nameData)); - } - } + public SensorDirection getSensorDirection() { + return sensorDirection; + } - public byte getSensorOwnerId() { - return sensorOwnerId; - } + public void setSensorDirection(SensorDirection sensorDirection) { + this.sensorDirection = sensorDirection; + } - public void setSensorOwnerId(byte sensorOwnerId) { - this.sensorOwnerId = sensorOwnerId; - } + public InstanceModifierType getIdInstanceModifierType() { + return idInstanceModifierType; + } - public AddressType getAddressType() { - return addressType; - } + public void setIdInstanceModifierType( + InstanceModifierType idInstanceModifierType) { + this.idInstanceModifierType = idInstanceModifierType; + } - public void setAddressType(AddressType addressType) { - this.addressType = addressType; - } + public int getShareCount() { + return shareCount; + } - public byte getChannelNumber() { - return channelNumber; - } + public void setShareCount(int shareCount) { + this.shareCount = shareCount; + } - public void setChannelNumber(byte channelNumber) { - this.channelNumber = channelNumber; - } + public boolean isEntityInstanceIncrements() { + return entityInstanceIncrements; + } - public byte getSensorOwnerLun() { - return sensorOwnerLun; - } + public void setEntityInstanceIncrements(boolean entityInstanceIncrements) { + this.entityInstanceIncrements = entityInstanceIncrements; + } - public void setSensorOwnerLun(byte sensorOwnerLun) { - this.sensorOwnerLun = sensorOwnerLun; - } + public int getIdInstanceModifierOffset() { + return idInstanceModifierOffset; + } - public byte getSensorNumber() { - return sensorNumber; - } + public void setIdInstanceModifierOffset(int idInstanceModifierOffset) { + this.idInstanceModifierOffset = idInstanceModifierOffset; + } - public void setSensorNumber(byte sensorNumber) { - this.sensorNumber = sensorNumber; - } + public void setName(String name) { + this.name = name; + } - public EntityId getEntityId() { - return entityId; - } + public String getName() { + return name; + } - public void setEntityId(EntityId entityId) { - this.entityId = entityId; - } - - public boolean isEntityPhysical() { - return entityPhysical; - } - - public void setEntityPhysical(boolean entityPhysical) { - this.entityPhysical = entityPhysical; - } - - public byte getEntityInstanceNumber() { - return entityInstanceNumber; - } - - public void setEntityInstanceNumber(byte entityInstanceNumber) { - this.entityInstanceNumber = entityInstanceNumber; - } - - public boolean isHysteresisReadable() { - return hysteresisReadable; - } - - public void setHysteresisReadable(boolean hysteresisReadable) { - this.hysteresisReadable = hysteresisReadable; - } - - public boolean isThresholdsReadable() { - return thresholdsReadable; - } - - public void setThresholdsReadable(boolean thresholdsReadable) { - this.thresholdsReadable = thresholdsReadable; - } - - public SensorType getSensorType() { - return sensorType; - } - - public void setSensorType(SensorType sensorType) { - this.sensorType = sensorType; - } - - public int getEventReadingType() { - return eventReadingType; - } - - public void setEventReadingType(int eventReadingType) { - this.eventReadingType = eventReadingType; - } - - public RateUnit getRateUnit() { - return rateUnit; - } - - public void setRateUnit(RateUnit rateUnit) { - this.rateUnit = rateUnit; - } - - public ModifierUnitUsage getModifierUnitUsage() { - return modifierUnitUsage; - } - - public void setModifierUnitUsage(ModifierUnitUsage modifierUnitUsage) { - this.modifierUnitUsage = modifierUnitUsage; - } - - public SensorUnit getSensorBaseUnit() { - return sensorBaseUnit; - } - - public void setSensorBaseUnit(SensorUnit sensorBaseUnit) { - this.sensorBaseUnit = sensorBaseUnit; - } - - public SensorUnit getSensorModifierUnit() { - return sensorModifierUnit; - } - - public void setSensorModifierUnit(SensorUnit sensorModifierUnit) { - this.sensorModifierUnit = sensorModifierUnit; - } - - public SensorDirection getSensorDirection() { - return sensorDirection; - } - - public void setSensorDirection(SensorDirection sensorDirection) { - this.sensorDirection = sensorDirection; - } - - public InstanceModifierType getIdInstanceModifierType() { - return idInstanceModifierType; - } - - public void setIdInstanceModifierType( - InstanceModifierType idInstanceModifierType) { - this.idInstanceModifierType = idInstanceModifierType; - } - - public int getShareCount() { - return shareCount; - } - - public void setShareCount(int shareCount) { - this.shareCount = shareCount; - } - - public boolean isEntityInstanceIncrements() { - return entityInstanceIncrements; - } - - public void setEntityInstanceIncrements(boolean entityInstanceIncrements) { - this.entityInstanceIncrements = entityInstanceIncrements; - } - - public int getIdInstanceModifierOffset() { - return idInstanceModifierOffset; - } - - public void setIdInstanceModifierOffset(int idInstanceModifierOffset) { - this.idInstanceModifierOffset = idInstanceModifierOffset; - } - - public void setName(String name) { - this.name = name; - } - - public String getName() { - return name; - } - - // TODO: Generate multiple records from instance modifiers (?) + // TODO: Generate multiple records from instance modifiers (?) } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/DeviceRelativeEntityAssiciationRecord.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/DeviceRelativeEntityAssiciationRecord.java index 44a51c3..c190c04 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/DeviceRelativeEntityAssiciationRecord.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/DeviceRelativeEntityAssiciationRecord.java @@ -31,297 +31,298 @@ */ public class DeviceRelativeEntityAssiciationRecord extends SensorRecord { - private int containerEntityId; + private int containerEntityId; - private int containerEntityInstance; + private int containerEntityInstance; - private int containerEntityDeviceAddress; + private int containerEntityDeviceAddress; - private int containerEntityDeviceChannel; + private int containerEntityDeviceChannel; - /** - * false - contained entities specified as list
- * true - contained entities specified as range - */ - private boolean entitiesAsRange; + /** + * false - contained entities specified as list
+ * true - contained entities specified as range + */ + private boolean entitiesAsRange; - private boolean recordLink; + private boolean recordLink; - private int entityDeviceAddress1; + private int entityDeviceAddress1; - private int entityDeviceChannel1; + private int entityDeviceChannel1; - /** - * If list: Entity ID for contained entity 1
- * If range: Entity ID of entity for contained entity range 1 - */ - private int entityRange1; + /** + * If list: Entity ID for contained entity 1
+ * If range: Entity ID of entity for contained entity range 1 + */ + private int entityRange1; - /** - * If list: Instance ID for contained entity 1
- * If range: Instance ID for first entity in contained entity range 1 - */ - private int entityRangeInstance1; + /** + * If list: Instance ID for contained entity 1
+ * If range: Instance ID for first entity in contained entity range 1 + */ + private int entityRangeInstance1; - private int entityDeviceAddress2; + private int entityDeviceAddress2; - private int entityDeviceChannel2; + private int entityDeviceChannel2; - /** - * If list: Entity ID for contained entity 2
- * If range: Entity ID of entity for contained entity range 2 - */ - private int entityRange2; + /** + * If list: Entity ID for contained entity 2
+ * If range: Entity ID of entity for contained entity range 2 + */ + private int entityRange2; - /** - * If list: Instance ID for contained entity 2
- * If range: Instance ID for first entity in contained entity range 2 - */ - private int entityRangeInstance2; + /** + * If list: Instance ID for contained entity 2
+ * If range: Instance ID for first entity in contained entity range 2 + */ + private int entityRangeInstance2; - private int entityDeviceAddress3; + private int entityDeviceAddress3; - private int entityDeviceChannel3; + private int entityDeviceChannel3; - /** - * If list: Entity ID for contained entity 3
- * If range: Entity ID of entity for contained entity range 3 - */ - private int entityRange3; + /** + * If list: Entity ID for contained entity 3
+ * If range: Entity ID of entity for contained entity range 3 + */ + private int entityRange3; - /** - * If list: Instance ID for contained entity 3
- * If range: Instance ID for first entity in contained entity range 3 - */ - private int entityRangeInstance3; + /** + * If list: Instance ID for contained entity 3
+ * If range: Instance ID for first entity in contained entity range 3 + */ + private int entityRangeInstance3; - private int entityDeviceAddress4; + private int entityDeviceAddress4; - private int entityDeviceChannel4; + private int entityDeviceChannel4; - /** - * If list: Entity ID for contained entity 4
- * If range: Entity ID of entity for contained entity range 4 - */ - private int entityRange4; + /** + * If list: Entity ID for contained entity 4
+ * If range: Entity ID of entity for contained entity range 4 + */ + private int entityRange4; - /** - * If list: Instance ID for contained entity 4
- * If range: Instance ID for first entity in contained entity range 4 - */ - private int entityRangeInstance4; + /** + * If list: Instance ID for contained entity 4
+ * If range: Instance ID for first entity in contained entity range 4 + */ + private int entityRangeInstance4; - @Override - protected void populateTypeSpecficValues(byte[] recordData, - SensorRecord record) { + @Override + protected void populateTypeSpecficValues( + byte[] recordData, + SensorRecord record) { - setContainerEntityId(TypeConverter.byteToInt(recordData[5])); + setContainerEntityId(TypeConverter.byteToInt(recordData[5])); - setContainerEntityInstance(TypeConverter.byteToInt(recordData[6])); + setContainerEntityInstance(TypeConverter.byteToInt(recordData[6])); - setContainerEntityDeviceAddress(TypeConverter.byteToInt(recordData[7])); + setContainerEntityDeviceAddress(TypeConverter.byteToInt(recordData[7])); - setContainerEntityDeviceChannel(TypeConverter.byteToInt(recordData[8])); + setContainerEntityDeviceChannel(TypeConverter.byteToInt(recordData[8])); - setEntitiesAsRange((TypeConverter.byteToInt(recordData[9]) & 0x80) != 0); + setEntitiesAsRange((TypeConverter.byteToInt(recordData[9]) & 0x80) != 0); - setRecordLink((TypeConverter.byteToInt(recordData[9]) & 0x40) != 0); + setRecordLink((TypeConverter.byteToInt(recordData[9]) & 0x40) != 0); - setEntityDeviceAddress1(TypeConverter.byteToInt(recordData[10])); - setEntityDeviceChannel1(TypeConverter.byteToInt(recordData[11])); - setEntityRange1(TypeConverter.byteToInt(recordData[12])); - setEntityRangeInstance1(TypeConverter.byteToInt(recordData[13])); + setEntityDeviceAddress1(TypeConverter.byteToInt(recordData[10])); + setEntityDeviceChannel1(TypeConverter.byteToInt(recordData[11])); + setEntityRange1(TypeConverter.byteToInt(recordData[12])); + setEntityRangeInstance1(TypeConverter.byteToInt(recordData[13])); - setEntityDeviceAddress2(TypeConverter.byteToInt(recordData[14])); - setEntityDeviceChannel2(TypeConverter.byteToInt(recordData[15])); - setEntityRange2(TypeConverter.byteToInt(recordData[16])); - setEntityRangeInstance2(TypeConverter.byteToInt(recordData[17])); + setEntityDeviceAddress2(TypeConverter.byteToInt(recordData[14])); + setEntityDeviceChannel2(TypeConverter.byteToInt(recordData[15])); + setEntityRange2(TypeConverter.byteToInt(recordData[16])); + setEntityRangeInstance2(TypeConverter.byteToInt(recordData[17])); - setEntityDeviceAddress3(TypeConverter.byteToInt(recordData[18])); - setEntityDeviceChannel3(TypeConverter.byteToInt(recordData[19])); - setEntityRange3(TypeConverter.byteToInt(recordData[20])); - setEntityRangeInstance3(TypeConverter.byteToInt(recordData[21])); + setEntityDeviceAddress3(TypeConverter.byteToInt(recordData[18])); + setEntityDeviceChannel3(TypeConverter.byteToInt(recordData[19])); + setEntityRange3(TypeConverter.byteToInt(recordData[20])); + setEntityRangeInstance3(TypeConverter.byteToInt(recordData[21])); - setEntityDeviceAddress4(TypeConverter.byteToInt(recordData[22])); - setEntityDeviceChannel4(TypeConverter.byteToInt(recordData[23])); - setEntityRange4(TypeConverter.byteToInt(recordData[24])); - setEntityRangeInstance4(TypeConverter.byteToInt(recordData[25])); - } + setEntityDeviceAddress4(TypeConverter.byteToInt(recordData[22])); + setEntityDeviceChannel4(TypeConverter.byteToInt(recordData[23])); + setEntityRange4(TypeConverter.byteToInt(recordData[24])); + setEntityRangeInstance4(TypeConverter.byteToInt(recordData[25])); + } - public int getContainerEntityId() { - return containerEntityId; - } + public int getContainerEntityId() { + return containerEntityId; + } - public void setContainerEntityId(int containerEntityId) { - this.containerEntityId = containerEntityId; - } + public void setContainerEntityId(int containerEntityId) { + this.containerEntityId = containerEntityId; + } - public int getContainerEntityInstance() { - return containerEntityInstance; - } + public int getContainerEntityInstance() { + return containerEntityInstance; + } - public void setContainerEntityInstance(int containerEntityInstance) { - this.containerEntityInstance = containerEntityInstance; - } + public void setContainerEntityInstance(int containerEntityInstance) { + this.containerEntityInstance = containerEntityInstance; + } - public int getContainerEntityDeviceAddress() { - return containerEntityDeviceAddress; - } + public int getContainerEntityDeviceAddress() { + return containerEntityDeviceAddress; + } - public void setContainerEntityDeviceAddress(int containerEntityDeviceAddress) { - this.containerEntityDeviceAddress = containerEntityDeviceAddress; - } + public void setContainerEntityDeviceAddress(int containerEntityDeviceAddress) { + this.containerEntityDeviceAddress = containerEntityDeviceAddress; + } - public int getContainerEntityDeviceChannel() { - return containerEntityDeviceChannel; - } + public int getContainerEntityDeviceChannel() { + return containerEntityDeviceChannel; + } - public void setContainerEntityDeviceChannel(int containerEntityDeviceChannel) { - this.containerEntityDeviceChannel = containerEntityDeviceChannel; - } + public void setContainerEntityDeviceChannel(int containerEntityDeviceChannel) { + this.containerEntityDeviceChannel = containerEntityDeviceChannel; + } - public boolean isEntitiesAsRange() { - return entitiesAsRange; - } + public boolean isEntitiesAsRange() { + return entitiesAsRange; + } - public void setEntitiesAsRange(boolean entitiesAsRange) { - this.entitiesAsRange = entitiesAsRange; - } + public void setEntitiesAsRange(boolean entitiesAsRange) { + this.entitiesAsRange = entitiesAsRange; + } - public boolean isRecordLink() { - return recordLink; - } + public boolean isRecordLink() { + return recordLink; + } - public void setRecordLink(boolean recordLink) { - this.recordLink = recordLink; - } + public void setRecordLink(boolean recordLink) { + this.recordLink = recordLink; + } - public int getEntityDeviceAddress1() { - return entityDeviceAddress1; - } + public int getEntityDeviceAddress1() { + return entityDeviceAddress1; + } - public void setEntityDeviceAddress1(int entityDeviceAddress1) { - this.entityDeviceAddress1 = entityDeviceAddress1; - } + public void setEntityDeviceAddress1(int entityDeviceAddress1) { + this.entityDeviceAddress1 = entityDeviceAddress1; + } - public int getEntityDeviceChannel1() { - return entityDeviceChannel1; - } + public int getEntityDeviceChannel1() { + return entityDeviceChannel1; + } - public void setEntityDeviceChannel1(int entityDeviceChannel1) { - this.entityDeviceChannel1 = entityDeviceChannel1; - } + public void setEntityDeviceChannel1(int entityDeviceChannel1) { + this.entityDeviceChannel1 = entityDeviceChannel1; + } - public int getEntityRange1() { - return entityRange1; - } + public int getEntityRange1() { + return entityRange1; + } - public void setEntityRange1(int entityRange1) { - this.entityRange1 = entityRange1; - } + public void setEntityRange1(int entityRange1) { + this.entityRange1 = entityRange1; + } - public int getEntityRangeInstance1() { - return entityRangeInstance1; - } - - public void setEntityRangeInstance1(int entityRangeInstance1) { - this.entityRangeInstance1 = entityRangeInstance1; - } - - public int getEntityDeviceAddress2() { - return entityDeviceAddress2; - } - - public void setEntityDeviceAddress2(int entityDeviceAddress2) { - this.entityDeviceAddress2 = entityDeviceAddress2; - } - - public int getEntityDeviceChannel2() { - return entityDeviceChannel2; - } - - public void setEntityDeviceChannel2(int entityDeviceChannel2) { - this.entityDeviceChannel2 = entityDeviceChannel2; - } - - public int getEntityRange2() { - return entityRange2; - } + public int getEntityRangeInstance1() { + return entityRangeInstance1; + } + + public void setEntityRangeInstance1(int entityRangeInstance1) { + this.entityRangeInstance1 = entityRangeInstance1; + } + + public int getEntityDeviceAddress2() { + return entityDeviceAddress2; + } + + public void setEntityDeviceAddress2(int entityDeviceAddress2) { + this.entityDeviceAddress2 = entityDeviceAddress2; + } + + public int getEntityDeviceChannel2() { + return entityDeviceChannel2; + } + + public void setEntityDeviceChannel2(int entityDeviceChannel2) { + this.entityDeviceChannel2 = entityDeviceChannel2; + } + + public int getEntityRange2() { + return entityRange2; + } - public void setEntityRange2(int entityRange2) { - this.entityRange2 = entityRange2; - } + public void setEntityRange2(int entityRange2) { + this.entityRange2 = entityRange2; + } - public int getEntityRangeInstance2() { - return entityRangeInstance2; - } + public int getEntityRangeInstance2() { + return entityRangeInstance2; + } - public void setEntityRangeInstance2(int entityRangeInstance2) { - this.entityRangeInstance2 = entityRangeInstance2; - } + public void setEntityRangeInstance2(int entityRangeInstance2) { + this.entityRangeInstance2 = entityRangeInstance2; + } - public int getEntityDeviceAddress3() { - return entityDeviceAddress3; - } + public int getEntityDeviceAddress3() { + return entityDeviceAddress3; + } - public void setEntityDeviceAddress3(int entityDeviceAddress3) { - this.entityDeviceAddress3 = entityDeviceAddress3; - } + public void setEntityDeviceAddress3(int entityDeviceAddress3) { + this.entityDeviceAddress3 = entityDeviceAddress3; + } - public int getEntityDeviceChannel3() { - return entityDeviceChannel3; - } + public int getEntityDeviceChannel3() { + return entityDeviceChannel3; + } - public void setEntityDeviceChannel3(int entityDeviceChannel3) { - this.entityDeviceChannel3 = entityDeviceChannel3; - } + public void setEntityDeviceChannel3(int entityDeviceChannel3) { + this.entityDeviceChannel3 = entityDeviceChannel3; + } - public int getEntityRange3() { - return entityRange3; - } + public int getEntityRange3() { + return entityRange3; + } - public void setEntityRange3(int entityRange3) { - this.entityRange3 = entityRange3; - } + public void setEntityRange3(int entityRange3) { + this.entityRange3 = entityRange3; + } - public int getEntityRangeInstance3() { - return entityRangeInstance3; - } + public int getEntityRangeInstance3() { + return entityRangeInstance3; + } - public void setEntityRangeInstance3(int entityRangeInstance3) { - this.entityRangeInstance3 = entityRangeInstance3; - } + public void setEntityRangeInstance3(int entityRangeInstance3) { + this.entityRangeInstance3 = entityRangeInstance3; + } - public int getEntityDeviceAddress4() { - return entityDeviceAddress4; - } + public int getEntityDeviceAddress4() { + return entityDeviceAddress4; + } - public void setEntityDeviceAddress4(int entityDeviceAddress4) { - this.entityDeviceAddress4 = entityDeviceAddress4; - } + public void setEntityDeviceAddress4(int entityDeviceAddress4) { + this.entityDeviceAddress4 = entityDeviceAddress4; + } - public int getEntityDeviceChannel4() { - return entityDeviceChannel4; - } + public int getEntityDeviceChannel4() { + return entityDeviceChannel4; + } - public void setEntityDeviceChannel4(int entityDeviceChannel4) { - this.entityDeviceChannel4 = entityDeviceChannel4; - } + public void setEntityDeviceChannel4(int entityDeviceChannel4) { + this.entityDeviceChannel4 = entityDeviceChannel4; + } - public int getEntityRange4() { - return entityRange4; - } + public int getEntityRange4() { + return entityRange4; + } - public void setEntityRange4(int entityRange4) { - this.entityRange4 = entityRange4; - } + public void setEntityRange4(int entityRange4) { + this.entityRange4 = entityRange4; + } - public int getEntityRangeInstance4() { - return entityRangeInstance4; - } + public int getEntityRangeInstance4() { + return entityRangeInstance4; + } - public void setEntityRangeInstance4(int entityRangeInstance4) { - this.entityRangeInstance4 = entityRangeInstance4; - } + public void setEntityRangeInstance4(int entityRangeInstance4) { + this.entityRangeInstance4 = entityRangeInstance4; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/DeviceType.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/DeviceType.java index bc5f83e..af6e9e4 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/DeviceType.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/DeviceType.java @@ -26,151 +26,154 @@ import org.slf4j.LoggerFactory; public enum DeviceType { - Eeprom24C04(DeviceType.EEPROM24C04), - Eeprom24C08(DeviceType.EEPROM24C08), - Eeprom24C16(DeviceType.EEPROM24C16), - Eeprom24C17(DeviceType.EEPROM24C17), - Eeprom24C32(DeviceType.EEPROM24C32), - Eeprom24C64(DeviceType.EEPROM24C64), - FRUInventoryDevice(DeviceType.FRUINVENTORYDEVICE), - Other(DeviceType.OTHER), - OEMSpecifiedDevice(DeviceType.OEMSPECIFIEDDEVICE), - DS1624TemperatureSensor(DeviceType.DS1624TEMPERATURESENSOR), - PCF8570256ByteRAM(DeviceType.PCF8570256BYTERAM), - PCF8573ClockCalendar(DeviceType.PCF8573CLOCKCALENDAR), - PCF8574AIoPort(DeviceType.PCF8574AIOPORT), - PCF8583ClockCalendar(DeviceType.PCF8583CLOCKCALENDAR), - PCF8593ClockCalendar(DeviceType.PCF8593CLOCKCALENDAR), - ClockCalendar(DeviceType.CLOCKCALENDAR), - PCF8591AdDaConverter(DeviceType.PCF8591ADDACONVERTER), - IoPort(DeviceType.IOPORT), - AdConverter(DeviceType.ADCONVERTER), - DaConverter(DeviceType.DACONVERTER), - DS1621TemperatureSensor(DeviceType.DS1621TEMPERATURESENSOR), - AdDaConverter(DeviceType.ADDACONVERTER), - LCDControllerDriver(DeviceType.LCDCONTROLLERDRIVER), - CoreLogicDevice(DeviceType.CORELOGICDEVICE), - LMC6874IntelligentBatteryController(DeviceType.LMC6874INTELLIGENTBATTERYCONTROLLER), - IntelligentBatteryController(DeviceType.INTELLIGENTBATTERYCONTROLLER), - ComboManagementASIC(DeviceType.COMBOMANAGEMENTASIC), - Maxim1617TemperatureSensor(DeviceType.MAXIM1617TEMPERATURESENSOR), - LM75TemperatureSensor(DeviceType.LM75TEMPERATURESENSOR), - HecetaASIC(DeviceType.HECETAASIC), - Eeprom24C01(DeviceType.EEPROM24C01), - Eeprom24C02(DeviceType.EEPROM24C02), - ; - private static final int EEPROM24C04 = 10; - private static final int EEPROM24C08 = 11; - private static final int EEPROM24C16 = 12; - private static final int EEPROM24C17 = 13; - private static final int EEPROM24C32 = 14; - private static final int EEPROM24C64 = 15; - private static final int FRUINVENTORYDEVICE = 16; - private static final int OTHER = 191; - private static final int OEMSPECIFIEDDEVICE = 192; - private static final int DS1624TEMPERATURESENSOR = 2; - private static final int PCF8570256BYTERAM = 20; - private static final int PCF8573CLOCKCALENDAR = 21; - private static final int PCF8574AIOPORT = 22; - private static final int PCF8583CLOCKCALENDAR = 23; - private static final int PCF8593CLOCKCALENDAR = 24; - private static final int CLOCKCALENDAR = 25; - private static final int PCF8591ADDACONVERTER = 26; - private static final int IOPORT = 27; - private static final int ADCONVERTER = 28; - private static final int DACONVERTER = 29; - private static final int DS1621TEMPERATURESENSOR = 3; - private static final int ADDACONVERTER = 30; - private static final int LCDCONTROLLERDRIVER = 31; - private static final int CORELOGICDEVICE = 32; - private static final int LMC6874INTELLIGENTBATTERYCONTROLLER = 33; - private static final int INTELLIGENTBATTERYCONTROLLER = 34; - private static final int COMBOMANAGEMENTASIC = 35; - private static final int MAXIM1617TEMPERATURESENSOR = 36; - private static final int LM75TEMPERATURESENSOR = 4; - private static final int HECETAASIC = 5; - private static final int EEPROM24C01 = 8; - private static final int EEPROM24C02 = 9; + Eeprom24C04(DeviceType.EEPROM24C04), + Eeprom24C08(DeviceType.EEPROM24C08), + Eeprom24C16(DeviceType.EEPROM24C16), + Eeprom24C17(DeviceType.EEPROM24C17), + Eeprom24C32(DeviceType.EEPROM24C32), + Eeprom24C64(DeviceType.EEPROM24C64), + FRUInventoryDevice(DeviceType.FRUINVENTORYDEVICE), + Other(DeviceType.OTHER), + OEMSpecifiedDevice(DeviceType.OEMSPECIFIEDDEVICE), + DS1624TemperatureSensor(DeviceType.DS1624TEMPERATURESENSOR), + PCF8570256ByteRAM(DeviceType.PCF8570256BYTERAM), + PCF8573ClockCalendar(DeviceType.PCF8573CLOCKCALENDAR), + PCF8574AIoPort(DeviceType.PCF8574AIOPORT), + PCF8583ClockCalendar(DeviceType.PCF8583CLOCKCALENDAR), + PCF8593ClockCalendar(DeviceType.PCF8593CLOCKCALENDAR), + ClockCalendar(DeviceType.CLOCKCALENDAR), + PCF8591AdDaConverter(DeviceType.PCF8591ADDACONVERTER), + IoPort(DeviceType.IOPORT), + AdConverter(DeviceType.ADCONVERTER), + DaConverter(DeviceType.DACONVERTER), + DS1621TemperatureSensor(DeviceType.DS1621TEMPERATURESENSOR), + AdDaConverter(DeviceType.ADDACONVERTER), + LCDControllerDriver(DeviceType.LCDCONTROLLERDRIVER), + CoreLogicDevice(DeviceType.CORELOGICDEVICE), + LMC6874IntelligentBatteryController(DeviceType.LMC6874INTELLIGENTBATTERYCONTROLLER), + IntelligentBatteryController(DeviceType.INTELLIGENTBATTERYCONTROLLER), + ComboManagementASIC(DeviceType.COMBOMANAGEMENTASIC), + Maxim1617TemperatureSensor(DeviceType.MAXIM1617TEMPERATURESENSOR), + LM75TemperatureSensor(DeviceType.LM75TEMPERATURESENSOR), + HecetaASIC(DeviceType.HECETAASIC), + Eeprom24C01(DeviceType.EEPROM24C01), + Eeprom24C02(DeviceType.EEPROM24C02), + ; - private int code; + private static final int EEPROM24C04 = 10; + private static final int EEPROM24C08 = 11; + private static final int EEPROM24C16 = 12; + private static final int EEPROM24C17 = 13; + private static final int EEPROM24C32 = 14; + private static final int EEPROM24C64 = 15; + private static final int FRUINVENTORYDEVICE = 16; + private static final int OTHER = 191; + private static final int OEMSPECIFIEDDEVICE = 192; + private static final int DS1624TEMPERATURESENSOR = 2; + private static final int PCF8570256BYTERAM = 20; + private static final int PCF8573CLOCKCALENDAR = 21; + private static final int PCF8574AIOPORT = 22; + private static final int PCF8583CLOCKCALENDAR = 23; + private static final int PCF8593CLOCKCALENDAR = 24; + private static final int CLOCKCALENDAR = 25; + private static final int PCF8591ADDACONVERTER = 26; + private static final int IOPORT = 27; + private static final int ADCONVERTER = 28; + private static final int DACONVERTER = 29; + private static final int DS1621TEMPERATURESENSOR = 3; + private static final int ADDACONVERTER = 30; + private static final int LCDCONTROLLERDRIVER = 31; + private static final int CORELOGICDEVICE = 32; + private static final int LMC6874INTELLIGENTBATTERYCONTROLLER = 33; + private static final int INTELLIGENTBATTERYCONTROLLER = 34; + private static final int COMBOMANAGEMENTASIC = 35; + private static final int MAXIM1617TEMPERATURESENSOR = 36; + private static final int LM75TEMPERATURESENSOR = 4; + private static final int HECETAASIC = 5; + private static final int EEPROM24C01 = 8; + private static final int EEPROM24C02 = 9; - private static Logger logger = LoggerFactory.getLogger(DeviceType.class); + private int code; - DeviceType(int code) { - this.code = code; - } - public int getCode() { - return code; - } - public static DeviceType parseInt(int value) { - switch(value) { - case EEPROM24C04: - return Eeprom24C04; - case EEPROM24C08: - return Eeprom24C08; - case EEPROM24C16: - return Eeprom24C16; - case EEPROM24C17: - return Eeprom24C17; - case EEPROM24C32: - return Eeprom24C32; - case EEPROM24C64: - return Eeprom24C64; - case FRUINVENTORYDEVICE: - return FRUInventoryDevice; - case OTHER: - return Other; - case OEMSPECIFIEDDEVICE: - return OEMSpecifiedDevice; - case DS1624TEMPERATURESENSOR: - return DS1624TemperatureSensor; - case PCF8570256BYTERAM: - return PCF8570256ByteRAM; - case PCF8573CLOCKCALENDAR: - return PCF8573ClockCalendar; - case PCF8574AIOPORT: - return PCF8574AIoPort; - case PCF8583CLOCKCALENDAR: - return PCF8583ClockCalendar; - case PCF8593CLOCKCALENDAR: - return PCF8593ClockCalendar; - case CLOCKCALENDAR: - return ClockCalendar; - case PCF8591ADDACONVERTER: - return PCF8591AdDaConverter; - case IOPORT: - return IoPort; - case ADCONVERTER: - return AdConverter; - case DACONVERTER: - return DaConverter; - case DS1621TEMPERATURESENSOR: - return DS1621TemperatureSensor; - case ADDACONVERTER: - return AdDaConverter; - case LCDCONTROLLERDRIVER: - return LCDControllerDriver; - case CORELOGICDEVICE: - return CoreLogicDevice; - case LMC6874INTELLIGENTBATTERYCONTROLLER: - return LMC6874IntelligentBatteryController; - case INTELLIGENTBATTERYCONTROLLER: - return IntelligentBatteryController; - case COMBOMANAGEMENTASIC: - return ComboManagementASIC; - case MAXIM1617TEMPERATURESENSOR: - return Maxim1617TemperatureSensor; - case LM75TEMPERATURESENSOR: - return LM75TemperatureSensor; - case HECETAASIC: - return HecetaASIC; - case EEPROM24C01: - return Eeprom24C01; - case EEPROM24C02: - return Eeprom24C02; - default: - logger.error("Invalid value: " + value); - return Other; - } - } + private static Logger logger = LoggerFactory.getLogger(DeviceType.class); + + DeviceType(int code) { + this.code = code; + } + + public int getCode() { + return code; + } + + public static DeviceType parseInt(int value) { + switch (value) { + case EEPROM24C04: + return Eeprom24C04; + case EEPROM24C08: + return Eeprom24C08; + case EEPROM24C16: + return Eeprom24C16; + case EEPROM24C17: + return Eeprom24C17; + case EEPROM24C32: + return Eeprom24C32; + case EEPROM24C64: + return Eeprom24C64; + case FRUINVENTORYDEVICE: + return FRUInventoryDevice; + case OTHER: + return Other; + case OEMSPECIFIEDDEVICE: + return OEMSpecifiedDevice; + case DS1624TEMPERATURESENSOR: + return DS1624TemperatureSensor; + case PCF8570256BYTERAM: + return PCF8570256ByteRAM; + case PCF8573CLOCKCALENDAR: + return PCF8573ClockCalendar; + case PCF8574AIOPORT: + return PCF8574AIoPort; + case PCF8583CLOCKCALENDAR: + return PCF8583ClockCalendar; + case PCF8593CLOCKCALENDAR: + return PCF8593ClockCalendar; + case CLOCKCALENDAR: + return ClockCalendar; + case PCF8591ADDACONVERTER: + return PCF8591AdDaConverter; + case IOPORT: + return IoPort; + case ADCONVERTER: + return AdConverter; + case DACONVERTER: + return DaConverter; + case DS1621TEMPERATURESENSOR: + return DS1621TemperatureSensor; + case ADDACONVERTER: + return AdDaConverter; + case LCDCONTROLLERDRIVER: + return LCDControllerDriver; + case CORELOGICDEVICE: + return CoreLogicDevice; + case LMC6874INTELLIGENTBATTERYCONTROLLER: + return LMC6874IntelligentBatteryController; + case INTELLIGENTBATTERYCONTROLLER: + return IntelligentBatteryController; + case COMBOMANAGEMENTASIC: + return ComboManagementASIC; + case MAXIM1617TEMPERATURESENSOR: + return Maxim1617TemperatureSensor; + case LM75TEMPERATURESENSOR: + return LM75TemperatureSensor; + case HECETAASIC: + return HecetaASIC; + case EEPROM24C01: + return Eeprom24C01; + case EEPROM24C02: + return Eeprom24C02; + default: + logger.error("Invalid value: " + value); + return Other; + } + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/EntityAssociationRecord.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/EntityAssociationRecord.java index 12f1958..62bf22b 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/EntityAssociationRecord.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/EntityAssociationRecord.java @@ -30,185 +30,186 @@ */ public class EntityAssociationRecord extends SensorRecord { - private int containerEntityId; + private int containerEntityId; - private int containerEntityInstance; - - /** - * false - contained entities specified as list
- * true - contained entities specified as range - */ - private boolean entitiesAsRange; + private int containerEntityInstance; + + /** + * false - contained entities specified as list
+ * true - contained entities specified as range + */ + private boolean entitiesAsRange; - private boolean recordLink; - - /** - * If list: Entity ID for contained entity 1
- * If range: Entity ID of entity for contained entity range 1 - */ - private int entityRange1; + private boolean recordLink; + + /** + * If list: Entity ID for contained entity 1
+ * If range: Entity ID of entity for contained entity range 1 + */ + private int entityRange1; - /** - * If list: Instance ID for contained entity 1
- * If range: Instance ID for first entity in contained entity range 1 - */ - private int entityRangeInstance1; - - /** - * If list: Entity ID for contained entity 2
- * If range: Entity ID of entity for contained entity range 2 - */ - private int entityRange2; + /** + * If list: Instance ID for contained entity 1
+ * If range: Instance ID for first entity in contained entity range 1 + */ + private int entityRangeInstance1; + + /** + * If list: Entity ID for contained entity 2
+ * If range: Entity ID of entity for contained entity range 2 + */ + private int entityRange2; - /** - * If list: Instance ID for contained entity 2
- * If range: Instance ID for first entity in contained entity range 2 - */ - private int entityRangeInstance2; - - /** - * If list: Entity ID for contained entity 3
- * If range: Entity ID of entity for contained entity range 3 - */ - private int entityRange3; + /** + * If list: Instance ID for contained entity 2
+ * If range: Instance ID for first entity in contained entity range 2 + */ + private int entityRangeInstance2; + + /** + * If list: Entity ID for contained entity 3
+ * If range: Entity ID of entity for contained entity range 3 + */ + private int entityRange3; - /** - * If list: Instance ID for contained entity 3
- * If range: Instance ID for first entity in contained entity range 3 - */ - private int entityRangeInstance3; - - /** - * If list: Entity ID for contained entity 4
- * If range: Entity ID of entity for contained entity range 4 - */ - private int entityRange4; + /** + * If list: Instance ID for contained entity 3
+ * If range: Instance ID for first entity in contained entity range 3 + */ + private int entityRangeInstance3; + + /** + * If list: Entity ID for contained entity 4
+ * If range: Entity ID of entity for contained entity range 4 + */ + private int entityRange4; - /** - * If list: Instance ID for contained entity 4
- * If range: Instance ID for first entity in contained entity range 4 - */ - private int entityRangeInstance4; - - @Override - protected void populateTypeSpecficValues(byte[] recordData, - SensorRecord record) { - - setContainerEntityId(TypeConverter.byteToInt(recordData[5])); + /** + * If list: Instance ID for contained entity 4
+ * If range: Instance ID for first entity in contained entity range 4 + */ + private int entityRangeInstance4; + + @Override + protected void populateTypeSpecficValues( + byte[] recordData, + SensorRecord record) { + + setContainerEntityId(TypeConverter.byteToInt(recordData[5])); - setContainerEntityInstance(TypeConverter.byteToInt(recordData[6])); - - setEntitiesAsRange((TypeConverter.byteToInt(recordData[7]) & 0x80) != 0); + setContainerEntityInstance(TypeConverter.byteToInt(recordData[6])); + + setEntitiesAsRange((TypeConverter.byteToInt(recordData[7]) & 0x80) != 0); - setRecordLink((TypeConverter.byteToInt(recordData[7]) & 0x40) != 0); - - setEntityRange1(TypeConverter.byteToInt(recordData[8])); - setEntityRangeInstance1(TypeConverter.byteToInt(recordData[9])); + setRecordLink((TypeConverter.byteToInt(recordData[7]) & 0x40) != 0); + + setEntityRange1(TypeConverter.byteToInt(recordData[8])); + setEntityRangeInstance1(TypeConverter.byteToInt(recordData[9])); + + setEntityRange2(TypeConverter.byteToInt(recordData[10])); + setEntityRangeInstance2(TypeConverter.byteToInt(recordData[11])); - setEntityRange2(TypeConverter.byteToInt(recordData[10])); - setEntityRangeInstance2(TypeConverter.byteToInt(recordData[11])); + setEntityRange3(TypeConverter.byteToInt(recordData[12])); + setEntityRangeInstance3(TypeConverter.byteToInt(recordData[13])); + + setEntityRange4(TypeConverter.byteToInt(recordData[14])); + setEntityRangeInstance4(TypeConverter.byteToInt(recordData[15])); + } + + public int getContainerEntityId() { + return containerEntityId; + } + + public void setContainerEntityId(int containerEntityId) { + this.containerEntityId = containerEntityId; + } + + public int getContainerEntityInstance() { + return containerEntityInstance; + } + + public void setContainerEntityInstance(int containerEntityInstance) { + this.containerEntityInstance = containerEntityInstance; + } + + public boolean isEntitiesAsRange() { + return entitiesAsRange; + } + + public void setEntitiesAsRange(boolean entitiesAsRange) { + this.entitiesAsRange = entitiesAsRange; + } + + public boolean isRecordLink() { + return recordLink; + } + + public void setRecordLink(boolean recordLink) { + this.recordLink = recordLink; + } + + public int getEntityRange1() { + return entityRange1; + } + + public void setEntityRange1(int entityRange1) { + this.entityRange1 = entityRange1; + } + + public int getEntityRangeInstance1() { + return entityRangeInstance1; + } - setEntityRange3(TypeConverter.byteToInt(recordData[12])); - setEntityRangeInstance3(TypeConverter.byteToInt(recordData[13])); - - setEntityRange4(TypeConverter.byteToInt(recordData[14])); - setEntityRangeInstance4(TypeConverter.byteToInt(recordData[15])); - } - - public int getContainerEntityId() { - return containerEntityId; - } - - public void setContainerEntityId(int containerEntityId) { - this.containerEntityId = containerEntityId; - } - - public int getContainerEntityInstance() { - return containerEntityInstance; - } - - public void setContainerEntityInstance(int containerEntityInstance) { - this.containerEntityInstance = containerEntityInstance; - } - - public boolean isEntitiesAsRange() { - return entitiesAsRange; - } - - public void setEntitiesAsRange(boolean entitiesAsRange) { - this.entitiesAsRange = entitiesAsRange; - } - - public boolean isRecordLink() { - return recordLink; - } - - public void setRecordLink(boolean recordLink) { - this.recordLink = recordLink; - } - - public int getEntityRange1() { - return entityRange1; - } - - public void setEntityRange1(int entityRange1) { - this.entityRange1 = entityRange1; - } - - public int getEntityRangeInstance1() { - return entityRangeInstance1; - } + public void setEntityRangeInstance1(int entityRangeInstance1) { + this.entityRangeInstance1 = entityRangeInstance1; + } - public void setEntityRangeInstance1(int entityRangeInstance1) { - this.entityRangeInstance1 = entityRangeInstance1; - } + public int getEntityRange2() { + return entityRange2; + } - public int getEntityRange2() { - return entityRange2; - } + public void setEntityRange2(int entityRange2) { + this.entityRange2 = entityRange2; + } - public void setEntityRange2(int entityRange2) { - this.entityRange2 = entityRange2; - } + public int getEntityRangeInstance2() { + return entityRangeInstance2; + } - public int getEntityRangeInstance2() { - return entityRangeInstance2; - } + public void setEntityRangeInstance2(int entityRangeInstance2) { + this.entityRangeInstance2 = entityRangeInstance2; + } - public void setEntityRangeInstance2(int entityRangeInstance2) { - this.entityRangeInstance2 = entityRangeInstance2; - } + public int getEntityRange3() { + return entityRange3; + } - public int getEntityRange3() { - return entityRange3; - } + public void setEntityRange3(int entityRange3) { + this.entityRange3 = entityRange3; + } - public void setEntityRange3(int entityRange3) { - this.entityRange3 = entityRange3; - } + public int getEntityRangeInstance3() { + return entityRangeInstance3; + } - public int getEntityRangeInstance3() { - return entityRangeInstance3; - } + public void setEntityRangeInstance3(int entityRangeInstance3) { + this.entityRangeInstance3 = entityRangeInstance3; + } - public void setEntityRangeInstance3(int entityRangeInstance3) { - this.entityRangeInstance3 = entityRangeInstance3; - } + public int getEntityRange4() { + return entityRange4; + } - public int getEntityRange4() { - return entityRange4; - } + public void setEntityRange4(int entityRange4) { + this.entityRange4 = entityRange4; + } - public void setEntityRange4(int entityRange4) { - this.entityRange4 = entityRange4; - } + public int getEntityRangeInstance4() { + return entityRangeInstance4; + } - public int getEntityRangeInstance4() { - return entityRangeInstance4; - } - - public void setEntityRangeInstance4(int entityRangeInstance4) { - this.entityRangeInstance4 = entityRangeInstance4; - } + public void setEntityRangeInstance4(int entityRangeInstance4) { + this.entityRangeInstance4 = entityRangeInstance4; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/EntityId.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/EntityId.java index ab1cb27..d1a19ee 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/EntityId.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/EntityId.java @@ -30,288 +30,329 @@ * device is associated with. */ public enum EntityId { - Unspecified(EntityId.UNSPECIFIED), Other(EntityId.OTHER), Unknown(EntityId.UNKNOWN), Processor(EntityId.PROCESSOR), - /** - * Disk or disk bay. - */ - Disk(EntityId.DISK), PeripheralBay(EntityId.PERIPHERALBAY), SystemManagementModule(EntityId.SYSTEMMANAGEMENTMODULE), - /** - * Main system board, may also be a processor board and/or internal - * expansion board. - */ - SystemBoard(EntityId.SYSTEMBOARD), - /** - * Board holding memory devices. - */ - MemoryModule(EntityId.MEMORYMODULE), - /** - * Holds processors, use this designation when processors are not mounted on - * system board - */ - ProcesorModule(EntityId.PROCESORMODULE), PowerSupply(EntityId.POWERSUPPLY), AddInCard(EntityId.ADDINCARD), FrontPanelBoard(EntityId.FRONTPANELBOARD), BackPanelBoard( - EntityId.BACKPANELBOARD), PowerSystemBoard(EntityId.POWERSYSTEMBOARD), DriveBackplane(EntityId.DRIVEBACKPLANE), SystemInternalExpansionBoard( - EntityId.SYSTEMINTERNALEXPANSIONBOARD), OtherSystemBoard(EntityId.OTHERSYSTEMBOARD), ProcessorBoard(EntityId.PROCESSORBOARD), - /** - * This Entity ID is typically used as a pre-defined logical entity for - * grouping power supplies and/or sensors that are associated in monitoring - * a particular logical power domain. - */ - PowerUnit(EntityId.POWERUNIT), - /** - * DC-to-DC internal converter. - */ - PowerModule(EntityId.POWERMODULE), - /** - * Power management / power distribution board - */ - PowerManagement(EntityId.POWERMANAGEMENT), ChassisBackPanelBoard(EntityId.CHASSISBACKPANELBOARD), SystemChassis(EntityId.SYSTEMCHASSIS), SubChassis( - EntityId.SUBCHASSIS), OtherChassis(EntityId.OTHERCHASSIS), DiskDriveBay(EntityId.DISKDRIVEBAY), - /** - * Duplicate of {@link #PeripheralBay} - */ - PeripheralBay2(EntityId.PERIPHERALBAY2), DeviceBay(EntityId.DEVICEBAY), Fan(EntityId.FAN), CoolingUnit(EntityId.COOLINGUNIT), CableInterconnect( - EntityId.CABLEINTERCONNECT), MemoryDevice(EntityId.MEMORYDEVICE), SystemManagementSoftware(EntityId.SYSTEMMANAGEMENTSOFTWARE), SystemFirmware( - EntityId.SYSTEMFIRMWARE), OperatingSystem(EntityId.OPERATINGSYSTEM), SystemBus(EntityId.SYSTEMBUS), - /** - * This is a logical entity for use with Entity Association records. It is - * provided to allow an Entityassociation record to define a grouping of - * entities when there is no appropriate pre-defined entity for the - * container entity. This Entity should not be used as a physical entity. - */ - Group(EntityId.GROUP), RemoteManagementCommunicationDevice(EntityId.REMOTEMANAGEMENTCOMMUNICATIONDEVICE), - /** - * This Entity ID can be used to identify the environment outside the system - * chassis. For example, a system may have a temperature sensor that - * monitors the temperature 'outside the box'. Such a temperature sensor can - * be associated with an External Environment entity. - */ - ExternalEnvironment(EntityId.EXTERNALENVIRONMENT), Battery(EntityId.BATTERY), - /** - * A blade module that contains processor, memory, and I/O connections that - * enable it to operate as a processing entity. - */ - ProcessingBlade(EntityId.PROCESSINGBLADE), - /** - * A blade module that provides the fabric or network connection for one or - * more processing blades or modules. - */ - ConnectivitySwitch(EntityId.CONNECTIVITYSWITCH), - /** - * Processor and memory together on a module. - */ - ProcessorMemoryModule(EntityId.PROCESSORMEMORYMODULE), - /** - * A module that contains the main elements of an I/O interface. - */ - IoModule(EntityId.IOMODULE), ProcessorIoModule(EntityId.PROCESSORIOMODULE), ManagementControllerFirmware(EntityId.MANAGEMENTCONTROLLERFIRMWARE), IpmiChannel( - EntityId.IPMICHANNEL), PciBus(EntityId.PCIBUS), PciExpressBus(EntityId.PCIEXPRESSBUS), ScsiBus(EntityId.SCSIBUS), - /** - * SATA/SAS bus. - */ - SataBus(EntityId.SATABUS), FrontSideBus(EntityId.FRONTSIDEBUS), RealTimeClock(EntityId.REALTIMECLOCK), AirInlet(EntityId.AIRINLET), - /** - * Duplicate of {@link #AirInlet}. - */ - AirInlet2(EntityId.AIRINLET2), - /** - * Duplicate of {@link #Processor}. - */ - Processor2(EntityId.PROCESSOR2), - /** - * Duplicate of {@link #SystemBoard}. - */ - Baseboard(EntityId.BASEBOARD); + Unspecified(EntityId.UNSPECIFIED), + Other(EntityId.OTHER), + Unknown(EntityId.UNKNOWN), + Processor(EntityId.PROCESSOR), + /** + * Disk or disk bay. + */ + Disk(EntityId.DISK), + PeripheralBay(EntityId.PERIPHERALBAY), + SystemManagementModule(EntityId.SYSTEMMANAGEMENTMODULE), + /** + * Main system board, may also be a processor board and/or internal + * expansion board. + */ + SystemBoard(EntityId.SYSTEMBOARD), + /** + * Board holding memory devices. + */ + MemoryModule(EntityId.MEMORYMODULE), + /** + * Holds processors, use this designation when processors are not mounted on + * system board + */ + ProcesorModule(EntityId.PROCESORMODULE), + PowerSupply(EntityId.POWERSUPPLY), + AddInCard(EntityId.ADDINCARD), + FrontPanelBoard(EntityId.FRONTPANELBOARD), + BackPanelBoard( + EntityId.BACKPANELBOARD), + PowerSystemBoard(EntityId.POWERSYSTEMBOARD), + DriveBackplane(EntityId.DRIVEBACKPLANE), + SystemInternalExpansionBoard( + EntityId.SYSTEMINTERNALEXPANSIONBOARD), + OtherSystemBoard(EntityId.OTHERSYSTEMBOARD), + ProcessorBoard(EntityId.PROCESSORBOARD), + /** + * This Entity ID is typically used as a pre-defined logical entity for + * grouping power supplies and/or sensors that are associated in monitoring + * a particular logical power domain. + */ + PowerUnit(EntityId.POWERUNIT), + /** + * DC-to-DC internal converter. + */ + PowerModule(EntityId.POWERMODULE), + /** + * Power management / power distribution board + */ + PowerManagement(EntityId.POWERMANAGEMENT), + ChassisBackPanelBoard(EntityId.CHASSISBACKPANELBOARD), + SystemChassis(EntityId.SYSTEMCHASSIS), + SubChassis( + EntityId.SUBCHASSIS), + OtherChassis(EntityId.OTHERCHASSIS), + DiskDriveBay(EntityId.DISKDRIVEBAY), + /** + * Duplicate of {@link #PeripheralBay} + */ + PeripheralBay2(EntityId.PERIPHERALBAY2), + DeviceBay(EntityId.DEVICEBAY), + Fan(EntityId.FAN), + CoolingUnit(EntityId.COOLINGUNIT), + CableInterconnect( + EntityId.CABLEINTERCONNECT), + MemoryDevice(EntityId.MEMORYDEVICE), + SystemManagementSoftware(EntityId.SYSTEMMANAGEMENTSOFTWARE), + SystemFirmware( + EntityId.SYSTEMFIRMWARE), + OperatingSystem(EntityId.OPERATINGSYSTEM), + SystemBus(EntityId.SYSTEMBUS), + /** + * This is a logical entity for use with Entity Association records. It is + * provided to allow an Entityassociation record to define a grouping of + * entities when there is no appropriate pre-defined entity for the + * container entity. This Entity should not be used as a physical entity. + */ + Group(EntityId.GROUP), + RemoteManagementCommunicationDevice(EntityId.REMOTEMANAGEMENTCOMMUNICATIONDEVICE), + /** + * This Entity ID can be used to identify the environment outside the system + * chassis. For example, a system may have a temperature sensor that + * monitors the temperature 'outside the box'. Such a temperature sensor can + * be associated with an External Environment entity. + */ + ExternalEnvironment(EntityId.EXTERNALENVIRONMENT), + Battery(EntityId.BATTERY), + /** + * A blade module that contains processor, memory, and I/O connections that + * enable it to operate as a processing entity. + */ + ProcessingBlade(EntityId.PROCESSINGBLADE), + /** + * A blade module that provides the fabric or network connection for one or + * more processing blades or modules. + */ + ConnectivitySwitch(EntityId.CONNECTIVITYSWITCH), + /** + * Processor and memory together on a module. + */ + ProcessorMemoryModule(EntityId.PROCESSORMEMORYMODULE), + /** + * A module that contains the main elements of an I/O interface. + */ + IoModule(EntityId.IOMODULE), + ProcessorIoModule(EntityId.PROCESSORIOMODULE), + ManagementControllerFirmware(EntityId.MANAGEMENTCONTROLLERFIRMWARE), + IpmiChannel( + EntityId.IPMICHANNEL), + PciBus(EntityId.PCIBUS), + PciExpressBus(EntityId.PCIEXPRESSBUS), + ScsiBus(EntityId.SCSIBUS), + /** + * SATA/SAS bus. + */ + SataBus(EntityId.SATABUS), + FrontSideBus(EntityId.FRONTSIDEBUS), + RealTimeClock(EntityId.REALTIMECLOCK), + AirInlet(EntityId.AIRINLET), + /** + * Duplicate of {@link #AirInlet}. + */ + AirInlet2(EntityId.AIRINLET2), + /** + * Duplicate of {@link #Processor}. + */ + Processor2(EntityId.PROCESSOR2), + /** + * Duplicate of {@link #SystemBoard}. + */ + Baseboard(EntityId.BASEBOARD); - private static final int POWERSUPPLY = 10; - private static final int ADDINCARD = 11; - private static final int FRONTPANELBOARD = 12; - private static final int BACKPANELBOARD = 13; - private static final int POWERSYSTEMBOARD = 14; - private static final int DRIVEBACKPLANE = 15; - private static final int SYSTEMINTERNALEXPANSIONBOARD = 16; - private static final int COOLINGUNIT = 30; - private static final int OTHERSYSTEMBOARD = 17; - private static final int CABLEINTERCONNECT = 31; - private static final int PROCESSORBOARD = 18; - private static final int MEMORYDEVICE = 32; - private static final int POWERUNIT = 19; - private static final int SYSTEMMANAGEMENTSOFTWARE = 33; - private static final int SYSTEMFIRMWARE = 34; - private static final int OPERATINGSYSTEM = 35; - private static final int SYSTEMBUS = 36; - private static final int SCSIBUS = 50; - private static final int GROUP = 37; - private static final int SATABUS = 51; - private static final int REMOTEMANAGEMENTCOMMUNICATIONDEVICE = 38; - private static final int FRONTSIDEBUS = 52; - private static final int EXTERNALENVIRONMENT = 39; - private static final int REALTIMECLOCK = 53; - private static final int AIRINLET = 55; - private static final int UNSPECIFIED = 0; - private static final int OTHER = 1; - private static final int UNKNOWN = 2; - private static final int PROCESSOR = 3; - private static final int DISK = 4; - private static final int PERIPHERALBAY = 5; - private static final int SYSTEMMANAGEMENTMODULE = 6; - private static final int SYSTEMBOARD = 7; - private static final int MEMORYMODULE = 8; - private static final int PROCESORMODULE = 9; - private static final int POWERMODULE = 20; - private static final int POWERMANAGEMENT = 21; - private static final int CHASSISBACKPANELBOARD = 22; - private static final int SYSTEMCHASSIS = 23; - private static final int SUBCHASSIS = 24; - private static final int OTHERCHASSIS = 25; - private static final int DISKDRIVEBAY = 26; - private static final int BATTERY = 40; - private static final int PERIPHERALBAY2 = 27; - private static final int PROCESSINGBLADE = 41; - private static final int DEVICEBAY = 28; - private static final int CONNECTIVITYSWITCH = 42; - private static final int FAN = 29; - private static final int PROCESSORMEMORYMODULE = 43; - private static final int IOMODULE = 44; - private static final int PROCESSORIOMODULE = 45; - private static final int MANAGEMENTCONTROLLERFIRMWARE = 46; - private static final int IPMICHANNEL = 47; - private static final int PCIBUS = 48; - private static final int PCIEXPRESSBUS = 49; - private static final int AIRINLET2 = 64; - private static final int PROCESSOR2 = 65; - private static final int BASEBOARD = 66; + private static final int POWERSUPPLY = 10; + private static final int ADDINCARD = 11; + private static final int FRONTPANELBOARD = 12; + private static final int BACKPANELBOARD = 13; + private static final int POWERSYSTEMBOARD = 14; + private static final int DRIVEBACKPLANE = 15; + private static final int SYSTEMINTERNALEXPANSIONBOARD = 16; + private static final int COOLINGUNIT = 30; + private static final int OTHERSYSTEMBOARD = 17; + private static final int CABLEINTERCONNECT = 31; + private static final int PROCESSORBOARD = 18; + private static final int MEMORYDEVICE = 32; + private static final int POWERUNIT = 19; + private static final int SYSTEMMANAGEMENTSOFTWARE = 33; + private static final int SYSTEMFIRMWARE = 34; + private static final int OPERATINGSYSTEM = 35; + private static final int SYSTEMBUS = 36; + private static final int SCSIBUS = 50; + private static final int GROUP = 37; + private static final int SATABUS = 51; + private static final int REMOTEMANAGEMENTCOMMUNICATIONDEVICE = 38; + private static final int FRONTSIDEBUS = 52; + private static final int EXTERNALENVIRONMENT = 39; + private static final int REALTIMECLOCK = 53; + private static final int AIRINLET = 55; + private static final int UNSPECIFIED = 0; + private static final int OTHER = 1; + private static final int UNKNOWN = 2; + private static final int PROCESSOR = 3; + private static final int DISK = 4; + private static final int PERIPHERALBAY = 5; + private static final int SYSTEMMANAGEMENTMODULE = 6; + private static final int SYSTEMBOARD = 7; + private static final int MEMORYMODULE = 8; + private static final int PROCESORMODULE = 9; + private static final int POWERMODULE = 20; + private static final int POWERMANAGEMENT = 21; + private static final int CHASSISBACKPANELBOARD = 22; + private static final int SYSTEMCHASSIS = 23; + private static final int SUBCHASSIS = 24; + private static final int OTHERCHASSIS = 25; + private static final int DISKDRIVEBAY = 26; + private static final int BATTERY = 40; + private static final int PERIPHERALBAY2 = 27; + private static final int PROCESSINGBLADE = 41; + private static final int DEVICEBAY = 28; + private static final int CONNECTIVITYSWITCH = 42; + private static final int FAN = 29; + private static final int PROCESSORMEMORYMODULE = 43; + private static final int IOMODULE = 44; + private static final int PROCESSORIOMODULE = 45; + private static final int MANAGEMENTCONTROLLERFIRMWARE = 46; + private static final int IPMICHANNEL = 47; + private static final int PCIBUS = 48; + private static final int PCIEXPRESSBUS = 49; + private static final int AIRINLET2 = 64; + private static final int PROCESSOR2 = 65; + private static final int BASEBOARD = 66; - private int code; + private int code; - private static Logger logger = LoggerFactory.getLogger(EntityId.class); + private static Logger logger = LoggerFactory.getLogger(EntityId.class); - EntityId(int code) { - this.code = code; - } - public int getCode() { - return code; - } - public static EntityId parseInt(int value) { - switch(value) { - case POWERSUPPLY: - return PowerSupply; - case ADDINCARD: - return AddInCard; - case FRONTPANELBOARD: - return FrontPanelBoard; - case BACKPANELBOARD: - return BackPanelBoard; - case POWERSYSTEMBOARD: - return PowerSystemBoard; - case DRIVEBACKPLANE: - return DriveBackplane; - case SYSTEMINTERNALEXPANSIONBOARD: - return SystemInternalExpansionBoard; - case COOLINGUNIT: - return CoolingUnit; - case OTHERSYSTEMBOARD: - return OtherSystemBoard; - case CABLEINTERCONNECT: - return CableInterconnect; - case PROCESSORBOARD: - return ProcessorBoard; - case MEMORYDEVICE: - return MemoryDevice; - case POWERUNIT: - return PowerUnit; - case SYSTEMMANAGEMENTSOFTWARE: - return SystemManagementSoftware; - case SYSTEMFIRMWARE: - return SystemFirmware; - case OPERATINGSYSTEM: - return OperatingSystem; - case SYSTEMBUS: - return SystemBus; - case SCSIBUS: - return ScsiBus; - case GROUP: - return Group; - case SATABUS: - return SataBus; - case REMOTEMANAGEMENTCOMMUNICATIONDEVICE: - return RemoteManagementCommunicationDevice; - case FRONTSIDEBUS: - return FrontSideBus; - case EXTERNALENVIRONMENT: - return ExternalEnvironment; - case REALTIMECLOCK: - return RealTimeClock; - case AIRINLET: - return AirInlet; - case UNSPECIFIED: - return Unspecified; - case OTHER: - return Other; - case UNKNOWN: - return Unknown; - case PROCESSOR: - return Processor; - case DISK: - return Disk; - case PERIPHERALBAY: - return PeripheralBay; - case SYSTEMMANAGEMENTMODULE: - return SystemManagementModule; - case SYSTEMBOARD: - return SystemBoard; - case MEMORYMODULE: - return MemoryModule; - case PROCESORMODULE: - return ProcesorModule; - case POWERMODULE: - return PowerModule; - case POWERMANAGEMENT: - return PowerManagement; - case CHASSISBACKPANELBOARD: - return ChassisBackPanelBoard; - case SYSTEMCHASSIS: - return SystemChassis; - case SUBCHASSIS: - return SubChassis; - case OTHERCHASSIS: - return OtherChassis; - case DISKDRIVEBAY: - return DiskDriveBay; - case BATTERY: - return Battery; - case PERIPHERALBAY2: - return PeripheralBay2; - case PROCESSINGBLADE: - return ProcessingBlade; - case DEVICEBAY: - return DeviceBay; - case CONNECTIVITYSWITCH: - return ConnectivitySwitch; - case FAN: - return Fan; - case PROCESSORMEMORYMODULE: - return ProcessorMemoryModule; - case IOMODULE: - return IoModule; - case PROCESSORIOMODULE: - return ProcessorIoModule; - case MANAGEMENTCONTROLLERFIRMWARE: - return ManagementControllerFirmware; - case IPMICHANNEL: - return IpmiChannel; - case PCIBUS: - return PciBus; - case PCIEXPRESSBUS: - return PciExpressBus; - case AIRINLET2: - return AirInlet2; - case PROCESSOR2: - return Processor2; - case BASEBOARD: - return Baseboard; - default: - logger.error("Invalid value: " + value); - return Other; - } - } + EntityId(int code) { + this.code = code; + } + + public int getCode() { + return code; + } + + public static EntityId parseInt(int value) { + switch (value) { + case POWERSUPPLY: + return PowerSupply; + case ADDINCARD: + return AddInCard; + case FRONTPANELBOARD: + return FrontPanelBoard; + case BACKPANELBOARD: + return BackPanelBoard; + case POWERSYSTEMBOARD: + return PowerSystemBoard; + case DRIVEBACKPLANE: + return DriveBackplane; + case SYSTEMINTERNALEXPANSIONBOARD: + return SystemInternalExpansionBoard; + case COOLINGUNIT: + return CoolingUnit; + case OTHERSYSTEMBOARD: + return OtherSystemBoard; + case CABLEINTERCONNECT: + return CableInterconnect; + case PROCESSORBOARD: + return ProcessorBoard; + case MEMORYDEVICE: + return MemoryDevice; + case POWERUNIT: + return PowerUnit; + case SYSTEMMANAGEMENTSOFTWARE: + return SystemManagementSoftware; + case SYSTEMFIRMWARE: + return SystemFirmware; + case OPERATINGSYSTEM: + return OperatingSystem; + case SYSTEMBUS: + return SystemBus; + case SCSIBUS: + return ScsiBus; + case GROUP: + return Group; + case SATABUS: + return SataBus; + case REMOTEMANAGEMENTCOMMUNICATIONDEVICE: + return RemoteManagementCommunicationDevice; + case FRONTSIDEBUS: + return FrontSideBus; + case EXTERNALENVIRONMENT: + return ExternalEnvironment; + case REALTIMECLOCK: + return RealTimeClock; + case AIRINLET: + return AirInlet; + case UNSPECIFIED: + return Unspecified; + case OTHER: + return Other; + case UNKNOWN: + return Unknown; + case PROCESSOR: + return Processor; + case DISK: + return Disk; + case PERIPHERALBAY: + return PeripheralBay; + case SYSTEMMANAGEMENTMODULE: + return SystemManagementModule; + case SYSTEMBOARD: + return SystemBoard; + case MEMORYMODULE: + return MemoryModule; + case PROCESORMODULE: + return ProcesorModule; + case POWERMODULE: + return PowerModule; + case POWERMANAGEMENT: + return PowerManagement; + case CHASSISBACKPANELBOARD: + return ChassisBackPanelBoard; + case SYSTEMCHASSIS: + return SystemChassis; + case SUBCHASSIS: + return SubChassis; + case OTHERCHASSIS: + return OtherChassis; + case DISKDRIVEBAY: + return DiskDriveBay; + case BATTERY: + return Battery; + case PERIPHERALBAY2: + return PeripheralBay2; + case PROCESSINGBLADE: + return ProcessingBlade; + case DEVICEBAY: + return DeviceBay; + case CONNECTIVITYSWITCH: + return ConnectivitySwitch; + case FAN: + return Fan; + case PROCESSORMEMORYMODULE: + return ProcessorMemoryModule; + case IOMODULE: + return IoModule; + case PROCESSORIOMODULE: + return ProcessorIoModule; + case MANAGEMENTCONTROLLERFIRMWARE: + return ManagementControllerFirmware; + case IPMICHANNEL: + return IpmiChannel; + case PCIBUS: + return PciBus; + case PCIEXPRESSBUS: + return PciExpressBus; + case AIRINLET2: + return AirInlet2; + case PROCESSOR2: + return Processor2; + case BASEBOARD: + return Baseboard; + default: + logger.error("Invalid value: " + value); + return Other; + } + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/EventOnlyRecord.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/EventOnlyRecord.java index 7c44942..8066d28 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/EventOnlyRecord.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/EventOnlyRecord.java @@ -32,268 +32,267 @@ */ public class EventOnlyRecord extends SensorRecord { - private byte sensorOwnerId; + private byte sensorOwnerId; - private AddressType addressType; + private AddressType addressType; - private byte channelNumber; + private byte channelNumber; - private byte sensorOwnerLun; + private byte sensorOwnerLun; - private byte sensorNumber; + private byte sensorNumber; - private EntityId entityId; + private EntityId entityId; + + /** + * Entity is physical if true, logical otherwise. + */ + private boolean entityPhysical; + + private byte entityInstanceNumber; + + private SensorType sensorType; + + private int eventReadingType; - /** - * Entity is physical if true, logical otherwise. - */ - private boolean entityPhysical; + private SensorDirection sensorDirection; - private byte entityInstanceNumber; + private String name; - private SensorType sensorType; + /** + * The instance modifier is a character(s) that software can append to the + * end of the ID String. This field selects whether the appended + * character(s) will be numeric or alpha. + */ + private InstanceModifierType idInstanceModifierType; - private int eventReadingType; + /** + * Sensor numbers sharing this record are sequential starting with the + * sensor number specified by the Sensor Number field for this record. + */ + private int shareCount; - private SensorDirection sensorDirection; + private boolean entityInstanceIncrements; - private String name; + /** + * Suppose sensor ID is 'Temp' for 'Temperature Sensor', share count = 3, ID + * string instance modifier = numeric, instance modifier offset = 5 - then + * the sensors could be identified as: Temp 5, Temp 6, Temp 7
+ * If the modifier = alpha, offset=0 corresponds to 'A', offset=25 + * corresponds to 'Z', and offset = 26 corresponds to 'AA', thus, for + * offset=26 the sensors could be identified as: Temp AA, Temp AB, Temp AC + */ + private int idInstanceModifierOffset; - /** - * The instance modifier is a character(s) that software can append to the - * end of the ID String. This field selects whether the appended - * character(s) will be numeric or alpha. - */ - private InstanceModifierType idInstanceModifierType; + @Override + protected void populateTypeSpecficValues( + byte[] recordData, + SensorRecord record) { - /** - * Sensor numbers sharing this record are sequential starting with the - * sensor number specified by the Sensor Number field for this record. - */ - private int shareCount; + setSensorOwnerId( + TypeConverter + .intToByte( + (TypeConverter + .byteToInt(recordData[5]) + & 0xfe) >> 1)); - private boolean entityInstanceIncrements; + setAddressType( + AddressType + .parseInt( + TypeConverter + .byteToInt(recordData[5]) + & 0x01)); - /** - * Suppose sensor ID is 'Temp' for 'Temperature Sensor', share count = 3, ID - * string instance modifier = numeric, instance modifier offset = 5 - then - * the sensors could be identified as: Temp 5, Temp 6, Temp 7
- * If the modifier = alpha, offset=0 corresponds to 'A', offset=25 - * corresponds to 'Z', and offset = 26 corresponds to 'AA', thus, for - * offset=26 the sensors could be identified as: Temp AA, Temp AB, Temp AC - */ - private int idInstanceModifierOffset; + setChannelNumber( + TypeConverter + .intToByte( + (TypeConverter + .byteToInt(recordData[6]) + & 0xf0) >> 4)); + setSensorOwnerLun( + TypeConverter + .intToByte( + TypeConverter + .byteToInt(recordData[6]) + & 0x3)); - @Override - protected void populateTypeSpecficValues(byte[] recordData, - SensorRecord record) { + setSensorNumber(recordData[7]); - setSensorOwnerId(TypeConverter.intToByte((TypeConverter - .byteToInt(recordData[5]) & 0xfe) >> 1)); + setEntityId(EntityId.parseInt(TypeConverter.byteToInt(recordData[8]))); - setAddressType(AddressType.parseInt(TypeConverter - .byteToInt(recordData[5]) & 0x01)); + setEntityPhysical((TypeConverter.byteToInt(recordData[9]) & 0x80) == 0); - setChannelNumber(TypeConverter.intToByte((TypeConverter - .byteToInt(recordData[6]) & 0xf0) >> 4)); + setEntityInstanceNumber( + TypeConverter + .intToByte( + TypeConverter + .byteToInt(recordData[9]) + & 0x7f)); - setSensorOwnerLun(TypeConverter.intToByte(TypeConverter - .byteToInt(recordData[6]) & 0x3)); + setSensorType( + SensorType + .parseInt( + TypeConverter + .byteToInt(recordData[10]))); - setSensorNumber(recordData[7]); + setEventReadingType(TypeConverter.byteToInt(recordData[11])); - setEntityId(EntityId.parseInt(TypeConverter.byteToInt(recordData[8]))); + setSensorDirection( + SensorDirection + .parseInt( + (TypeConverter + .byteToInt(recordData[12]) + & 0xc0) >> 6)); + + setIdInstanceModifierType( + InstanceModifierType + .parseInt( + (TypeConverter + .byteToInt(recordData[12]) + & 0x30) >> 4)); + + setShareCount(TypeConverter.byteToInt(recordData[12]) & 0xf); + + setEntityInstanceIncrements((TypeConverter.byteToInt(recordData[13]) & 0x80) != 0); + + setIdInstanceModifierOffset(TypeConverter.byteToInt(recordData[13]) & 0x7f); + + byte[] nameData = new byte[recordData.length - 17]; + + System.arraycopy(recordData, 17, nameData, 0, nameData.length); + + setName(decodeName(recordData[16], nameData)); + + } + + public byte getSensorOwnerId() { + return sensorOwnerId; + } + + public void setSensorOwnerId(byte sensorOwnerId) { + this.sensorOwnerId = sensorOwnerId; + } + + public AddressType getAddressType() { + return addressType; + } + + public void setAddressType(AddressType addressType) { + this.addressType = addressType; + } + + public byte getChannelNumber() { + return channelNumber; + } + + public void setChannelNumber(byte channelNumber) { + this.channelNumber = channelNumber; + } + + public byte getSensorOwnerLun() { + return sensorOwnerLun; + } - setEntityPhysical((TypeConverter.byteToInt(recordData[9]) & 0x80) == 0); + public void setSensorOwnerLun(byte sensorOwnerLun) { + this.sensorOwnerLun = sensorOwnerLun; + } - setEntityInstanceNumber(TypeConverter.intToByte(TypeConverter - .byteToInt(recordData[9]) & 0x7f)); + public byte getSensorNumber() { + return sensorNumber; + } - setSensorType(SensorType.parseInt(TypeConverter - .byteToInt(recordData[10]))); + public void setSensorNumber(byte sensorNumber) { + this.sensorNumber = sensorNumber; + } - setEventReadingType(TypeConverter.byteToInt(recordData[11])); + public EntityId getEntityId() { + return entityId; + } - setSensorDirection(SensorDirection.parseInt((TypeConverter - .byteToInt(recordData[12]) & 0xc0) >> 6)); + public void setEntityId(EntityId entityId) { + this.entityId = entityId; + } - setIdInstanceModifierType(InstanceModifierType.parseInt((TypeConverter - .byteToInt(recordData[12]) & 0x30) >> 4)); + public boolean isEntityPhysical() { + return entityPhysical; + } - setShareCount(TypeConverter.byteToInt(recordData[12]) & 0xf); + public void setEntityPhysical(boolean entityPhysical) { + this.entityPhysical = entityPhysical; + } - setEntityInstanceIncrements((TypeConverter.byteToInt(recordData[13]) & 0x80) != 0); + public byte getEntityInstanceNumber() { + return entityInstanceNumber; + } - setIdInstanceModifierOffset(TypeConverter.byteToInt(recordData[13]) & 0x7f); + public void setEntityInstanceNumber(byte entityInstanceNumber) { + this.entityInstanceNumber = entityInstanceNumber; + } - byte[] nameData = new byte[recordData.length - 17]; + public SensorType getSensorType() { + return sensorType; + } - System.arraycopy(recordData, 17, nameData, 0, nameData.length); + public void setSensorType(SensorType sensorType) { + this.sensorType = sensorType; + } - setName(decodeName(recordData[16], nameData)); + public int getEventReadingType() { + return eventReadingType; + } - } + public void setEventReadingType(int eventReadingType) { + this.eventReadingType = eventReadingType; + } + public SensorDirection getSensorDirection() { + return sensorDirection; + } - public byte getSensorOwnerId() { - return sensorOwnerId; - } + public void setSensorDirection(SensorDirection sensorDirection) { + this.sensorDirection = sensorDirection; + } + public String getName() { + return name; + } - public void setSensorOwnerId(byte sensorOwnerId) { - this.sensorOwnerId = sensorOwnerId; - } + public void setName(String name) { + this.name = name; + } + public InstanceModifierType getIdInstanceModifierType() { + return idInstanceModifierType; + } - public AddressType getAddressType() { - return addressType; - } - - - public void setAddressType(AddressType addressType) { - this.addressType = addressType; - } - - - public byte getChannelNumber() { - return channelNumber; - } - - - public void setChannelNumber(byte channelNumber) { - this.channelNumber = channelNumber; - } - - - public byte getSensorOwnerLun() { - return sensorOwnerLun; - } - - - public void setSensorOwnerLun(byte sensorOwnerLun) { - this.sensorOwnerLun = sensorOwnerLun; - } - - - public byte getSensorNumber() { - return sensorNumber; - } - - - public void setSensorNumber(byte sensorNumber) { - this.sensorNumber = sensorNumber; - } - - - public EntityId getEntityId() { - return entityId; - } - - - public void setEntityId(EntityId entityId) { - this.entityId = entityId; - } - - - public boolean isEntityPhysical() { - return entityPhysical; - } - - - public void setEntityPhysical(boolean entityPhysical) { - this.entityPhysical = entityPhysical; - } - - - public byte getEntityInstanceNumber() { - return entityInstanceNumber; - } - - - public void setEntityInstanceNumber(byte entityInstanceNumber) { - this.entityInstanceNumber = entityInstanceNumber; - } - - - public SensorType getSensorType() { - return sensorType; - } - - - public void setSensorType(SensorType sensorType) { - this.sensorType = sensorType; - } - - - public int getEventReadingType() { - return eventReadingType; - } - - - public void setEventReadingType(int eventReadingType) { - this.eventReadingType = eventReadingType; - } - - - public SensorDirection getSensorDirection() { - return sensorDirection; - } - - - public void setSensorDirection(SensorDirection sensorDirection) { - this.sensorDirection = sensorDirection; - } - - - public String getName() { - return name; - } - - - public void setName(String name) { - this.name = name; - } - - - public InstanceModifierType getIdInstanceModifierType() { - return idInstanceModifierType; - } - - - public void setIdInstanceModifierType( - InstanceModifierType idInstanceModifierType) { - this.idInstanceModifierType = idInstanceModifierType; - } - - - public int getShareCount() { - return shareCount; - } - - - public void setShareCount(int shareCount) { - this.shareCount = shareCount; - } - - - public boolean isEntityInstanceIncrements() { - return entityInstanceIncrements; - } - - - public void setEntityInstanceIncrements(boolean entityInstanceIncrements) { - this.entityInstanceIncrements = entityInstanceIncrements; - } - - - public int getIdInstanceModifierOffset() { - return idInstanceModifierOffset; - } - - - public void setIdInstanceModifierOffset(int idInstanceModifierOffset) { - this.idInstanceModifierOffset = idInstanceModifierOffset; - } + public void setIdInstanceModifierType( + InstanceModifierType idInstanceModifierType) { + this.idInstanceModifierType = idInstanceModifierType; + } + + public int getShareCount() { + return shareCount; + } + + public void setShareCount(int shareCount) { + this.shareCount = shareCount; + } + + public boolean isEntityInstanceIncrements() { + return entityInstanceIncrements; + } + + public void setEntityInstanceIncrements(boolean entityInstanceIncrements) { + this.entityInstanceIncrements = entityInstanceIncrements; + } + + public int getIdInstanceModifierOffset() { + return idInstanceModifierOffset; + } + + public void setIdInstanceModifierOffset(int idInstanceModifierOffset) { + this.idInstanceModifierOffset = idInstanceModifierOffset; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/FruDeviceLocatorRecord.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/FruDeviceLocatorRecord.java index 3d80c99..0cd58ac 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/FruDeviceLocatorRecord.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/FruDeviceLocatorRecord.java @@ -31,152 +31,155 @@ */ public class FruDeviceLocatorRecord extends SensorRecord { - private int deviceAccessAddress; + private int deviceAccessAddress; - private int deviceId; + private int deviceId; - /** - * false - device is not a logical FRU Device
- * true - device is logical FRU Device (accessed via FRU commands to mgmt. - * controller) - */ - private boolean logical; + /** + * false - device is not a logical FRU Device
+ * true - device is logical FRU Device (accessed via FRU commands to mgmt. + * controller) + */ + private boolean logical; - private int accessLun; + private int accessLun; - private int managementChannelNumber; + private int managementChannelNumber; - private DeviceType deviceType; + private DeviceType deviceType; - private int deviceTypeModifier; + private int deviceTypeModifier; - private int fruEntityId; + private int fruEntityId; - private int fruEntityInstance; + private int fruEntityInstance; - private String name; + private String name; - @Override - protected void populateTypeSpecficValues(byte[] recordData, SensorRecord record) { + @Override + protected void populateTypeSpecficValues(byte[] recordData, SensorRecord record) { - setDeviceAccessAddress((TypeConverter.byteToInt(recordData[5]) & 0xfe) >> 1); + setDeviceAccessAddress((TypeConverter.byteToInt(recordData[5]) & 0xfe) >> 1); - setLogical((TypeConverter.byteToInt(recordData[7]) & 0x80) != 0); + setLogical((TypeConverter.byteToInt(recordData[7]) & 0x80) != 0); - int deviceIdFromRecord = TypeConverter.byteToInt(recordData[6]); + int deviceIdFromRecord = TypeConverter.byteToInt(recordData[6]); - if (!isLogical()) { - deviceIdFromRecord &= 0xfe; - deviceIdFromRecord >>= 1; - } + if (!isLogical()) { + deviceIdFromRecord &= 0xfe; + deviceIdFromRecord >>= 1; + } - setDeviceId(deviceIdFromRecord); - int id = TypeConverter.byteToInt(recordData[6]); + setDeviceId(deviceIdFromRecord); + int id = TypeConverter.byteToInt(recordData[6]); - if (!isLogical()) { - id >>= 1; - } + if (!isLogical()) { + id >>= 1; + } - setId(id); + setId(id); - setAccessLun((TypeConverter.byteToInt(recordData[7]) & 0xc) >> 2); + setAccessLun((TypeConverter.byteToInt(recordData[7]) & 0xc) >> 2); - setManagementChannelNumber((TypeConverter.byteToInt(recordData[8]) & 0xf0) >> 4); + setManagementChannelNumber((TypeConverter.byteToInt(recordData[8]) & 0xf0) >> 4); - setDeviceType(DeviceType.parseInt(TypeConverter - .byteToInt(recordData[10]))); + setDeviceType( + DeviceType + .parseInt( + TypeConverter + .byteToInt(recordData[10]))); - setDeviceTypeModifier(TypeConverter.byteToInt(recordData[11])); + setDeviceTypeModifier(TypeConverter.byteToInt(recordData[11])); - setFruEntityId(TypeConverter.byteToInt(recordData[12])); + setFruEntityId(TypeConverter.byteToInt(recordData[12])); - setFruEntityInstance(TypeConverter.byteToInt(recordData[13])); + setFruEntityInstance(TypeConverter.byteToInt(recordData[13])); - byte[] nameData = new byte[recordData.length - 16]; + byte[] nameData = new byte[recordData.length - 16]; - System.arraycopy(recordData, 16, nameData, 0, nameData.length); + System.arraycopy(recordData, 16, nameData, 0, nameData.length); - setName(decodeName(recordData[15], nameData)); - } + setName(decodeName(recordData[15], nameData)); + } - public int getDeviceAccessAddress() { - return deviceAccessAddress; - } + public int getDeviceAccessAddress() { + return deviceAccessAddress; + } - public void setDeviceAccessAddress(int deviceAccessAddress) { - this.deviceAccessAddress = deviceAccessAddress; - } + public void setDeviceAccessAddress(int deviceAccessAddress) { + this.deviceAccessAddress = deviceAccessAddress; + } - public int getDeviceId() { - return deviceId; - } + public int getDeviceId() { + return deviceId; + } - public void setDeviceId(int deviceId) { - this.deviceId = deviceId; - } + public void setDeviceId(int deviceId) { + this.deviceId = deviceId; + } - public boolean isLogical() { - return logical; - } + public boolean isLogical() { + return logical; + } - public void setLogical(boolean logical) { - this.logical = logical; - } + public void setLogical(boolean logical) { + this.logical = logical; + } - public int getAccessLun() { - return accessLun; - } + public int getAccessLun() { + return accessLun; + } - public void setAccessLun(int accessLun) { - this.accessLun = accessLun; - } + public void setAccessLun(int accessLun) { + this.accessLun = accessLun; + } - public int getManagementChannelNumber() { - return managementChannelNumber; - } + public int getManagementChannelNumber() { + return managementChannelNumber; + } - public void setManagementChannelNumber(int managementChannelNumber) { - this.managementChannelNumber = managementChannelNumber; - } + public void setManagementChannelNumber(int managementChannelNumber) { + this.managementChannelNumber = managementChannelNumber; + } - public DeviceType getDeviceType() { - return deviceType; - } + public DeviceType getDeviceType() { + return deviceType; + } - public void setDeviceType(DeviceType deviceType) { - this.deviceType = deviceType; - } + public void setDeviceType(DeviceType deviceType) { + this.deviceType = deviceType; + } - public int getDeviceTypeModifier() { - return deviceTypeModifier; - } + public int getDeviceTypeModifier() { + return deviceTypeModifier; + } - public void setDeviceTypeModifier(int deviceTypeModifier) { - this.deviceTypeModifier = deviceTypeModifier; - } + public void setDeviceTypeModifier(int deviceTypeModifier) { + this.deviceTypeModifier = deviceTypeModifier; + } - public int getFruEntityId() { - return fruEntityId; - } + public int getFruEntityId() { + return fruEntityId; + } - public void setFruEntityId(int fruEntityId) { - this.fruEntityId = fruEntityId; - } + public void setFruEntityId(int fruEntityId) { + this.fruEntityId = fruEntityId; + } - public int getFruEntityInstance() { - return fruEntityInstance; - } + public int getFruEntityInstance() { + return fruEntityInstance; + } - public void setFruEntityInstance(int fruEntityInstance) { - this.fruEntityInstance = fruEntityInstance; - } + public void setFruEntityInstance(int fruEntityInstance) { + this.fruEntityInstance = fruEntityInstance; + } - public void setName(String name) { - this.name = name; - } + public void setName(String name) { + this.name = name; + } - public String getName() { - return name; - } + public String getName() { + return name; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/FullSensorRecord.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/FullSensorRecord.java index 33f115d..8a7cc9f 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/FullSensorRecord.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/FullSensorRecord.java @@ -29,570 +29,633 @@ */ public class FullSensorRecord extends SensorRecord { - private byte sensorOwnerId; + private byte sensorOwnerId; - private AddressType addressType; + private AddressType addressType; - private byte channelNumber; + private byte channelNumber; - private byte sensorOwnerLun; + private byte sensorOwnerLun; - private byte sensorNumber; + private byte sensorNumber; - private EntityId entityId; + private EntityId entityId; - /** - * Entity is physical if true, logical otherwise. - */ - private boolean entityPhysical; + /** + * Entity is physical if true, logical otherwise. + */ + private boolean entityPhysical; - private byte entityInstanceNumber; + private byte entityInstanceNumber; - private boolean hysteresisReadable; + private boolean hysteresisReadable; - private boolean thresholdsReadable; + private boolean thresholdsReadable; - private SensorType sensorType; + private SensorType sensorType; - private int eventReadingType; + private int eventReadingType; - private RateUnit rateUnit; + private RateUnit rateUnit; - private ModifierUnitUsage modifierUnitUsage; + private ModifierUnitUsage modifierUnitUsage; - private SensorUnit sensorBaseUnit; + private SensorUnit sensorBaseUnit; - private SensorUnit sensorModifierUnit; + private SensorUnit sensorModifierUnit; - private double m; + private double m; - private double tolerance; + private double tolerance; - private double b; + private double b; - private double accuracy; + private double accuracy; - private int rExp; + private int rExp; - private SensorDirection sensorDirection; + private SensorDirection sensorDirection; - private double nominalReading; + private double nominalReading; - private double normalMaximum; + private double normalMaximum; - private double normalMinimum; + private double normalMinimum; - private double sensorMaximumReading; + private double sensorMaximumReading; - private double sensorMinmumReading; + private double sensorMinmumReading; - private double upperNonRecoverableThreshold; + private double upperNonRecoverableThreshold; - private double lowerNonRecoverableThreshold; + private double lowerNonRecoverableThreshold; - private double upperCriticalThreshold; + private double upperCriticalThreshold; - private double lowerCriticalThreshold; + private double lowerCriticalThreshold; - private double upperNonCriticalThreshold; + private double upperNonCriticalThreshold; - private double lowerNonCriticalThreshold; + private double lowerNonCriticalThreshold; - private String name; + private String name; - private byte sensorUnits1; + private byte sensorUnits1; - private int linearization; + private int linearization; - @Override - protected void populateTypeSpecficValues(byte[] recordData, - SensorRecord record) { - setSensorOwnerId(TypeConverter.intToByte((TypeConverter - .byteToInt(recordData[5]) & 0xfe) >> 1)); + @Override + protected void populateTypeSpecficValues( + byte[] recordData, + SensorRecord record) { + setSensorOwnerId( + TypeConverter + .intToByte( + (TypeConverter + .byteToInt(recordData[5]) + & 0xfe) >> 1)); - setAddressType(AddressType.parseInt(TypeConverter - .byteToInt(recordData[5]) & 0x01)); + setAddressType( + AddressType + .parseInt( + TypeConverter + .byteToInt(recordData[5]) + & 0x01)); - setChannelNumber(TypeConverter.intToByte((TypeConverter - .byteToInt(recordData[6]) & 0xf0) >> 4)); + setChannelNumber( + TypeConverter + .intToByte( + (TypeConverter + .byteToInt(recordData[6]) + & 0xf0) >> 4)); - setSensorOwnerLun(TypeConverter.intToByte(TypeConverter - .byteToInt(recordData[6]) & 0x3)); + setSensorOwnerLun( + TypeConverter + .intToByte( + TypeConverter + .byteToInt(recordData[6]) + & 0x3)); - setSensorNumber(recordData[7]); + setSensorNumber(recordData[7]); - setEntityId(EntityId.parseInt(TypeConverter.byteToInt(recordData[8]))); + setEntityId(EntityId.parseInt(TypeConverter.byteToInt(recordData[8]))); - setEntityPhysical((TypeConverter.byteToInt(recordData[9]) & 0x80) == 0); + setEntityPhysical((TypeConverter.byteToInt(recordData[9]) & 0x80) == 0); - setEntityInstanceNumber(TypeConverter.intToByte(TypeConverter - .byteToInt(recordData[9]) & 0x7f)); + setEntityInstanceNumber( + TypeConverter + .intToByte( + TypeConverter + .byteToInt(recordData[9]) + & 0x7f)); - int hysteresis = (TypeConverter.byteToInt(recordData[11]) & 0x30) >> 4; - setHysteresisReadable(isFieldReadable(hysteresis)); + int hysteresis = (TypeConverter.byteToInt(recordData[11]) & 0x30) >> 4; + setHysteresisReadable(isFieldReadable(hysteresis)); - int thresholds = (TypeConverter.byteToInt(recordData[11]) & 0xc) >> 2; - setThresholdsReadable(isFieldReadable(thresholds)); + int thresholds = (TypeConverter.byteToInt(recordData[11]) & 0xc) >> 2; + setThresholdsReadable(isFieldReadable(thresholds)); - setSensorType(SensorType.parseInt(TypeConverter - .byteToInt(recordData[12]))); + setSensorType( + SensorType + .parseInt( + TypeConverter + .byteToInt(recordData[12]))); - setEventReadingType(TypeConverter.byteToInt(recordData[13])); + setEventReadingType(TypeConverter.byteToInt(recordData[13])); - setRateUnit(RateUnit - .parseInt((TypeConverter.byteToInt(recordData[20]) & 0x38) >> 3)); + setRateUnit( + RateUnit + .parseInt((TypeConverter.byteToInt(recordData[20]) & 0x38) >> 3)); - setModifierUnitUsage(ModifierUnitUsage.parseInt((TypeConverter - .byteToInt(recordData[20]) & 0x6) >> 1)); + setModifierUnitUsage( + ModifierUnitUsage + .parseInt( + (TypeConverter + .byteToInt(recordData[20]) + & 0x6) >> 1)); - setSensorBaseUnit(SensorUnit.parseInt(TypeConverter - .byteToInt(recordData[21]))); + setSensorBaseUnit( + SensorUnit + .parseInt( + TypeConverter + .byteToInt(recordData[21]))); + + setSensorModifierUnit( + SensorUnit + .parseInt( + TypeConverter + .byteToInt(recordData[22]))); + + int calcM = TypeConverter.byteToInt(recordData[24]); + + calcM |= (TypeConverter.byteToInt(recordData[25]) & 0xc0) << 2; + + setM(TypeConverter.decode2sComplement(calcM, 9)); + + sensorUnits1 = recordData[20]; + + setTolerance( + calcFormula( + (TypeConverter.byteToInt(recordData[25]) & 0x3f) / 2, + 8, + sensorUnits1)); + + int calcB = TypeConverter.byteToInt(recordData[26]); + + calcB |= (TypeConverter.byteToInt(recordData[27]) & 0xc0) << 2; + + setB(TypeConverter.decode2sComplement(calcB, 9)); + + int calcAcc = TypeConverter.byteToInt(recordData[27]) & 0x3f; + + calcAcc |= (TypeConverter.byteToInt(recordData[28]) & 0xf0) << 2; + + int exp = TypeConverter.byteToInt(recordData[28]) & 0xc >> 2; + + setAccuracy((double) calcAcc / 10000 * Math.pow(10, exp)); + + setSensorDirection( + SensorDirection + .parseInt( + TypeConverter + .byteToInt(recordData[28]) + & 0x3)); + + setrExp( + TypeConverter + .decode2sComplement( + (TypeConverter.byteToInt(recordData[29]) & 0xf0) >> 4, + 3)); + + int bExp = TypeConverter + .decode2sComplement( + (TypeConverter.byteToInt(recordData[29]) & 0xf), + 3); + + setB(getB() * Math.pow(10, bExp)); + + setNominalReading(calcFormula(TypeConverter.byteToInt(recordData[31]))); + setNormalMaximum(calcFormula(TypeConverter.byteToInt(recordData[32]))); + setNormalMinimum(calcFormula(TypeConverter.byteToInt(recordData[33]))); + + setSensorMaximumReading( + calcFormula( + TypeConverter + .byteToInt(recordData[34]))); + setSensorMinmumReading( + calcFormula( + TypeConverter + .byteToInt(recordData[35]))); + + if ((TypeConverter.byteToInt(recordData[10]) & 0x4) != 0) { + if ((TypeConverter.byteToInt(recordData[18]) & 0x20) != 0) { + setUpperNonRecoverableThreshold( + calcFormula( + TypeConverter + .byteToInt(recordData[36]))); + } + if ((TypeConverter.byteToInt(recordData[18]) & 0x10) != 0) { + setUpperCriticalThreshold( + calcFormula( + TypeConverter + .byteToInt(recordData[37]))); + } + if ((TypeConverter.byteToInt(recordData[18]) & 0x8) != 0) { + setUpperNonCriticalThreshold( + calcFormula( + TypeConverter + .byteToInt(recordData[38]))); + } + + if ((TypeConverter.byteToInt(recordData[18]) & 0x4) != 0) { + setLowerNonRecoverableThreshold( + calcFormula( + TypeConverter + .byteToInt(recordData[39]))); + } + if ((TypeConverter.byteToInt(recordData[18]) & 0x2) != 0) { + setLowerCriticalThreshold( + calcFormula( + TypeConverter + .byteToInt(recordData[40]))); + } + if ((TypeConverter.byteToInt(recordData[18]) & 0x1) != 0) { + setLowerNonCriticalThreshold( + calcFormula( + TypeConverter + .byteToInt(recordData[41]))); + } + } + + byte[] nameData = new byte[recordData.length - 48]; + + System.arraycopy(recordData, 48, nameData, 0, nameData.length); + + setName(decodeName(recordData[47], nameData)); + + linearization = TypeConverter.byteToInt(recordData[23]) & 0x7f; + } + + private boolean isFieldReadable(int field) { + return field == 1 /* field readable */ + || field == 2 /* field readable & settable */; + } + + public void setSensorOwnerId(byte sensorOwnerId) { + this.sensorOwnerId = sensorOwnerId; + } + + public byte getSensorOwnerId() { + return sensorOwnerId; + } + + public AddressType getAddressType() { + return addressType; + } + + public void setAddressType(AddressType addressType) { + this.addressType = addressType; + } + + public byte getChannelNumber() { + return channelNumber; + } + + public void setChannelNumber(byte channelNumber) { + this.channelNumber = channelNumber; + } + + public byte getSensorOwnerLun() { + return sensorOwnerLun; + } + + public void setSensorOwnerLun(byte sensorOwnerLun) { + this.sensorOwnerLun = sensorOwnerLun; + } + + public byte getSensorNumber() { + return sensorNumber; + } + + public void setSensorNumber(byte sensorNumber) { + this.sensorNumber = sensorNumber; + } + + public EntityId getEntityId() { + return entityId; + } + + public void setEntityId(EntityId entityId) { + this.entityId = entityId; + } + + public boolean isEntityPhysical() { + return entityPhysical; + } + + public void setEntityPhysical(boolean entityPhysical) { + this.entityPhysical = entityPhysical; + } + + public byte getEntityInstanceNumber() { + return entityInstanceNumber; + } + + public void setEntityInstanceNumber(byte entityInstanceNumber) { + this.entityInstanceNumber = entityInstanceNumber; + } + + public boolean isHysteresisReadable() { + return hysteresisReadable; + } + + public void setHysteresisReadable(boolean hysteresisReadable) { + this.hysteresisReadable = hysteresisReadable; + } + + public boolean isThresholdsReadable() { + return thresholdsReadable; + } - setSensorModifierUnit(SensorUnit.parseInt(TypeConverter - .byteToInt(recordData[22]))); + public void setThresholdsReadable(boolean thresholdsReadable) { + this.thresholdsReadable = thresholdsReadable; + } - int calcM = TypeConverter.byteToInt(recordData[24]); + public SensorType getSensorType() { + return sensorType; + } - calcM |= (TypeConverter.byteToInt(recordData[25]) & 0xc0) << 2; + public void setSensorType(SensorType sensorType) { + this.sensorType = sensorType; + } - setM(TypeConverter.decode2sComplement(calcM, 9)); + public int getEventReadingType() { + return eventReadingType; + } - sensorUnits1 = recordData[20]; + public void setEventReadingType(int eventReadingType) { + this.eventReadingType = eventReadingType; + } - setTolerance(calcFormula( - (TypeConverter.byteToInt(recordData[25]) & 0x3f) / 2, 8, sensorUnits1)); + public RateUnit getRateUnit() { + return rateUnit; + } - int calcB = TypeConverter.byteToInt(recordData[26]); + public void setRateUnit(RateUnit rateUnit) { + this.rateUnit = rateUnit; + } - calcB |= (TypeConverter.byteToInt(recordData[27]) & 0xc0) << 2; + public ModifierUnitUsage getModifierUnitUsage() { + return modifierUnitUsage; + } - setB(TypeConverter.decode2sComplement(calcB, 9)); + public void setModifierUnitUsage(ModifierUnitUsage modifierUnitUsage) { + this.modifierUnitUsage = modifierUnitUsage; + } - int calcAcc = TypeConverter.byteToInt(recordData[27]) & 0x3f; + public SensorUnit getSensorBaseUnit() { + return sensorBaseUnit; + } - calcAcc |= (TypeConverter.byteToInt(recordData[28]) & 0xf0) << 2; + public void setSensorBaseUnit(SensorUnit sensorBaseUnit) { + this.sensorBaseUnit = sensorBaseUnit; + } - int exp = TypeConverter.byteToInt(recordData[28]) & 0xc >> 2; + public SensorUnit getSensorModifierUnit() { + return sensorModifierUnit; + } - setAccuracy((double) calcAcc / 10000 * Math.pow(10, exp)); + public void setSensorModifierUnit(SensorUnit sensorModifierUnit) { + this.sensorModifierUnit = sensorModifierUnit; + } - setSensorDirection(SensorDirection.parseInt(TypeConverter - .byteToInt(recordData[28]) & 0x3)); + private double getM() { + return m; + } - setrExp(TypeConverter.decode2sComplement( - (TypeConverter.byteToInt(recordData[29]) & 0xf0) >> 4, 3)); + private void setM(double m) { + this.m = m; + } - int bExp = TypeConverter.decode2sComplement( - (TypeConverter.byteToInt(recordData[29]) & 0xf), 3); + public double getTolerance() { + return tolerance; + } - setB(getB() * Math.pow(10, bExp)); + public void setTolerance(double mTolerance) { + this.tolerance = mTolerance; + } - setNominalReading(calcFormula(TypeConverter.byteToInt(recordData[31]))); - setNormalMaximum(calcFormula(TypeConverter.byteToInt(recordData[32]))); - setNormalMinimum(calcFormula(TypeConverter.byteToInt(recordData[33]))); + private double getB() { + return b; + } - setSensorMaximumReading(calcFormula(TypeConverter - .byteToInt(recordData[34]))); - setSensorMinmumReading(calcFormula(TypeConverter - .byteToInt(recordData[35]))); + private void setB(double b) { + this.b = b; + } - if ((TypeConverter.byteToInt(recordData[10]) & 0x4) != 0) { - if ((TypeConverter.byteToInt(recordData[18]) & 0x20) != 0) { - setUpperNonRecoverableThreshold(calcFormula(TypeConverter - .byteToInt(recordData[36]))); - } - if ((TypeConverter.byteToInt(recordData[18]) & 0x10) != 0) { - setUpperCriticalThreshold(calcFormula(TypeConverter - .byteToInt(recordData[37]))); - } - if ((TypeConverter.byteToInt(recordData[18]) & 0x8) != 0) { - setUpperNonCriticalThreshold(calcFormula(TypeConverter - .byteToInt(recordData[38]))); - } + public double getAccuracy() { + return accuracy; + } - if ((TypeConverter.byteToInt(recordData[18]) & 0x4) != 0) { - setLowerNonRecoverableThreshold(calcFormula(TypeConverter - .byteToInt(recordData[39]))); - } - if ((TypeConverter.byteToInt(recordData[18]) & 0x2) != 0) { - setLowerCriticalThreshold(calcFormula(TypeConverter - .byteToInt(recordData[40]))); - } - if ((TypeConverter.byteToInt(recordData[18]) & 0x1) != 0) { - setLowerNonCriticalThreshold(calcFormula(TypeConverter - .byteToInt(recordData[41]))); - } - } + public void setAccuracy(double bAccuracy) { + this.accuracy = bAccuracy; + } - byte[] nameData = new byte[recordData.length - 48]; + private void setrExp(int rExp) { + this.rExp = rExp; + } - System.arraycopy(recordData, 48, nameData, 0, nameData.length); + private int getrExp() { + return rExp; + } - setName(decodeName(recordData[47], nameData)); + public SensorDirection getSensorDirection() { + return sensorDirection; + } - linearization = TypeConverter.byteToInt(recordData[23]) & 0x7f; - } + public void setSensorDirection(SensorDirection sensorDirection) { + this.sensorDirection = sensorDirection; + } - private boolean isFieldReadable(int field) { - return field == 1 /* field readable */ - || field == 2 /* field readable & settable */; - } - - public void setSensorOwnerId(byte sensorOwnerId) { - this.sensorOwnerId = sensorOwnerId; - } - - public byte getSensorOwnerId() { - return sensorOwnerId; - } - - public AddressType getAddressType() { - return addressType; - } - - public void setAddressType(AddressType addressType) { - this.addressType = addressType; - } - - public byte getChannelNumber() { - return channelNumber; - } - - public void setChannelNumber(byte channelNumber) { - this.channelNumber = channelNumber; - } - - public byte getSensorOwnerLun() { - return sensorOwnerLun; - } - - public void setSensorOwnerLun(byte sensorOwnerLun) { - this.sensorOwnerLun = sensorOwnerLun; - } - - public byte getSensorNumber() { - return sensorNumber; - } - - public void setSensorNumber(byte sensorNumber) { - this.sensorNumber = sensorNumber; - } - - public EntityId getEntityId() { - return entityId; - } - - public void setEntityId(EntityId entityId) { - this.entityId = entityId; - } - - public boolean isEntityPhysical() { - return entityPhysical; - } - - public void setEntityPhysical(boolean entityPhysical) { - this.entityPhysical = entityPhysical; - } - - public byte getEntityInstanceNumber() { - return entityInstanceNumber; - } - - public void setEntityInstanceNumber(byte entityInstanceNumber) { - this.entityInstanceNumber = entityInstanceNumber; - } - - public boolean isHysteresisReadable() { - return hysteresisReadable; - } - - public void setHysteresisReadable(boolean hysteresisReadable) { - this.hysteresisReadable = hysteresisReadable; - } - - public boolean isThresholdsReadable() { - return thresholdsReadable; - } - - public void setThresholdsReadable(boolean thresholdsReadable) { - this.thresholdsReadable = thresholdsReadable; - } - - public SensorType getSensorType() { - return sensorType; - } - - public void setSensorType(SensorType sensorType) { - this.sensorType = sensorType; - } - - public int getEventReadingType() { - return eventReadingType; - } - - public void setEventReadingType(int eventReadingType) { - this.eventReadingType = eventReadingType; - } - - public RateUnit getRateUnit() { - return rateUnit; - } - - public void setRateUnit(RateUnit rateUnit) { - this.rateUnit = rateUnit; - } - - public ModifierUnitUsage getModifierUnitUsage() { - return modifierUnitUsage; - } - - public void setModifierUnitUsage(ModifierUnitUsage modifierUnitUsage) { - this.modifierUnitUsage = modifierUnitUsage; - } - - public SensorUnit getSensorBaseUnit() { - return sensorBaseUnit; - } - - public void setSensorBaseUnit(SensorUnit sensorBaseUnit) { - this.sensorBaseUnit = sensorBaseUnit; - } - - public SensorUnit getSensorModifierUnit() { - return sensorModifierUnit; - } - - public void setSensorModifierUnit(SensorUnit sensorModifierUnit) { - this.sensorModifierUnit = sensorModifierUnit; - } - - private double getM() { - return m; - } - - private void setM(double m) { - this.m = m; - } - - public double getTolerance() { - return tolerance; - } - - public void setTolerance(double mTolerance) { - this.tolerance = mTolerance; - } - - private double getB() { - return b; - } - - private void setB(double b) { - this.b = b; - } - - public double getAccuracy() { - return accuracy; - } - - public void setAccuracy(double bAccuracy) { - this.accuracy = bAccuracy; - } - - private void setrExp(int rExp) { - this.rExp = rExp; - } - - private int getrExp() { - return rExp; - } - - public SensorDirection getSensorDirection() { - return sensorDirection; - } - - public void setSensorDirection(SensorDirection sensorDirection) { - this.sensorDirection = sensorDirection; - } - - public double getNominalReading() { - return nominalReading; - } - - public void setNominalReading(double nominalReading) { - this.nominalReading = nominalReading; - } - - public double getNormalMaximum() { - return normalMaximum; - } - - public void setNormalMaximum(double normalMaximum) { - this.normalMaximum = normalMaximum; - } - - public double getNormalMinimum() { - return normalMinimum; - } - - public void setNormalMinimum(double normalMinimum) { - this.normalMinimum = normalMinimum; - } - - public double getSensorMaximumReading() { - return sensorMaximumReading; - } - - public void setSensorMaximumReading(double sensorMaximumReading) { - this.sensorMaximumReading = sensorMaximumReading; - } - - public double getSensorMinmumReading() { - return sensorMinmumReading; - } - - public void setSensorMinmumReading(double sensorMinmumReading) { - this.sensorMinmumReading = sensorMinmumReading; - } - - public double getUpperNonRecoverableThreshold() { - return upperNonRecoverableThreshold; - } - - public void setUpperNonRecoverableThreshold( - double upperNonRecoverableThreshold) { - this.upperNonRecoverableThreshold = upperNonRecoverableThreshold; - } - - public double getLowerNonRecoverableThreshold() { - return lowerNonRecoverableThreshold; - } - - public void setLowerNonRecoverableThreshold( - double lowerNonRecoverableThreshold) { - this.lowerNonRecoverableThreshold = lowerNonRecoverableThreshold; - } - - public double getUpperCriticalThreshold() { - return upperCriticalThreshold; - } - - public void setUpperCriticalThreshold(double upperCriticalThreshold) { - this.upperCriticalThreshold = upperCriticalThreshold; - } - - public double getLowerCriticalThreshold() { - return lowerCriticalThreshold; - } - - public void setLowerCriticalThreshold(double lowerCriticalThreshold) { - this.lowerCriticalThreshold = lowerCriticalThreshold; - } - - public double getUpperNonCriticalThreshold() { - return upperNonCriticalThreshold; - } - - public void setUpperNonCriticalThreshold(double upperNonCriticalThreshold) { - this.upperNonCriticalThreshold = upperNonCriticalThreshold; - } - - public double getLowerNonCriticalThreshold() { - return lowerNonCriticalThreshold; - } - - public void setLowerNonCriticalThreshold(double lowerNonCriticalThreshold) { - this.lowerNonCriticalThreshold = lowerNonCriticalThreshold; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - /** - * Converts to units-based value using the 'y=Mx+B' formula. 1's or 2's - * complement signed or unsigned per flag bits in Sensor Units 1. - * - * @param value - * - Value to be converted. Length of 8 is assumed. - * @return converted value - */ - public double calcFormula(int value) { - return calcFormula(value, 8, sensorUnits1); - } - - /** - * Converts to units-based value using the 'y=Mx+B' formula. 1's or 2's - * complement signed or unsigned per flag bits in Sensor Units 1. - * - * @param value - * - value to be converted - * @param length - * - number of bits of value - * @param sensorUnits1 - * - byte containing numeric data format - * @return converted value - * @throws IllegalArgumentException - * when record's numeric values are linearized in a way that is - * not supported - */ - protected double calcFormula(int value, int length, byte sensorUnits1) { - int dataFormat = (TypeConverter.byteToInt(sensorUnits1) & 0xc0) >> 6; - - int base = 0; - - switch (dataFormat) { - case 0: // unsigned - base = value; - break; - case 1: // 1's complement - base = TypeConverter.decode1sComplement(value, length - 1); - break; - case 2: // 2's complement - base = TypeConverter.decode2sComplement(value, length - 1); - break; - case 3: // no analog reading - base = value; - break; - default: - throw new IllegalArgumentException( - "Invalid data format in sensorUnits1"); - } - - double result = (getM() * base + getB()) * Math.pow(10, getrExp()); - - switch (linearization) { - case 0: - return result; - case 1: - return Math.log(result); - case 2: - return Math.log10(result); - case 3: - return Math.log(result) / Math.log(2); - case 5: - return Math.pow(10, result); - case 6: - return Math.pow(2, result); - case 7: - return 1 / result; - case 8: - return Math.pow(result, 2); - case 9: - return Math.pow(result, 3); - case 10: - return Math.pow(result, 0.5); - case 11: - return Math.pow(result, 0.33); - default: - throw new IllegalArgumentException("Unsupported linearization type"); - } - } - - public double getSensorResolution() { - return Math.abs(getM() / 2.0 * Math.pow(10, getrExp())); - } + public double getNominalReading() { + return nominalReading; + } + + public void setNominalReading(double nominalReading) { + this.nominalReading = nominalReading; + } + + public double getNormalMaximum() { + return normalMaximum; + } + + public void setNormalMaximum(double normalMaximum) { + this.normalMaximum = normalMaximum; + } + + public double getNormalMinimum() { + return normalMinimum; + } + + public void setNormalMinimum(double normalMinimum) { + this.normalMinimum = normalMinimum; + } + + public double getSensorMaximumReading() { + return sensorMaximumReading; + } + + public void setSensorMaximumReading(double sensorMaximumReading) { + this.sensorMaximumReading = sensorMaximumReading; + } + + public double getSensorMinmumReading() { + return sensorMinmumReading; + } + + public void setSensorMinmumReading(double sensorMinmumReading) { + this.sensorMinmumReading = sensorMinmumReading; + } + + public double getUpperNonRecoverableThreshold() { + return upperNonRecoverableThreshold; + } + + public void setUpperNonRecoverableThreshold( + double upperNonRecoverableThreshold) { + this.upperNonRecoverableThreshold = upperNonRecoverableThreshold; + } + + public double getLowerNonRecoverableThreshold() { + return lowerNonRecoverableThreshold; + } + + public void setLowerNonRecoverableThreshold( + double lowerNonRecoverableThreshold) { + this.lowerNonRecoverableThreshold = lowerNonRecoverableThreshold; + } + + public double getUpperCriticalThreshold() { + return upperCriticalThreshold; + } + + public void setUpperCriticalThreshold(double upperCriticalThreshold) { + this.upperCriticalThreshold = upperCriticalThreshold; + } + + public double getLowerCriticalThreshold() { + return lowerCriticalThreshold; + } + + public void setLowerCriticalThreshold(double lowerCriticalThreshold) { + this.lowerCriticalThreshold = lowerCriticalThreshold; + } + + public double getUpperNonCriticalThreshold() { + return upperNonCriticalThreshold; + } + + public void setUpperNonCriticalThreshold(double upperNonCriticalThreshold) { + this.upperNonCriticalThreshold = upperNonCriticalThreshold; + } + + public double getLowerNonCriticalThreshold() { + return lowerNonCriticalThreshold; + } + + public void setLowerNonCriticalThreshold(double lowerNonCriticalThreshold) { + this.lowerNonCriticalThreshold = lowerNonCriticalThreshold; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + /** + * Converts to units-based value using the 'y=Mx+B' formula. 1's or 2's + * complement signed or unsigned per flag bits in Sensor Units 1. + * + * @param value + * - Value to be converted. Length of 8 is assumed. + * @return converted value + */ + public double calcFormula(int value) { + return calcFormula(value, 8, sensorUnits1); + } + + /** + * Converts to units-based value using the 'y=Mx+B' formula. 1's or 2's + * complement signed or unsigned per flag bits in Sensor Units 1. + * + * @param value + * - value to be converted + * @param length + * - number of bits of value + * @param units1 + * - byte containing numeric data format + * @return converted value + * @throws IllegalArgumentException + * when record's numeric values are linearized in a way that is + * not supported + */ + protected double calcFormula(int value, int length, byte units1) { + int dataFormat = (TypeConverter.byteToInt(units1) & 0xc0) >> 6; + + int base = 0; + + switch (dataFormat) { + case 0: // unsigned + base = value; + break; + case 1: // 1's complement + base = TypeConverter.decode1sComplement(value, length - 1); + break; + case 2: // 2's complement + base = TypeConverter.decode2sComplement(value, length - 1); + break; + case 3: // no analog reading + base = value; + break; + default: + throw new IllegalArgumentException( + "Invalid data format in sensorUnits1"); + } + + double result = (getM() * base + getB()) * Math.pow(10, getrExp()); + + switch (linearization) { + case 0: + return result; + case 1: + return Math.log(result); + case 2: + return Math.log10(result); + case 3: + return Math.log(result) / Math.log(2); + case 5: + return Math.pow(10, result); + case 6: + return Math.pow(2, result); + case 7: + return 1 / result; + case 8: + return Math.pow(result, 2); + case 9: + return Math.pow(result, 3); + case 10: + return Math.pow(result, 0.5); + case 11: + return Math.pow(result, 0.33); + default: + throw new IllegalArgumentException("Unsupported linearization type"); + } + } + + public double getSensorResolution() { + return Math.abs(getM() / 2.0 * Math.pow(10, getrExp())); + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/GenericDeviceLocatorRecord.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/GenericDeviceLocatorRecord.java index 017cda4..90ce614 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/GenericDeviceLocatorRecord.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/GenericDeviceLocatorRecord.java @@ -31,145 +31,146 @@ */ public class GenericDeviceLocatorRecord extends SensorRecord { - private int deviceAccessAddress; + private int deviceAccessAddress; - private int deviceSlaveAddress; + private int deviceSlaveAddress; - private int channelNumber; + private int channelNumber; - private int accessLun; + private int accessLun; - private int busId; + private int busId; - private int addressSpan; + private int addressSpan; - private DeviceType deviceType; + private DeviceType deviceType; - private int deviceTypeModifier; + private int deviceTypeModifier; - private int entityId; + private int entityId; - private int entityInstance; + private int entityInstance; - private String name; + private String name; - @Override - protected void populateTypeSpecficValues(byte[] recordData, - SensorRecord record) { + @Override + protected void populateTypeSpecficValues( + byte[] recordData, + SensorRecord record) { - setDeviceAccessAddress((TypeConverter.byteToInt(recordData[5]) & 0xfe) >> 1); + setDeviceAccessAddress((TypeConverter.byteToInt(recordData[5]) & 0xfe) >> 1); - setDeviceSlaveAddress((TypeConverter.byteToInt(recordData[6]) & 0xfe) >> 1); + setDeviceSlaveAddress((TypeConverter.byteToInt(recordData[6]) & 0xfe) >> 1); - setChannelNumber(((TypeConverter.byteToInt(recordData[6]) & 0x1) << 3) - | ((TypeConverter.byteToInt(recordData[7]) & 0xe0) >> 5)); + setChannelNumber( + ((TypeConverter.byteToInt(recordData[6]) & 0x1) << 3) + | ((TypeConverter.byteToInt(recordData[7]) & 0xe0) >> 5)); - setAccessLun((TypeConverter.byteToInt(recordData[7]) & 0x18) >> 3); + setAccessLun((TypeConverter.byteToInt(recordData[7]) & 0x18) >> 3); - setBusId(TypeConverter.byteToInt(recordData[7]) & 0x3); + setBusId(TypeConverter.byteToInt(recordData[7]) & 0x3); - setAddressSpan(TypeConverter.byteToInt(recordData[8]) & 0x3); + setAddressSpan(TypeConverter.byteToInt(recordData[8]) & 0x3); - setDeviceType(DeviceType.parseInt(TypeConverter.byteToInt(recordData[10]))); - setDeviceTypeModifier(TypeConverter.byteToInt(recordData[11])); + setDeviceType(DeviceType.parseInt(TypeConverter.byteToInt(recordData[10]))); + setDeviceTypeModifier(TypeConverter.byteToInt(recordData[11])); - setEntityId(TypeConverter.byteToInt(recordData[12])); - setEntityInstance(TypeConverter.byteToInt(recordData[13])); + setEntityId(TypeConverter.byteToInt(recordData[12])); + setEntityInstance(TypeConverter.byteToInt(recordData[13])); + byte[] nameData = new byte[recordData.length - 17]; - byte[] nameData = new byte[recordData.length - 17]; + System.arraycopy(recordData, 17, nameData, 0, nameData.length); - System.arraycopy(recordData, 17, nameData, 0, nameData.length); + setName(decodeName(recordData[16], nameData)); + } - setName(decodeName(recordData[16], nameData)); - } + public int getDeviceAccessAddress() { + return deviceAccessAddress; + } - public int getDeviceAccessAddress() { - return deviceAccessAddress; - } + public void setDeviceAccessAddress(int deviceAccessAddress) { + this.deviceAccessAddress = deviceAccessAddress; + } - public void setDeviceAccessAddress(int deviceAccessAddress) { - this.deviceAccessAddress = deviceAccessAddress; - } + public int getDeviceSlaveAddress() { + return deviceSlaveAddress; + } - public int getDeviceSlaveAddress() { - return deviceSlaveAddress; - } + public void setDeviceSlaveAddress(int deviceSlaveAddress) { + this.deviceSlaveAddress = deviceSlaveAddress; + } - public void setDeviceSlaveAddress(int deviceSlaveAddress) { - this.deviceSlaveAddress = deviceSlaveAddress; - } + public int getChannelNumber() { + return channelNumber; + } - public int getChannelNumber() { - return channelNumber; - } + public void setChannelNumber(int channelNumber) { + this.channelNumber = channelNumber; + } - public void setChannelNumber(int channelNumber) { - this.channelNumber = channelNumber; - } + public int getAccessLun() { + return accessLun; + } - public int getAccessLun() { - return accessLun; - } + public void setAccessLun(int accessLun) { + this.accessLun = accessLun; + } - public void setAccessLun(int accessLun) { - this.accessLun = accessLun; - } + public int getBusId() { + return busId; + } - public int getBusId() { - return busId; - } + public void setBusId(int busId) { + this.busId = busId; + } - public void setBusId(int busId) { - this.busId = busId; - } + public int getAddressSpan() { + return addressSpan; + } - public int getAddressSpan() { - return addressSpan; - } + public void setAddressSpan(int addressSpan) { + this.addressSpan = addressSpan; + } - public void setAddressSpan(int addressSpan) { - this.addressSpan = addressSpan; - } + public DeviceType getDeviceType() { + return deviceType; + } - public DeviceType getDeviceType() { - return deviceType; - } + public void setDeviceType(DeviceType deviceType) { + this.deviceType = deviceType; + } - public void setDeviceType(DeviceType deviceType) { - this.deviceType = deviceType; - } + public int getDeviceTypeModifier() { + return deviceTypeModifier; + } - public int getDeviceTypeModifier() { - return deviceTypeModifier; - } + public void setDeviceTypeModifier(int deviceTypeModifier) { + this.deviceTypeModifier = deviceTypeModifier; + } - public void setDeviceTypeModifier(int deviceTypeModifier) { - this.deviceTypeModifier = deviceTypeModifier; - } + public int getEntityId() { + return entityId; + } - public int getEntityId() { - return entityId; - } + public void setEntityId(int entityId) { + this.entityId = entityId; + } - public void setEntityId(int entityId) { - this.entityId = entityId; - } + public int getEntityInstance() { + return entityInstance; + } - public int getEntityInstance() { - return entityInstance; - } + public void setEntityInstance(int entityInstance) { + this.entityInstance = entityInstance; + } - public void setEntityInstance(int entityInstance) { - this.entityInstance = entityInstance; - } + public String getName() { + return name; + } - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } + public void setName(String name) { + this.name = name; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/InstanceModifierType.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/InstanceModifierType.java index 7f1c264..201e1c8 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/InstanceModifierType.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/InstanceModifierType.java @@ -23,28 +23,31 @@ */ public enum InstanceModifierType { - Numeric(InstanceModifierType.NUMERIC), - Alpha(InstanceModifierType.ALPHA), - ; - private static final int NUMERIC = 0; - private static final int ALPHA = 1; + Numeric(InstanceModifierType.NUMERIC), + Alpha(InstanceModifierType.ALPHA), + ; - private int code; + private static final int NUMERIC = 0; + private static final int ALPHA = 1; - InstanceModifierType(int code) { - this.code = code; - } - public int getCode() { - return code; - } - public static InstanceModifierType parseInt(int value) { - switch(value) { - case NUMERIC: - return Numeric; - case ALPHA: - return Alpha; - default: - throw new IllegalArgumentException("Invalid value: " + value); - } - } + private int code; + + InstanceModifierType(int code) { + this.code = code; + } + + public int getCode() { + return code; + } + + public static InstanceModifierType parseInt(int value) { + switch (value) { + case NUMERIC: + return Numeric; + case ALPHA: + return Alpha; + default: + throw new IllegalArgumentException("Invalid value: " + value); + } + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/ManagementControllerConfirmationRecord.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/ManagementControllerConfirmationRecord.java index 3aeb35f..1e8e0c0 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/ManagementControllerConfirmationRecord.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/ManagementControllerConfirmationRecord.java @@ -31,145 +31,147 @@ */ public class ManagementControllerConfirmationRecord extends SensorRecord { - private int deviceSlaveAddress; + private int deviceSlaveAddress; - private int deviceId; + private int deviceId; - private int channelNumber; + private int channelNumber; - private int deviceRevision; + private int deviceRevision; - private int firmwareRevision1; + private int firmwareRevision1; - private int firmwareRevision2; + private int firmwareRevision2; - private int ipmiVersion; + private int ipmiVersion; - private int manufacturerId; + private int manufacturerId; - private int productId; + private int productId; - private byte[] deviceGuid; + private byte[] deviceGuid; - @Override - protected void populateTypeSpecficValues(byte[] recordData, - SensorRecord record) { + @Override + protected void populateTypeSpecficValues( + byte[] recordData, + SensorRecord record) { - setDeviceSlaveAddress(TypeConverter.byteToInt(recordData[5]) >> 1); + setDeviceSlaveAddress(TypeConverter.byteToInt(recordData[5]) >> 1); - setDeviceId(TypeConverter.byteToInt(recordData[6])); + setDeviceId(TypeConverter.byteToInt(recordData[6])); - setChannelNumber((TypeConverter.byteToInt(recordData[7]) & 0xf0) >> 4); + setChannelNumber((TypeConverter.byteToInt(recordData[7]) & 0xf0) >> 4); - setDeviceRevision(TypeConverter.byteToInt(recordData[7]) & 0xf); + setDeviceRevision(TypeConverter.byteToInt(recordData[7]) & 0xf); - setFirmwareRevision1(TypeConverter.byteToInt(recordData[8]) & 0x7f); + setFirmwareRevision1(TypeConverter.byteToInt(recordData[8]) & 0x7f); - setFirmwareRevision2(TypeConverter - .littleEndianBcdByteToInt(recordData[9])); + setFirmwareRevision2( + TypeConverter + .littleEndianBcdByteToInt(recordData[9])); - setIpmiVersion(TypeConverter.littleEndianBcdByteToInt(recordData[10])); + setIpmiVersion(TypeConverter.littleEndianBcdByteToInt(recordData[10])); - byte[] buffer = new byte[4]; + byte[] buffer = new byte[4]; - System.arraycopy(recordData, 11, buffer, 0, 3); + System.arraycopy(recordData, 11, buffer, 0, 3); - buffer[3] = 0; + buffer[3] = 0; - setManufacturerId(TypeConverter.littleEndianByteArrayToInt(buffer)); + setManufacturerId(TypeConverter.littleEndianByteArrayToInt(buffer)); - System.arraycopy(recordData, 14, buffer, 0, 2); + System.arraycopy(recordData, 14, buffer, 0, 2); - buffer[2] = 0; - buffer[3] = 0; + buffer[2] = 0; + buffer[3] = 0; - setProductId(TypeConverter.littleEndianByteArrayToInt(buffer)); + setProductId(TypeConverter.littleEndianByteArrayToInt(buffer)); - byte[] guid = new byte[16]; + byte[] guid = new byte[16]; - System.arraycopy(recordData, 16, guid, 0, 16); + System.arraycopy(recordData, 16, guid, 0, 16); - setDeviceGuid(guid); - } + setDeviceGuid(guid); + } - public int getDeviceSlaveAddress() { - return deviceSlaveAddress; - } + public int getDeviceSlaveAddress() { + return deviceSlaveAddress; + } - public void setDeviceSlaveAddress(int deviceSlaveAddress) { - this.deviceSlaveAddress = deviceSlaveAddress; - } + public void setDeviceSlaveAddress(int deviceSlaveAddress) { + this.deviceSlaveAddress = deviceSlaveAddress; + } - public int getDeviceId() { - return deviceId; - } + public int getDeviceId() { + return deviceId; + } - public void setDeviceId(int deviceId) { - this.deviceId = deviceId; - } + public void setDeviceId(int deviceId) { + this.deviceId = deviceId; + } - public int getChannelNumber() { - return channelNumber; - } + public int getChannelNumber() { + return channelNumber; + } - public void setChannelNumber(int channelNumber) { - this.channelNumber = channelNumber; - } + public void setChannelNumber(int channelNumber) { + this.channelNumber = channelNumber; + } - public int getDeviceRevision() { - return deviceRevision; - } + public int getDeviceRevision() { + return deviceRevision; + } - public void setDeviceRevision(int deviceRevision) { - this.deviceRevision = deviceRevision; - } + public void setDeviceRevision(int deviceRevision) { + this.deviceRevision = deviceRevision; + } - public int getFirmwareRevision1() { - return firmwareRevision1; - } + public int getFirmwareRevision1() { + return firmwareRevision1; + } - public void setFirmwareRevision1(int firmwareRevision1) { - this.firmwareRevision1 = firmwareRevision1; - } + public void setFirmwareRevision1(int firmwareRevision1) { + this.firmwareRevision1 = firmwareRevision1; + } - public int getFirmwareRevision2() { - return firmwareRevision2; - } + public int getFirmwareRevision2() { + return firmwareRevision2; + } - public void setFirmwareRevision2(int firmwareRevision2) { - this.firmwareRevision2 = firmwareRevision2; - } + public void setFirmwareRevision2(int firmwareRevision2) { + this.firmwareRevision2 = firmwareRevision2; + } - public int getIpmiVersion() { - return ipmiVersion; - } + public int getIpmiVersion() { + return ipmiVersion; + } - public void setIpmiVersion(int ipmiVersion) { - this.ipmiVersion = ipmiVersion; - } + public void setIpmiVersion(int ipmiVersion) { + this.ipmiVersion = ipmiVersion; + } - public int getManufacturerId() { - return manufacturerId; - } + public int getManufacturerId() { + return manufacturerId; + } - public void setManufacturerId(int manufacturerId) { - this.manufacturerId = manufacturerId; - } + public void setManufacturerId(int manufacturerId) { + this.manufacturerId = manufacturerId; + } - public int getProductId() { - return productId; - } + public int getProductId() { + return productId; + } - public void setProductId(int productId) { - this.productId = productId; - } + public void setProductId(int productId) { + this.productId = productId; + } - public byte[] getDeviceGuid() { - return deviceGuid; - } + public byte[] getDeviceGuid() { + return deviceGuid; + } - public void setDeviceGuid(byte[] deviceGuid) { - this.deviceGuid = deviceGuid; - } + public void setDeviceGuid(byte[] deviceGuid) { + this.deviceGuid = deviceGuid; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/ManagementControllerDeviceLocatorRecord.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/ManagementControllerDeviceLocatorRecord.java index 2f2f7b2..2e275f6 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/ManagementControllerDeviceLocatorRecord.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/ManagementControllerDeviceLocatorRecord.java @@ -31,201 +31,202 @@ */ public class ManagementControllerDeviceLocatorRecord extends SensorRecord { - private int deviceAddress; + private int deviceAddress; - private int channelNumber; + private int channelNumber; - /** - * Device functions as chassis device, - */ - private boolean supportsChassis; + /** + * Device functions as chassis device, + */ + private boolean supportsChassis; - /** - * Controller responds to Bridge NetFn commands - */ - private boolean supportsBridge; + /** + * Controller responds to Bridge NetFn commands + */ + private boolean supportsBridge; - /** - * Device generates event messages on IPMB - */ - private boolean supportsIpmbEventGenerator; + /** + * Device generates event messages on IPMB + */ + private boolean supportsIpmbEventGenerator; - /** - * Device accepts event messages from IPMB - */ - private boolean supportsIpmbEventReciever; + /** + * Device accepts event messages from IPMB + */ + private boolean supportsIpmbEventReciever; - /** - * Device accepts FRU commands to FRU Device #0 at LUN 00b - */ - private boolean supportsFruInventoryDevice; + /** + * Device accepts FRU commands to FRU Device #0 at LUN 00b + */ + private boolean supportsFruInventoryDevice; - /** - * Device provides interface to SEL - */ - private boolean supportsSelDevice; + /** + * Device provides interface to SEL + */ + private boolean supportsSelDevice; - /** - * For BMC, indicates BMC provides interface to SDR Repository. For other - * controller, indicates controller accepts Device SDR commands - */ - private boolean supportsSdrRepositoryDevice; + /** + * For BMC, indicates BMC provides interface to SDR Repository. For other + * controller, indicates controller accepts Device SDR commands + */ + private boolean supportsSdrRepositoryDevice; - /** - * Device accepts sensor commands - */ - private boolean supportsSensors; + /** + * Device accepts sensor commands + */ + private boolean supportsSensors; - /** - * Entity ID for the FRU associated with this device. - */ - private int entityId; + /** + * Entity ID for the FRU associated with this device. + */ + private int entityId; - /** - * Instance number for entity. - */ - private int entityInstance; + /** + * Instance number for entity. + */ + private int entityInstance; - private String name; + private String name; - @Override - protected void populateTypeSpecficValues(byte[] recordData, - SensorRecord record) { + @Override + protected void populateTypeSpecficValues( + byte[] recordData, + SensorRecord record) { - setDeviceAddress(TypeConverter.byteToInt(recordData[5]) >> 1); + setDeviceAddress(TypeConverter.byteToInt(recordData[5]) >> 1); - setChannelNumber(TypeConverter.byteToInt(recordData[6]) & 0xf); + setChannelNumber(TypeConverter.byteToInt(recordData[6]) & 0xf); - setSupportsChassis((TypeConverter.byteToInt(recordData[8]) & 0x80) != 0); + setSupportsChassis((TypeConverter.byteToInt(recordData[8]) & 0x80) != 0); - setSupportsBridge((TypeConverter.byteToInt(recordData[8]) & 0x40) != 0); + setSupportsBridge((TypeConverter.byteToInt(recordData[8]) & 0x40) != 0); - setSupportsIpmbEventGenerator((TypeConverter.byteToInt(recordData[8]) & 0x20) != 0); + setSupportsIpmbEventGenerator((TypeConverter.byteToInt(recordData[8]) & 0x20) != 0); - setSupportsIpmbEventReciever((TypeConverter.byteToInt(recordData[8]) & 0x10) != 0); + setSupportsIpmbEventReciever((TypeConverter.byteToInt(recordData[8]) & 0x10) != 0); - setSupportsFruInventoryDevice((TypeConverter.byteToInt(recordData[8]) & 0x8) != 0); + setSupportsFruInventoryDevice((TypeConverter.byteToInt(recordData[8]) & 0x8) != 0); - setSupportsSelDevice((TypeConverter.byteToInt(recordData[8]) & 0x4) != 0); + setSupportsSelDevice((TypeConverter.byteToInt(recordData[8]) & 0x4) != 0); - setSupportsSdrRepositoryDevice((TypeConverter.byteToInt(recordData[8]) & 0x2) != 0); + setSupportsSdrRepositoryDevice((TypeConverter.byteToInt(recordData[8]) & 0x2) != 0); - setSupportsSensors((TypeConverter.byteToInt(recordData[8]) & 0x1) != 0); + setSupportsSensors((TypeConverter.byteToInt(recordData[8]) & 0x1) != 0); - setEntityId(TypeConverter.byteToInt(recordData[12])); + setEntityId(TypeConverter.byteToInt(recordData[12])); - setEntityInstance(TypeConverter.byteToInt(recordData[13])); + setEntityInstance(TypeConverter.byteToInt(recordData[13])); - byte[] nameData = new byte[recordData.length - 16]; + byte[] nameData = new byte[recordData.length - 16]; - System.arraycopy(recordData, 16, nameData, 0, nameData.length); + System.arraycopy(recordData, 16, nameData, 0, nameData.length); - setName(decodeName(recordData[15], nameData)); + setName(decodeName(recordData[15], nameData)); - } + } - public int getDeviceAddress() { - return deviceAddress; - } + public int getDeviceAddress() { + return deviceAddress; + } - public void setDeviceAddress(int deviceAddress) { - this.deviceAddress = deviceAddress; - } + public void setDeviceAddress(int deviceAddress) { + this.deviceAddress = deviceAddress; + } - public int getChannelNumber() { - return channelNumber; - } + public int getChannelNumber() { + return channelNumber; + } - public void setChannelNumber(int channelNumber) { - this.channelNumber = channelNumber; - } + public void setChannelNumber(int channelNumber) { + this.channelNumber = channelNumber; + } - public boolean isSupportsChassis() { - return supportsChassis; - } + public boolean isSupportsChassis() { + return supportsChassis; + } - public void setSupportsChassis(boolean supportsChassis) { - this.supportsChassis = supportsChassis; - } + public void setSupportsChassis(boolean supportsChassis) { + this.supportsChassis = supportsChassis; + } - public boolean isSupportsBridge() { - return supportsBridge; - } + public boolean isSupportsBridge() { + return supportsBridge; + } - public void setSupportsBridge(boolean supportsBridge) { - this.supportsBridge = supportsBridge; - } + public void setSupportsBridge(boolean supportsBridge) { + this.supportsBridge = supportsBridge; + } - public boolean isSupportsIpmbEventGenerator() { - return supportsIpmbEventGenerator; - } + public boolean isSupportsIpmbEventGenerator() { + return supportsIpmbEventGenerator; + } - public void setSupportsIpmbEventGenerator(boolean supportsIpmbEventGenerator) { - this.supportsIpmbEventGenerator = supportsIpmbEventGenerator; - } + public void setSupportsIpmbEventGenerator(boolean supportsIpmbEventGenerator) { + this.supportsIpmbEventGenerator = supportsIpmbEventGenerator; + } - public boolean isSupportsIpmbEventReciever() { - return supportsIpmbEventReciever; - } + public boolean isSupportsIpmbEventReciever() { + return supportsIpmbEventReciever; + } - public void setSupportsIpmbEventReciever(boolean supportsIpmbEventReciever) { - this.supportsIpmbEventReciever = supportsIpmbEventReciever; - } + public void setSupportsIpmbEventReciever(boolean supportsIpmbEventReciever) { + this.supportsIpmbEventReciever = supportsIpmbEventReciever; + } - public boolean isSupportsFruInventoryDevice() { - return supportsFruInventoryDevice; - } + public boolean isSupportsFruInventoryDevice() { + return supportsFruInventoryDevice; + } - public void setSupportsFruInventoryDevice(boolean supportsFruInventoryDevice) { - this.supportsFruInventoryDevice = supportsFruInventoryDevice; - } + public void setSupportsFruInventoryDevice(boolean supportsFruInventoryDevice) { + this.supportsFruInventoryDevice = supportsFruInventoryDevice; + } - public boolean isSupportsSelDevice() { - return supportsSelDevice; - } + public boolean isSupportsSelDevice() { + return supportsSelDevice; + } - public void setSupportsSelDevice(boolean supportsSelDevice) { - this.supportsSelDevice = supportsSelDevice; - } + public void setSupportsSelDevice(boolean supportsSelDevice) { + this.supportsSelDevice = supportsSelDevice; + } - public boolean isSupportsSdrRepositoryDevice() { - return supportsSdrRepositoryDevice; - } + public boolean isSupportsSdrRepositoryDevice() { + return supportsSdrRepositoryDevice; + } - public void setSupportsSdrRepositoryDevice(boolean supportsSdrRepositoryDevice) { - this.supportsSdrRepositoryDevice = supportsSdrRepositoryDevice; - } + public void setSupportsSdrRepositoryDevice(boolean supportsSdrRepositoryDevice) { + this.supportsSdrRepositoryDevice = supportsSdrRepositoryDevice; + } - public boolean isSupportsSensors() { - return supportsSensors; - } + public boolean isSupportsSensors() { + return supportsSensors; + } - public void setSupportsSensors(boolean supportsSensors) { - this.supportsSensors = supportsSensors; - } + public void setSupportsSensors(boolean supportsSensors) { + this.supportsSensors = supportsSensors; + } - public int getEntityId() { - return entityId; - } + public int getEntityId() { + return entityId; + } - public void setEntityId(int entityId) { - this.entityId = entityId; - } + public void setEntityId(int entityId) { + this.entityId = entityId; + } - public int getEntityInstance() { - return entityInstance; - } + public int getEntityInstance() { + return entityInstance; + } - public void setEntityInstance(int entityInstance) { - this.entityInstance = entityInstance; - } + public void setEntityInstance(int entityInstance) { + this.entityInstance = entityInstance; + } - public String getName() { - return name; - } + public String getName() { + return name; + } - public void setName(String name) { - this.name = name; - } + public void setName(String name) { + this.name = name; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/ModifierUnitUsage.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/ModifierUnitUsage.java index ebc000c..c734f03 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/ModifierUnitUsage.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/ModifierUnitUsage.java @@ -24,40 +24,40 @@ public enum ModifierUnitUsage { - None(ModifierUnitUsage.NONE), - /** - * Unit = Basic Unit / Modifier Unit - */ - Divide(ModifierUnitUsage.DIVIDE), - /** - * Unit = Basic Unit * Modifier Unit - */ - Mulitply(ModifierUnitUsage.MULITPLY), ; - - private static final int NONE = 0; - private static final int DIVIDE = 1; - private static final int MULITPLY = 2; - - private int code; - - ModifierUnitUsage(int code) { - this.code = code; - } - - public int getCode() { - return code; - } - - public static ModifierUnitUsage parseInt(int value) { - switch (value) { - case NONE: - return None; - case DIVIDE: - return Divide; - case MULITPLY: - return Mulitply; - default: - throw new IllegalArgumentException("Invalid value: " + value); - } - } + None(ModifierUnitUsage.NONE), + /** + * Unit = Basic Unit / Modifier Unit + */ + Divide(ModifierUnitUsage.DIVIDE), + /** + * Unit = Basic Unit * Modifier Unit + */ + Mulitply(ModifierUnitUsage.MULITPLY),; + + private static final int NONE = 0; + private static final int DIVIDE = 1; + private static final int MULITPLY = 2; + + private int code; + + ModifierUnitUsage(int code) { + this.code = code; + } + + public int getCode() { + return code; + } + + public static ModifierUnitUsage parseInt(int value) { + switch (value) { + case NONE: + return None; + case DIVIDE: + return Divide; + case MULITPLY: + return Mulitply; + default: + throw new IllegalArgumentException("Invalid value: " + value); + } + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/OemRecord.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/OemRecord.java index 2c4d6f3..d31ddd5 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/OemRecord.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/OemRecord.java @@ -29,60 +29,61 @@ */ public class OemRecord extends SensorRecord { - /** - * Size of the common SDR record header (record ID, SDR version, record type, record length). - */ - private static final int HEADER_LENGTH = 5; - - /** - * Size of the manufacturer ID field in a C0h OEM record. - */ - private static final int MANUFACTURER_ID_LENGTH = 3; - - private int manufacturerId; - - private byte[] oemData; - - @Override - protected void populateTypeSpecficValues(byte[] recordData, - SensorRecord record) { - - // Only the C0h OEM record has a defined layout (3-byte manufacturer ID - // followed by OEM data). Vendor-defined record types C1h-FFh carry an - // unknown layout, so keep their whole type-specific payload and leave - // the manufacturer ID at 0 (unknown). - int dataOffset = HEADER_LENGTH; - - if (recordData[3] == RecordTypes.OEM_RECORD && recordData.length >= HEADER_LENGTH + MANUFACTURER_ID_LENGTH) { - byte[] buffer = new byte[4]; - System.arraycopy(recordData, HEADER_LENGTH, buffer, 0, MANUFACTURER_ID_LENGTH); - setManufacturerId(TypeConverter.littleEndianByteArrayToInt(buffer)); - dataOffset += MANUFACTURER_ID_LENGTH; - } - - byte[] data = new byte[Math.max(0, recordData.length - dataOffset)]; - - if (data.length > 0) { - System.arraycopy(recordData, dataOffset, data, 0, data.length); - } - - setOemData(data); - } - - public int getManufacturerId() { - return manufacturerId; - } - - public void setManufacturerId(int manufacturerId) { - this.manufacturerId = manufacturerId; - } - - public byte[] getOemData() { - return oemData; - } - - public void setOemData(byte[] oemData) { - this.oemData = oemData; - } + /** + * Size of the common SDR record header (record ID, SDR version, record type, record length). + */ + private static final int HEADER_LENGTH = 5; + + /** + * Size of the manufacturer ID field in a C0h OEM record. + */ + private static final int MANUFACTURER_ID_LENGTH = 3; + + private int manufacturerId; + + private byte[] oemData; + + @Override + protected void populateTypeSpecficValues( + byte[] recordData, + SensorRecord record) { + + // Only the C0h OEM record has a defined layout (3-byte manufacturer ID + // followed by OEM data). Vendor-defined record types C1h-FFh carry an + // unknown layout, so keep their whole type-specific payload and leave + // the manufacturer ID at 0 (unknown). + int dataOffset = HEADER_LENGTH; + + if (recordData[3] == RecordTypes.OEM_RECORD && recordData.length >= HEADER_LENGTH + MANUFACTURER_ID_LENGTH) { + byte[] buffer = new byte[4]; + System.arraycopy(recordData, HEADER_LENGTH, buffer, 0, MANUFACTURER_ID_LENGTH); + setManufacturerId(TypeConverter.littleEndianByteArrayToInt(buffer)); + dataOffset += MANUFACTURER_ID_LENGTH; + } + + byte[] data = new byte[Math.max(0, recordData.length - dataOffset)]; + + if (data.length > 0) { + System.arraycopy(recordData, dataOffset, data, 0, data.length); + } + + setOemData(data); + } + + public int getManufacturerId() { + return manufacturerId; + } + + public void setManufacturerId(int manufacturerId) { + this.manufacturerId = manufacturerId; + } + + public byte[] getOemData() { + return oemData; + } + + public void setOemData(byte[] oemData) { + this.oemData = oemData; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/RateUnit.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/RateUnit.java index 0149fd0..dd43cd4 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/RateUnit.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/RateUnit.java @@ -23,52 +23,58 @@ */ public enum RateUnit { - Microseconds(RateUnit.US, "us"), Miliseconds(RateUnit.MS, "ms"), Seconds( - RateUnit.S, "s"), Minutes(RateUnit.MIN, "min"), Hours(RateUnit.H, - "h"), Days(RateUnit.D, "days"), None(RateUnit.NONE, "") ; + Microseconds(RateUnit.US, "us"), + Miliseconds(RateUnit.MS, "ms"), + Seconds( + RateUnit.S, "s"), + Minutes(RateUnit.MIN, "min"), + Hours(RateUnit.H, + "h"), + Days(RateUnit.D, "days"), + None(RateUnit.NONE, ""); - private static final int NONE = 0x0; - private static final int US = 0x1; - private static final int MS = 0x2; - private static final int S = 0x3; - private static final int MIN = 0x4; - private static final int H = 0x5; - private static final int D = 0x6; + private static final int NONE = 0x0; + private static final int US = 0x1; + private static final int MS = 0x2; + private static final int S = 0x3; + private static final int MIN = 0x4; + private static final int H = 0x5; + private static final int D = 0x6; - private int code; - private String text; + private int code; + private String text; - RateUnit(int code, String value) { - this.code = code; - this.text = value; - } + RateUnit(int code, String value) { + this.code = code; + this.text = value; + } - public int getCode() { - return code; - } + public int getCode() { + return code; + } - public String getUnit() { - return text; - } + public String getUnit() { + return text; + } - public static RateUnit parseInt(int value) { - switch (value) { - case NONE: - return None; - case US: - return Microseconds; - case MS: - return Miliseconds; - case S: - return Seconds; - case MIN: - return Minutes; - case H: - return Hours; - case D: - return Days; - default: - throw new IllegalArgumentException("Invalid value: " + value); - } - } + public static RateUnit parseInt(int value) { + switch (value) { + case NONE: + return None; + case US: + return Microseconds; + case MS: + return Miliseconds; + case S: + return Seconds; + case MIN: + return Minutes; + case H: + return Hours; + case D: + return Days; + default: + throw new IllegalArgumentException("Invalid value: " + value); + } + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/ReadingType.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/ReadingType.java index 1a7a43e..a65fb2c 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/ReadingType.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/ReadingType.java @@ -29,1432 +29,1652 @@ * Type of the reading of the discrete sensor. */ public enum ReadingType { - /** - * FRU in standby or 'hot spare' state. - */ - FruInactive(ReadingType.FRUINACTIVE), SlotConnectorIdentifyStatusAsserted( - ReadingType.SLOTCONNECTORIDENTIFYSTATUSASSERTED), HardReset(ReadingType.HARDRESET), - /** - * Switch indicating FRU latch is in 'unlatched' position and FRU is mechanically removable - */ - FruLatchOpen(ReadingType.FRULATCHOPEN), FruActivationRequested(ReadingType.FRUACTIVATIONREQUESTED), SlotConnectorDeviceInstalled( - ReadingType.SLOTCONNECTORDEVICEINSTALLED), WarmReset(ReadingType.WARMRESET), FruActivationInProgress( - ReadingType.FRUACTIVATIONINPROGRESS), - /** - * Typically, this means that the slot power is off. The Ready for Installation, Ready for Removal, and Slot Power - * states can transition together, depending on the slot implementation. - */ - SlotConnectorReadyForDeviceInstallation(ReadingType.SLOTCONNECTORREADYFORDEVICEINSTALLATION), PxeBootRequested( - ReadingType.PXEBOOTREQUESTED), FruActive(ReadingType.FRUACTIVE), - /** - * An Invalid Username or Password was received during the session establishment process. - */ - InvalidUsernameOrPassword(ReadingType.INVALIDUSERNAMEORPASSWORD), SlotConnectorReadyForDeviceRemoval( - ReadingType.SLOTCONNECTORREADYFORDEVICEREMOVAL), AutomaticBootToDiagnostic( - ReadingType.AUTOMATICBOOTTODIAGNOSTIC), FruDeactivationRequested(ReadingType.FRUDEACTIVATIONREQUESTED), - /** - * A user's access has been disabled due to a series of bad password attempts. This offset can be used in - * conjunction with the Bad Password Threshold option. Refer to the LAN or serial/modem configuration parameter for - * 'Bad Password Threshold' for more information. - */ - InvalidPasswordDisable(ReadingType.INVALIDPASSWORDDISABLE), EntityPresent(ReadingType.ENTITYPRESENT), SlotPowerOff( - ReadingType.SLOTPOWEROFF), SoftwareInitiatedHardReset(ReadingType.SOFTWAREINITIATEDHARDRESET), FruDeactivationInProgress( - ReadingType.FRUDEACTIVATIONINPROGRESS), - /** - * The sensor is known to be in error. It may still be accessible by software. - */ - SensorFailure(ReadingType.SENSORFAILURE), EntityAbsent(ReadingType.ENTITYABSENT), SoftwareInitiatedWarmReset( - ReadingType.SOFTWAREINITIATEDWARMRESET), FruCommunicationLost(ReadingType.FRUCOMMUNICATIONLOST), FruFailure( - ReadingType.FRUFAILURE), SystemRestart(ReadingType.SYSTEMRESTART), StateDeasserted( - ReadingType.STATEDEASSERTED), SystemFirmwareError(ReadingType.SYSTEMFIRMWAREERROR), StateAsserted( - ReadingType.STATEASSERTED), SystemFirmwareHang(ReadingType.SYSTEMFIRMWAREHANG), SystemFirmwareProgress( - ReadingType.SYSTEMFIRMWAREPROGRESS), - /** - * Informational. This does not imply whether the hardware change was successful or not. Only that a change - * occurred. - */ - HardwareChangeDetected(ReadingType.HARDWARECHANGEDETECTED), Frb1BistFailure(ReadingType.FRB1BISTFAILURE), - /** - * Informational. Success or failure not implied. - */ - FirmwareOrSoftwareChangeDetected(ReadingType.FIRMWAREORSOFTWARECHANGEDETECTED), - /** - * Used hang is believed to be due or related to a processor failure. Use System Firmware Progress sensor for other - * BIOS hangs. - */ - Frb2HangInPostFailure(ReadingType.FRB2HANGINPOSTFAILURE), HardwareIncompatibilityDetected( - ReadingType.HARDWAREINCOMPATIBILITYDETECTED), - /** - * CPU didn't start. - */ - Frb3ProcessorStartupFailure(ReadingType.FRB3PROCESSORSTARTUPFAILURE), FirmwareOrSoftwareIncompatibilityDetected( - ReadingType.FIRMWAREORSOFTWAREINCOMPATIBILITYDETECTED), DrivePresence(ReadingType.DRIVEPRESENCE), ConfigurationError( - ReadingType.CONFIGURATIONERROR), InvalidOrUnsupportedHardware(ReadingType.INVALIDORUNSUPPORTEDHARDWARE), DriveFault( - ReadingType.DRIVEFAULT), UncorrectableCpuComplexError(ReadingType.UNCORRECTABLECPUCOMPLEXERROR), InvalidOrUnsupportedFirmwareOrSoftware( - ReadingType.INVALIDORUNSUPPORTEDFIRMWAREORSOFTWARE), PredictiveFailure(ReadingType.PREDICTIVEFAILURE), ProcessorPresenceDetected( - ReadingType.PROCESSORPRESENCEDETECTED), HotSpare(ReadingType.HOTSPARE), ProcessorDisabled( - ReadingType.PROCESSORDISABLED), ConsistencyOrParityCheckInProgress( - ReadingType.CONSISTENCYORPARITYCHECKINPROGRESS), TerminatorPresenceDetected( - ReadingType.TERMINATORPRESENCEDETECTED), SecureModeViolationAttempt(ReadingType.SECUREMODEVIOLATIONATTEMPT), - /** - * System powered up, but normal OS operation has shut down and system is awaiting reset pushbutton, powercycle or - * other external input - */ - OsGracefulStop(ReadingType.OSGRACEFULSTOP), InCriticalArray(ReadingType.INCRITICALARRAY), - /** - * Processor throttling triggered by a hardware-based mechanism operating independent from system software, such as - * automatic thermal throttling or throttling to limit power consumption - */ - ProcessorAutomaticallyThrottled(ReadingType.PROCESSORAUTOMATICALLYTHROTTLED), PreBootUserPasswordViolation( - ReadingType.PREBOOTUSERPASSWORDVIOLATION), - /** - * System graceful power down by OS. - */ - OsGracefulShutdown(ReadingType.OSGRACEFULSHUTDOWN), MachineCheckException(ReadingType.MACHINECHECKEXCEPTION), PreBootSetupPasswordViolation( - ReadingType.PREBOOTSETUPPASSWORDVIOLATION), SoftOsShutdown(ReadingType.SOFTOSSHUTDOWN), PreBootNetworkPasswordViolation( - ReadingType.PREBOOTNETWORKPASSWORDVIOLATION), LANHeartbeatLost(ReadingType.LANHEARTBEATLOST), - /** - * Graceful shutdown request to agent via BMC did not occur due to missing or malfunctioning local agent. - */ - AgentNotResponding(ReadingType.AGENTNOTRESPONDING), OtherPreBootPasswordViolation( - ReadingType.OTHERPREBOOTPASSWORDVIOLATION), LANHeartbeat(ReadingType.LANHEARTBEAT), OutOfBandAccessPasswordViolation( - ReadingType.OUTOFBANDACCESSPASSWORDVIOLATION), Current(ReadingType.CURRENT), - /** - * Device Removed / Device Absent - */ - DeviceAbsent(ReadingType.DEVICEABSENT), Parity(ReadingType.PARITY), - /** - * Device Inserted / Device Present - */ - DevicePresent(ReadingType.DEVICEPRESENT), MemoryScrubFailed(ReadingType.MEMORYSCRUBFAILED), MemoryDeviceDisabled( - ReadingType.MEMORYDEVICEDISABLED), - /** - * Correctable ECC / other correctable memory error logging limit reached - */ - CorrectableEccOtherCorrectableMemoryErrorLoggingLimitReached( - ReadingType.CORRECTABLEECCOTHERCORRECTABLEMEMORYERRORLOGGINGLIMITREACHED), - /** - * Indicates presence of entity associated with the sensor. Typically the entity will be a 'memory module' or other - * entity representing a physically replaceable unit of memory. - */ - MemoryPresenceDetected(ReadingType.MEMORYPRESENCEDETECTED), - /** - * Indicates a memory configuration error for the entity associated with the sensor. This can include when a given - * implementation of the entity is not supported by the system (e.g., when the particular size of the memory module - * is unsupported) or that the entity is part of an unsupported memory configuration (e.g. the configuration is not - * supported because the memory module doesn't match other memory modules) - */ - MemoryConfigurationError(ReadingType.MEMORYCONFIGURATIONERROR), - /** - * Indicates entity associated with the sensor represents a 'spare' unit of memory. - */ - SpareMemoryUnit(ReadingType.SPAREMEMORYUNIT), - /** - * Memory throttling triggered by a hardware-based mechanism operating independent from system software, such as - * automatic thermal throttling or throttling to limit power consumption. - */ - MemoryAutomaticallyThrottled(ReadingType.MEMORYAUTOMATICALLYTHROTTLED), - /** - * Memory device has entered a critical overtemperature state, exceeding specified operating conditions. Memory - * devices in this state may produce errors or become inaccessible. - */ - MemoryCriticalOvertemperature(ReadingType.MEMORYCRITICALOVERTEMPERATURE), SystemReconfigured( - ReadingType.SYSTEMRECONFIGURED), OemSystemBootEvent(ReadingType.OEMSYSTEMBOOTEVENT), ABootCompleted( - ReadingType.ABOOTCOMPLETED), UndeterminedSystemHardwareFailure( - ReadingType.UNDETERMINEDSYSTEMHARDWAREFAILURE), TransitionToRunning(ReadingType.TRANSITIONTORUNNING), CBootCompleted( - ReadingType.CBOOTCOMPLETED), EntryAddedToAuxiliaryLog(ReadingType.ENTRYADDEDTOAUXILIARYLOG), TransitionToInTest( - ReadingType.TRANSITIONTOINTEST), PxeBootCompleted(ReadingType.PXEBOOTCOMPLETED), PefAction( - ReadingType.PEFACTION), TransitionToPowerOff(ReadingType.TRANSITIONTOPOWEROFF), DiagnosticBootCompleted( - ReadingType.DIAGNOSTICBOOTCOMPLETED), - /** - * This event can be used to record when changes are made to the timestamp clock(s) so that relative time - * differences between SEL entries can be determined. - */ - TimestampClockSynch(ReadingType.TIMESTAMPCLOCKSYNCH), TransitionToOnLine(ReadingType.TRANSITIONTOONLINE), CdRomBootCompleted( - ReadingType.CDROMBOOTCOMPLETED), BootSourceSelectionTimeout(ReadingType.BOOTSOURCESELECTIONTIMEOUT), PowerSupplyConfigurationError( - ReadingType.POWERSUPPLYCONFIGURATIONERROR), TransitionToOffLine(ReadingType.TRANSITIONTOOFFLINE), TimerExpired( - ReadingType.TIMEREXPIRED), RomBootCompleted(ReadingType.ROMBOOTCOMPLETED), TransitionToOffDuty( - ReadingType.TRANSITIONTOOFFDUTY), TimerHardReset(ReadingType.TIMERHARDRESET), - /** - * Boot device not specified. - */ - BootCompleted(ReadingType.BOOTCOMPLETED), PredictiveFailureDeasserted(ReadingType.PREDICTIVEFAILUREDEASSERTED), TransitionToDegraded( - ReadingType.TRANSITIONTODEGRADED), TimerPowerDown(ReadingType.TIMERPOWERDOWN), AcpiS5EnteredByOverride( - ReadingType.ACPIS5ENTEREDBYOVERRIDE), LANLeashLost(ReadingType.LANLEASHLOST), Predictive( - ReadingType.PREDICTIVE), TransitionToPowerSave(ReadingType.TRANSITIONTOPOWERSAVE), TimerPowerCycle( - ReadingType.TIMERPOWERCYCLE), AcpiLegacyOnState(ReadingType.ACPILEGACYONSTATE), PowerOffOrDown( - ReadingType.POWEROFFORDOWN), UnauthorizedDock(ReadingType.UNAUTHORIZEDDOCK), InstallError( - ReadingType.INSTALLERROR), AcpiLegacyOffState(ReadingType.ACPILEGACYOFFSTATE), PowerCycle( - ReadingType.POWERCYCLE), - /** - * Supports detection of hot plug fan tampering. - */ - FANAreaIntrusion(ReadingType.FANAREAINTRUSION), - /** - * Indicates that full redundancy has been regained. - */ - FullyRedundant(ReadingType.FULLYREDUNDANT), CableInterconnectConnected(ReadingType.CABLEINTERCONNECTCONNECTED), PowerDown240V( - ReadingType.POWERDOWN240V), - /** - * Entered any non-redundant state, including {@link ReadingType#NonRedundant_InsufficientResources} - */ - RedundancyLost(ReadingType.REDUNDANCYLOST), AcpiUnknown(ReadingType.ACPIUNKNOWN), - /** - * Incorrect cable connected / Incorrect interconnection - */ - CableInterconnectConfigurationError(ReadingType.CABLEINTERCONNECTCONFIGURATIONERROR), InterlockPowerDown( - ReadingType.INTERLOCKPOWERDOWN), - /** - * Redundancy still exists, but at a less than full level. For example, a system has four fans, and can tolerate the - * failure of two of them, and presently one has failed. - */ - RedundancyDegraded(ReadingType.REDUNDANCYDEGRADED), - /** - * Predictive failure. - */ - BatteryLow(ReadingType.BATTERYLOW), - /** - * The power source for the power unit was lost - */ - PowerInputLost(ReadingType.POWERINPUTLOST), - /** - * Redundancy has been lost but unit is functioning with minimum resources needed for 'normal' operation. - */ - NonRedundant_SufficientResourcesFromRedundant(ReadingType.NONREDUNDANT_SUFFICIENTRESOURCESFROMREDUNDANT), BatteryFailed( - ReadingType.BATTERYFAILED), - /** - * Unit did not respond to request to turn on. - */ - PowerUnitSoftPowerControlFailure(ReadingType.POWERUNITSOFTPOWERCONTROLFAILURE), Voltage(ReadingType.VOLTAGE), BatteryPresenceDetected( - ReadingType.BATTERYPRESENCEDETECTED), PowerUnitFailure(ReadingType.POWERUNITFAILURE), PowerUnitPredictiveFailure( - ReadingType.POWERUNITPREDICTIVEFAILURE), BusFatalError(ReadingType.BUSFATALERROR), CorrectableMemoryErrorLoggingDisabled( - ReadingType.CORRECTABLEMEMORYERRORLOGGINGDISABLED), BusDegraded(ReadingType.BUSDEGRADED), EventTypeLoggingDisabled( - ReadingType.EVENTTYPELOGGINGDISABLED), LogAreaReset(ReadingType.LOGAREARESET), TransitionToOK( - ReadingType.TRANSITIONTOOK), AllEventLoggingDisabled(ReadingType.ALLEVENTLOGGINGDISABLED), TransitionToNonCriticalFromOK( - ReadingType.TRANSITIONTONONCRITICALFROMOK), FruServiceRequestButtonPressed( - ReadingType.FRUSERVICEREQUESTBUTTONPRESSED), SelFull(ReadingType.SELFULL), TransitionToCriticalFromLessSevere( - ReadingType.TRANSITIONTOCRITICALFROMLESSSEVERE), SelAlmostFull(ReadingType.SELALMOSTFULL), TransitionToNonRecoverableFromLessSevere( - ReadingType.TRANSITIONTONONRECOVERABLEFROMLESSSEVERE), CorrectableMachineCheckErrorLoggingDisabled( - ReadingType.CORRECTABLEMACHINECHECKERRORLOGGINGDISABLED), TransitionToNonCriticalFromMoreSevere( - ReadingType.TRANSITIONTONONCRITICALFROMMORESEVERE), TransitionToCriticalFromNonRecoverable( - ReadingType.TRANSITIONTOCRITICALFROMNONRECOVERABLE), - /** - * This is typically connected to a switch that becomes asserted to request removal of the device) - */ - SlotConnectorDeviceRemovalRequest(ReadingType.SLOTCONNECTORDEVICEREMOVALREQUEST), TransitionToNonRecoverable( - ReadingType.TRANSITIONTONONRECOVERABLE), EntityDisabled(ReadingType.ENTITYDISABLED), - /** - * This is typically connected to a switch that mechanically enables/disables power to the slot, or locks the slot - * in the 'Ready for Installation / Ready for Removal states' - depending on the slot implementation. The asserted - * state indicates that the lock-out is active. - */ - InterlockAsserted(ReadingType.INTERLOCKASSERTED), Monitor(ReadingType.MONITOR), SlotDisabled( - ReadingType.SLOTDISABLED), SlotHoldsSpareDevice(ReadingType.SLOTHOLDSSPAREDEVICE), PlatformGeneratedPage( - ReadingType.PLATFORMGENERATEDPAGE), PlatformGeneratedLanAlert(ReadingType.PLATFORMGENERATEDLANALERT), PlatformEventTrapGenerated( - ReadingType.PLATFORMEVENTTRAPGENERATED), PlatformGeneratedSnmpTrap(ReadingType.PLATFORMGENERATEDSNMPTRAP), SessionActivated( - ReadingType.SESSIONACTIVATED), - /** - * Sensor access degraded or unavailable. A sensor that is degraded will still return valid results, but may be - * operating with a slower response time, or may not detect certain possible states. A sensor that is unavailable is - * not able to return any results - */ - SensorAccessUnavailable(ReadingType.SENSORACCESSUNAVAILABLE), SessionDeactivated(ReadingType.SESSIONDEACTIVATED), - /** - * Controller access degraded or unavailable. The ability to access the controller has been degraded, or access is - * unavailable, but the party that is doing the monitoring cannot determine which. - */ - ControllerAccessUnavailable(ReadingType.CONTROLLERACCESSUNAVAILABLE), - /** - * Controller cannot be accessed for normal operation because it has been intentionally taken off-line for a - * non-error condition. Note that any commands that are available must function according to specification. - */ - ManagementControllerOffLine(ReadingType.MANAGEMENTCONTROLLEROFFLINE), SuccessfulHardwareChangeDetected( - ReadingType.SUCCESSFULHARDWARECHANGEDETECTED), - /** - * Controller cannot be accessed because of an error condition - */ - ManagementControllerUnavailable(ReadingType.MANAGEMENTCONTROLLERUNAVAILABLE), SuccessfulSoftwareOrFWChangeDetected( - ReadingType.SUCCESSFULSOFTWAREORFWCHANGEDETECTED), InFailedArray(ReadingType.INFAILEDARRAY), RebuildRemapInProgress( - ReadingType.REBUILDREMAPINPROGRESS), CorrectableMachineCheckError(ReadingType.CORRECTABLEMACHINECHECKERROR), RebuildRemapAborted( - ReadingType.REBUILDREMAPABORTED), Ierr(ReadingType.IERR), - /** - * Chip set did not respond to BMC request to change system power state - */ - ChipsetSoftPowerControlFailure(ReadingType.CHIPSETSOFTPOWERCONTROLFAILURE), ProcessorThermalTrip( - ReadingType.PROCESSORTHERMALTRIP), ChipsetThermalTrip(ReadingType.CHIPSETTHERMALTRIP), D0PowerState( - ReadingType.D0POWERSTATE), D1PowerState(ReadingType.D1POWERSTATE), Temperature(ReadingType.TEMPERATURE), D2PowerState( - ReadingType.D2POWERSTATE), D3PowerState(ReadingType.D3POWERSTATE), - /** - * Unexpected error during system startup. Stopped waiting for input or power cycle/reset. - */ - CriticalStopDuringOsLoad(ReadingType.CRITICALSTOPDURINGOSLOAD), - /** - * a.k.a. 'core dump', 'blue screen' - */ - RunTimeCriticalStop(ReadingType.RUNTIMECRITICALSTOP), DeviceDisabled(ReadingType.DEVICEDISABLED), DeviceEnabled( - ReadingType.DEVICEENABLED), - /** - * Correctable ECC / other correctable memory error - */ - CorrectableEcc(ReadingType.CORRECTABLEECC), - /** - * Uncorrectable ECC / other uncorrectable memory error - */ - UncorrectableECC(ReadingType.UNCORRECTABLEECC), LimitNotExceeded(ReadingType.LIMITNOTEXCEEDED), LimitExceeded( - ReadingType.LIMITEXCEEDED), AcpiS0G0Working(ReadingType.ACPIS0G0WORKING), AcpiS1SleepingProcessorContextMaintained( - ReadingType.ACPIS1SLEEPINGPROCESSORCONTEXTMAINTAINED), PowerSupplyPresenceDetected( - ReadingType.POWERSUPPLYPRESENCEDETECTED), AcpiS2SleepingProcessorContextLost( - ReadingType.ACPIS2SLEEPINGPROCESSORCONTEXTLOST), PowerSupplyFailureDetected( - ReadingType.POWERSUPPLYFAILUREDETECTED), TimerInterrupt(ReadingType.TIMERINTERRUPT), AcpiS3SleepingProcessorContextLostMemoryRetained( - ReadingType.ACPIS3SLEEPINGPROCESSORCONTEXTLOSTMEMORYRETAINED), PowerSupplyPredictiveFailure( - ReadingType.POWERSUPPLYPREDICTIVEFAILURE), Fan(ReadingType.FAN), - /** - * Unit has regained minimum resources needed for 'normal' operation. Entered from Non-redundant:Insufficient - * Resources. - */ - NonRedundant_SufficientResourcesFromInsufficientResources( - ReadingType.NONREDUNDANT_SUFFICIENTRESOURCESFROMINSUFFICIENTRESOURCES), AcpiS4NonVolatileSleep( - ReadingType.ACPIS4NONVOLATILESLEEP), PowerSupplyInputLost(ReadingType.POWERSUPPLYINPUTLOST), - /** - * Unit has regained minimum resources needed for 'normal' operation. Entered from Non-redundant:Insufficient - * Resources. - */ - NonRedundant_InsufficientResources(ReadingType.NONREDUNDANT_INSUFFICIENTRESOURCES), AcpiS5G2SoftOff( - ReadingType.ACPIS5G2SOFTOFF), PowerSupplyInputLostOrOutOfRange(ReadingType.POWERSUPPLYINPUTLOSTOROUTOFRANGE), - /** - * Unit has lost some redundant resource(s) but is still in a redundant state. Entered by a transition from Fully - * Redundant condition. - */ - RedundancyDegradedFromFullyRedundant(ReadingType.REDUNDANCYDEGRADEDFROMFULLYREDUNDANT), PerformanceMet( - ReadingType.PERFORMANCEMET), AcpiS4S5SoftOffStateUndetermined(ReadingType.ACPIS4S5SOFTOFFSTATEUNDETERMINED), PowerSupplyInputOutOfRange( - ReadingType.POWERSUPPLYINPUTOUTOFRANGE), - /** - * Unit has regained some resource(s) and is redundant but not fully redundant. Entered from - * Non-redundant:Sufficient Resources or Non-redundant:Insufficient Resources. - */ - RedundancyDegradedFromNonRedundant(ReadingType.REDUNDANCYDEGRADEDFROMNONREDUNDANT), PerformanceLags( - ReadingType.PERFORMANCELAGS), AcpiG3MechanicalOff(ReadingType.ACPIG3MECHANICALOFF), AcpiSleepingInS1S2OrS3( - ReadingType.ACPISLEEPINGINS1S2ORS3), AcpiG1Sleeping(ReadingType.ACPIG1SLEEPING), FrontPanelInterrupt( - ReadingType.FRONTPANELINTERRUPT), Informational(ReadingType.INFORMATIONAL), NoBootableMedia( - ReadingType.NOBOOTABLEMEDIA), BusTimeout(ReadingType.BUSTIMEOUT), NonBootableDisketteLeftInDrive( - ReadingType.NONBOOTABLEDISKETTELEFTINDRIVE), IoChannelCheckNmi(ReadingType.IOCHANNELCHECKNMI), PxeServerNotFound( - ReadingType.PXESERVERNOTFOUND), Software(ReadingType.SOFTWARE), InvalidBootSector( - ReadingType.INVALIDBOOTSECTOR), PciPErr(ReadingType.PCIPERR), GeneralChassisIntrusion( - ReadingType.GENERALCHASSISINTRUSION), TransitionToIdle(ReadingType.TRANSITIONTOIDLE), PciSErr( - ReadingType.PCISERR), DriveBayIntrusion(ReadingType.DRIVEBAYINTRUSION), TransitionToActive( - ReadingType.TRANSITIONTOACTIVE), EisaFailSafeTimeout(ReadingType.EISAFAILSAFETIMEOUT), IoCardAreaIntrusion( - ReadingType.IOCARDAREAINTRUSION), TransitionToBusy(ReadingType.TRANSITIONTOBUSY), BusCorrectableError( - ReadingType.BUSCORRECTABLEERROR), ProcessorAreaIntrusion(ReadingType.PROCESSORAREAINTRUSION), BusUncorrectableError( - ReadingType.BUSUNCORRECTABLEERROR), FatalNmi(ReadingType.FATALNMI), PowerButtonPressed( - ReadingType.POWERBUTTONPRESSED), SleepButtonPressed(ReadingType.SLEEPBUTTONPRESSED), FruNotInstalled( - ReadingType.FRUNOTINSTALLED), SlotConnectorFaultStatusAsserted(ReadingType.SLOTCONNECTORFAULTSTATUSASSERTED), PowerUp( - ReadingType.POWERUP), ResetButtonPressed(ReadingType.RESETBUTTONPRESSED), LowerNonCriticalGoingLow( - ReadingType.LOWERNONCRITICALGOINGLOW), LowerNonCriticalGoingHigh(ReadingType.LOWERNONCRITICALGOINGHIGH), LowerCriticalGoingLow( - ReadingType.LOWERCRITICALGOINGLOW), LowerCriticalGoingHigh(ReadingType.LOWERCRITICALGOINGHIGH), LowerNonRecoverableGoingLow( - ReadingType.LOWERNONRECOVERABLEGOINGLOW), LowerNonRecoverableGoingHigh( - ReadingType.LOWERNONRECOVERABLEGOINGHIGH), UpperNonCriticalGoingLow(ReadingType.UPPERNONCRITICALGOINGLOW), UpperNonCriticalGoingHigh( - ReadingType.UPPERNONCRITICALGOINGHIGH), UpperCriticalGoingLow(ReadingType.UPPERCRITICALGOINGLOW), UpperCriticalGoingHigh( - ReadingType.UPPERCRITICALGOINGHIGH), UpperNonRecoverableGoingLow(ReadingType.UPPERNONRECOVERABLEGOINGLOW), UpperNonRecoverableGoingHigh( - ReadingType.UPPERNONRECOVERABLEGOINGHIGH), UnknownOEMEvent(ReadingType.UNKNOWNOEM), CoolingDevice( - ReadingType.COOLINGDEVICE), OtherUnitsBasedSensor(ReadingType.OTHERUNITSBASEDSENSOR), PostMemoryResize( - ReadingType.POSTMEMORYRESIZE), ModuleBoard(ReadingType.MODULEBOARD), MicrocontrollerCoprocessor( - ReadingType.MICROCONTROLLERCOPROCESSOR), AddInCard(ReadingType.ADDINCARD), Chassis(ReadingType.CHASSIS), OtherFru( - ReadingType.OTHERFRU), Terminator(ReadingType.TERMINATOR), MonitorAsicIc(ReadingType.MONITORASICIC), Unknown( - ReadingType.UNKNOWN), ; - private static final int LOWERNONCRITICALGOINGLOW = 256; + /** + * FRU in standby or 'hot spare' state. + */ + FruInactive(ReadingType.FRUINACTIVE), + SlotConnectorIdentifyStatusAsserted( + ReadingType.SLOTCONNECTORIDENTIFYSTATUSASSERTED), + HardReset(ReadingType.HARDRESET), + /** + * Switch indicating FRU latch is in 'unlatched' position and FRU is mechanically removable + */ + FruLatchOpen(ReadingType.FRULATCHOPEN), + FruActivationRequested(ReadingType.FRUACTIVATIONREQUESTED), + SlotConnectorDeviceInstalled( + ReadingType.SLOTCONNECTORDEVICEINSTALLED), + WarmReset(ReadingType.WARMRESET), + FruActivationInProgress( + ReadingType.FRUACTIVATIONINPROGRESS), + /** + * Typically, this means that the slot power is off. The Ready for Installation, Ready for Removal, and Slot Power + * states can transition together, depending on the slot implementation. + */ + SlotConnectorReadyForDeviceInstallation(ReadingType.SLOTCONNECTORREADYFORDEVICEINSTALLATION), + PxeBootRequested( + ReadingType.PXEBOOTREQUESTED), + FruActive(ReadingType.FRUACTIVE), + /** + * An Invalid Username or Password was received during the session establishment process. + */ + InvalidUsernameOrPassword(ReadingType.INVALIDUSERNAMEORPASSWORD), + SlotConnectorReadyForDeviceRemoval( + ReadingType.SLOTCONNECTORREADYFORDEVICEREMOVAL), + AutomaticBootToDiagnostic( + ReadingType.AUTOMATICBOOTTODIAGNOSTIC), + FruDeactivationRequested(ReadingType.FRUDEACTIVATIONREQUESTED), + /** + * A user's access has been disabled due to a series of bad password attempts. This offset can be used in + * conjunction with the Bad Password Threshold option. Refer to the LAN or serial/modem configuration parameter for + * 'Bad Password Threshold' for more information. + */ + InvalidPasswordDisable(ReadingType.INVALIDPASSWORDDISABLE), + EntityPresent(ReadingType.ENTITYPRESENT), + SlotPowerOff( + ReadingType.SLOTPOWEROFF), + SoftwareInitiatedHardReset(ReadingType.SOFTWAREINITIATEDHARDRESET), + FruDeactivationInProgress( + ReadingType.FRUDEACTIVATIONINPROGRESS), + /** + * The sensor is known to be in error. It may still be accessible by software. + */ + SensorFailure(ReadingType.SENSORFAILURE), + EntityAbsent(ReadingType.ENTITYABSENT), + SoftwareInitiatedWarmReset( + ReadingType.SOFTWAREINITIATEDWARMRESET), + FruCommunicationLost(ReadingType.FRUCOMMUNICATIONLOST), + FruFailure( + ReadingType.FRUFAILURE), + SystemRestart(ReadingType.SYSTEMRESTART), + StateDeasserted( + ReadingType.STATEDEASSERTED), + SystemFirmwareError(ReadingType.SYSTEMFIRMWAREERROR), + StateAsserted( + ReadingType.STATEASSERTED), + SystemFirmwareHang(ReadingType.SYSTEMFIRMWAREHANG), + SystemFirmwareProgress( + ReadingType.SYSTEMFIRMWAREPROGRESS), + /** + * Informational. This does not imply whether the hardware change was successful or not. Only that a change + * occurred. + */ + HardwareChangeDetected(ReadingType.HARDWARECHANGEDETECTED), + Frb1BistFailure(ReadingType.FRB1BISTFAILURE), + /** + * Informational. Success or failure not implied. + */ + FirmwareOrSoftwareChangeDetected(ReadingType.FIRMWAREORSOFTWARECHANGEDETECTED), + /** + * Used hang is believed to be due or related to a processor failure. Use System Firmware Progress sensor for other + * BIOS hangs. + */ + Frb2HangInPostFailure(ReadingType.FRB2HANGINPOSTFAILURE), + HardwareIncompatibilityDetected( + ReadingType.HARDWAREINCOMPATIBILITYDETECTED), + /** + * CPU didn't start. + */ + Frb3ProcessorStartupFailure(ReadingType.FRB3PROCESSORSTARTUPFAILURE), + FirmwareOrSoftwareIncompatibilityDetected( + ReadingType.FIRMWAREORSOFTWAREINCOMPATIBILITYDETECTED), + DrivePresence(ReadingType.DRIVEPRESENCE), + ConfigurationError( + ReadingType.CONFIGURATIONERROR), + InvalidOrUnsupportedHardware(ReadingType.INVALIDORUNSUPPORTEDHARDWARE), + DriveFault( + ReadingType.DRIVEFAULT), + UncorrectableCpuComplexError(ReadingType.UNCORRECTABLECPUCOMPLEXERROR), + InvalidOrUnsupportedFirmwareOrSoftware( + ReadingType.INVALIDORUNSUPPORTEDFIRMWAREORSOFTWARE), + PredictiveFailure(ReadingType.PREDICTIVEFAILURE), + ProcessorPresenceDetected( + ReadingType.PROCESSORPRESENCEDETECTED), + HotSpare(ReadingType.HOTSPARE), + ProcessorDisabled( + ReadingType.PROCESSORDISABLED), + ConsistencyOrParityCheckInProgress( + ReadingType.CONSISTENCYORPARITYCHECKINPROGRESS), + TerminatorPresenceDetected( + ReadingType.TERMINATORPRESENCEDETECTED), + SecureModeViolationAttempt(ReadingType.SECUREMODEVIOLATIONATTEMPT), + /** + * System powered up, but normal OS operation has shut down and system is awaiting reset pushbutton, powercycle or + * other external input + */ + OsGracefulStop(ReadingType.OSGRACEFULSTOP), + InCriticalArray(ReadingType.INCRITICALARRAY), + /** + * Processor throttling triggered by a hardware-based mechanism operating independent from system software, such as + * automatic thermal throttling or throttling to limit power consumption + */ + ProcessorAutomaticallyThrottled(ReadingType.PROCESSORAUTOMATICALLYTHROTTLED), + PreBootUserPasswordViolation( + ReadingType.PREBOOTUSERPASSWORDVIOLATION), + /** + * System graceful power down by OS. + */ + OsGracefulShutdown(ReadingType.OSGRACEFULSHUTDOWN), + MachineCheckException(ReadingType.MACHINECHECKEXCEPTION), + PreBootSetupPasswordViolation( + ReadingType.PREBOOTSETUPPASSWORDVIOLATION), + SoftOsShutdown(ReadingType.SOFTOSSHUTDOWN), + PreBootNetworkPasswordViolation( + ReadingType.PREBOOTNETWORKPASSWORDVIOLATION), + LANHeartbeatLost(ReadingType.LANHEARTBEATLOST), + /** + * Graceful shutdown request to agent via BMC did not occur due to missing or malfunctioning local agent. + */ + AgentNotResponding(ReadingType.AGENTNOTRESPONDING), + OtherPreBootPasswordViolation( + ReadingType.OTHERPREBOOTPASSWORDVIOLATION), + LANHeartbeat(ReadingType.LANHEARTBEAT), + OutOfBandAccessPasswordViolation( + ReadingType.OUTOFBANDACCESSPASSWORDVIOLATION), + Current(ReadingType.CURRENT), + /** + * Device Removed / Device Absent + */ + DeviceAbsent(ReadingType.DEVICEABSENT), + Parity(ReadingType.PARITY), + /** + * Device Inserted / Device Present + */ + DevicePresent(ReadingType.DEVICEPRESENT), + MemoryScrubFailed(ReadingType.MEMORYSCRUBFAILED), + MemoryDeviceDisabled( + ReadingType.MEMORYDEVICEDISABLED), + /** + * Correctable ECC / other correctable memory error logging limit reached + */ + CorrectableEccOtherCorrectableMemoryErrorLoggingLimitReached( + ReadingType.CORRECTABLEECCOTHERCORRECTABLEMEMORYERRORLOGGINGLIMITREACHED), + /** + * Indicates presence of entity associated with the sensor. Typically the entity will be a 'memory module' or other + * entity representing a physically replaceable unit of memory. + */ + MemoryPresenceDetected(ReadingType.MEMORYPRESENCEDETECTED), + /** + * Indicates a memory configuration error for the entity associated with the sensor. This can include when a given + * implementation of the entity is not supported by the system (e.g., when the particular size of the memory module + * is unsupported) or that the entity is part of an unsupported memory configuration (e.g. the configuration is not + * supported because the memory module doesn't match other memory modules) + */ + MemoryConfigurationError(ReadingType.MEMORYCONFIGURATIONERROR), + /** + * Indicates entity associated with the sensor represents a 'spare' unit of memory. + */ + SpareMemoryUnit(ReadingType.SPAREMEMORYUNIT), + /** + * Memory throttling triggered by a hardware-based mechanism operating independent from system software, such as + * automatic thermal throttling or throttling to limit power consumption. + */ + MemoryAutomaticallyThrottled(ReadingType.MEMORYAUTOMATICALLYTHROTTLED), + /** + * Memory device has entered a critical overtemperature state, exceeding specified operating conditions. Memory + * devices in this state may produce errors or become inaccessible. + */ + MemoryCriticalOvertemperature(ReadingType.MEMORYCRITICALOVERTEMPERATURE), + SystemReconfigured( + ReadingType.SYSTEMRECONFIGURED), + OemSystemBootEvent(ReadingType.OEMSYSTEMBOOTEVENT), + ABootCompleted( + ReadingType.ABOOTCOMPLETED), + UndeterminedSystemHardwareFailure( + ReadingType.UNDETERMINEDSYSTEMHARDWAREFAILURE), + TransitionToRunning(ReadingType.TRANSITIONTORUNNING), + CBootCompleted( + ReadingType.CBOOTCOMPLETED), + EntryAddedToAuxiliaryLog(ReadingType.ENTRYADDEDTOAUXILIARYLOG), + TransitionToInTest( + ReadingType.TRANSITIONTOINTEST), + PxeBootCompleted(ReadingType.PXEBOOTCOMPLETED), + PefAction( + ReadingType.PEFACTION), + TransitionToPowerOff(ReadingType.TRANSITIONTOPOWEROFF), + DiagnosticBootCompleted( + ReadingType.DIAGNOSTICBOOTCOMPLETED), + /** + * This event can be used to record when changes are made to the timestamp clock(s) so that relative time + * differences between SEL entries can be determined. + */ + TimestampClockSynch(ReadingType.TIMESTAMPCLOCKSYNCH), + TransitionToOnLine(ReadingType.TRANSITIONTOONLINE), + CdRomBootCompleted( + ReadingType.CDROMBOOTCOMPLETED), + BootSourceSelectionTimeout(ReadingType.BOOTSOURCESELECTIONTIMEOUT), + PowerSupplyConfigurationError( + ReadingType.POWERSUPPLYCONFIGURATIONERROR), + TransitionToOffLine(ReadingType.TRANSITIONTOOFFLINE), + TimerExpired( + ReadingType.TIMEREXPIRED), + RomBootCompleted(ReadingType.ROMBOOTCOMPLETED), + TransitionToOffDuty( + ReadingType.TRANSITIONTOOFFDUTY), + TimerHardReset(ReadingType.TIMERHARDRESET), + /** + * Boot device not specified. + */ + BootCompleted(ReadingType.BOOTCOMPLETED), + PredictiveFailureDeasserted(ReadingType.PREDICTIVEFAILUREDEASSERTED), + TransitionToDegraded( + ReadingType.TRANSITIONTODEGRADED), + TimerPowerDown(ReadingType.TIMERPOWERDOWN), + AcpiS5EnteredByOverride( + ReadingType.ACPIS5ENTEREDBYOVERRIDE), + LANLeashLost(ReadingType.LANLEASHLOST), + Predictive( + ReadingType.PREDICTIVE), + TransitionToPowerSave(ReadingType.TRANSITIONTOPOWERSAVE), + TimerPowerCycle( + ReadingType.TIMERPOWERCYCLE), + AcpiLegacyOnState(ReadingType.ACPILEGACYONSTATE), + PowerOffOrDown( + ReadingType.POWEROFFORDOWN), + UnauthorizedDock(ReadingType.UNAUTHORIZEDDOCK), + InstallError( + ReadingType.INSTALLERROR), + AcpiLegacyOffState(ReadingType.ACPILEGACYOFFSTATE), + PowerCycle( + ReadingType.POWERCYCLE), + /** + * Supports detection of hot plug fan tampering. + */ + FANAreaIntrusion(ReadingType.FANAREAINTRUSION), + /** + * Indicates that full redundancy has been regained. + */ + FullyRedundant(ReadingType.FULLYREDUNDANT), + CableInterconnectConnected(ReadingType.CABLEINTERCONNECTCONNECTED), + PowerDown240V( + ReadingType.POWERDOWN240V), + /** + * Entered any non-redundant state, including {@link ReadingType#NonRedundant_InsufficientResources} + */ + RedundancyLost(ReadingType.REDUNDANCYLOST), + AcpiUnknown(ReadingType.ACPIUNKNOWN), + /** + * Incorrect cable connected / Incorrect interconnection + */ + CableInterconnectConfigurationError(ReadingType.CABLEINTERCONNECTCONFIGURATIONERROR), + InterlockPowerDown( + ReadingType.INTERLOCKPOWERDOWN), + /** + * Redundancy still exists, but at a less than full level. For example, a system has four fans, and can tolerate the + * failure of two of them, and presently one has failed. + */ + RedundancyDegraded(ReadingType.REDUNDANCYDEGRADED), + /** + * Predictive failure. + */ + BatteryLow(ReadingType.BATTERYLOW), + /** + * The power source for the power unit was lost + */ + PowerInputLost(ReadingType.POWERINPUTLOST), + /** + * Redundancy has been lost but unit is functioning with minimum resources needed for 'normal' operation. + */ + NonRedundant_SufficientResourcesFromRedundant(ReadingType.NONREDUNDANT_SUFFICIENTRESOURCESFROMREDUNDANT), + BatteryFailed( + ReadingType.BATTERYFAILED), + /** + * Unit did not respond to request to turn on. + */ + PowerUnitSoftPowerControlFailure(ReadingType.POWERUNITSOFTPOWERCONTROLFAILURE), + Voltage(ReadingType.VOLTAGE), + BatteryPresenceDetected( + ReadingType.BATTERYPRESENCEDETECTED), + PowerUnitFailure(ReadingType.POWERUNITFAILURE), + PowerUnitPredictiveFailure( + ReadingType.POWERUNITPREDICTIVEFAILURE), + BusFatalError(ReadingType.BUSFATALERROR), + CorrectableMemoryErrorLoggingDisabled( + ReadingType.CORRECTABLEMEMORYERRORLOGGINGDISABLED), + BusDegraded(ReadingType.BUSDEGRADED), + EventTypeLoggingDisabled( + ReadingType.EVENTTYPELOGGINGDISABLED), + LogAreaReset(ReadingType.LOGAREARESET), + TransitionToOK( + ReadingType.TRANSITIONTOOK), + AllEventLoggingDisabled(ReadingType.ALLEVENTLOGGINGDISABLED), + TransitionToNonCriticalFromOK( + ReadingType.TRANSITIONTONONCRITICALFROMOK), + FruServiceRequestButtonPressed( + ReadingType.FRUSERVICEREQUESTBUTTONPRESSED), + SelFull(ReadingType.SELFULL), + TransitionToCriticalFromLessSevere( + ReadingType.TRANSITIONTOCRITICALFROMLESSSEVERE), + SelAlmostFull(ReadingType.SELALMOSTFULL), + TransitionToNonRecoverableFromLessSevere( + ReadingType.TRANSITIONTONONRECOVERABLEFROMLESSSEVERE), + CorrectableMachineCheckErrorLoggingDisabled( + ReadingType.CORRECTABLEMACHINECHECKERRORLOGGINGDISABLED), + TransitionToNonCriticalFromMoreSevere( + ReadingType.TRANSITIONTONONCRITICALFROMMORESEVERE), + TransitionToCriticalFromNonRecoverable( + ReadingType.TRANSITIONTOCRITICALFROMNONRECOVERABLE), + /** + * This is typically connected to a switch that becomes asserted to request removal of the device) + */ + SlotConnectorDeviceRemovalRequest(ReadingType.SLOTCONNECTORDEVICEREMOVALREQUEST), + TransitionToNonRecoverable( + ReadingType.TRANSITIONTONONRECOVERABLE), + EntityDisabled(ReadingType.ENTITYDISABLED), + /** + * This is typically connected to a switch that mechanically enables/disables power to the slot, or locks the slot + * in the 'Ready for Installation / Ready for Removal states' - depending on the slot implementation. The asserted + * state indicates that the lock-out is active. + */ + InterlockAsserted(ReadingType.INTERLOCKASSERTED), + Monitor(ReadingType.MONITOR), + SlotDisabled( + ReadingType.SLOTDISABLED), + SlotHoldsSpareDevice(ReadingType.SLOTHOLDSSPAREDEVICE), + PlatformGeneratedPage( + ReadingType.PLATFORMGENERATEDPAGE), + PlatformGeneratedLanAlert(ReadingType.PLATFORMGENERATEDLANALERT), + PlatformEventTrapGenerated( + ReadingType.PLATFORMEVENTTRAPGENERATED), + PlatformGeneratedSnmpTrap(ReadingType.PLATFORMGENERATEDSNMPTRAP), + SessionActivated( + ReadingType.SESSIONACTIVATED), + /** + * Sensor access degraded or unavailable. A sensor that is degraded will still return valid results, but may be + * operating with a slower response time, or may not detect certain possible states. A sensor that is unavailable is + * not able to return any results + */ + SensorAccessUnavailable(ReadingType.SENSORACCESSUNAVAILABLE), + SessionDeactivated(ReadingType.SESSIONDEACTIVATED), + /** + * Controller access degraded or unavailable. The ability to access the controller has been degraded, or access is + * unavailable, but the party that is doing the monitoring cannot determine which. + */ + ControllerAccessUnavailable(ReadingType.CONTROLLERACCESSUNAVAILABLE), + /** + * Controller cannot be accessed for normal operation because it has been intentionally taken off-line for a + * non-error condition. Note that any commands that are available must function according to specification. + */ + ManagementControllerOffLine(ReadingType.MANAGEMENTCONTROLLEROFFLINE), + SuccessfulHardwareChangeDetected( + ReadingType.SUCCESSFULHARDWARECHANGEDETECTED), + /** + * Controller cannot be accessed because of an error condition + */ + ManagementControllerUnavailable(ReadingType.MANAGEMENTCONTROLLERUNAVAILABLE), + SuccessfulSoftwareOrFWChangeDetected( + ReadingType.SUCCESSFULSOFTWAREORFWCHANGEDETECTED), + InFailedArray(ReadingType.INFAILEDARRAY), + RebuildRemapInProgress( + ReadingType.REBUILDREMAPINPROGRESS), + CorrectableMachineCheckError(ReadingType.CORRECTABLEMACHINECHECKERROR), + RebuildRemapAborted( + ReadingType.REBUILDREMAPABORTED), + Ierr(ReadingType.IERR), + /** + * Chip set did not respond to BMC request to change system power state + */ + ChipsetSoftPowerControlFailure(ReadingType.CHIPSETSOFTPOWERCONTROLFAILURE), + ProcessorThermalTrip( + ReadingType.PROCESSORTHERMALTRIP), + ChipsetThermalTrip(ReadingType.CHIPSETTHERMALTRIP), + D0PowerState( + ReadingType.D0POWERSTATE), + D1PowerState(ReadingType.D1POWERSTATE), + Temperature(ReadingType.TEMPERATURE), + D2PowerState( + ReadingType.D2POWERSTATE), + D3PowerState(ReadingType.D3POWERSTATE), + /** + * Unexpected error during system startup. Stopped waiting for input or power cycle/reset. + */ + CriticalStopDuringOsLoad(ReadingType.CRITICALSTOPDURINGOSLOAD), + /** + * a.k.a. 'core dump', 'blue screen' + */ + RunTimeCriticalStop(ReadingType.RUNTIMECRITICALSTOP), + DeviceDisabled(ReadingType.DEVICEDISABLED), + DeviceEnabled( + ReadingType.DEVICEENABLED), + /** + * Correctable ECC / other correctable memory error + */ + CorrectableEcc(ReadingType.CORRECTABLEECC), + /** + * Uncorrectable ECC / other uncorrectable memory error + */ + UncorrectableECC(ReadingType.UNCORRECTABLEECC), + LimitNotExceeded(ReadingType.LIMITNOTEXCEEDED), + LimitExceeded( + ReadingType.LIMITEXCEEDED), + AcpiS0G0Working(ReadingType.ACPIS0G0WORKING), + AcpiS1SleepingProcessorContextMaintained( + ReadingType.ACPIS1SLEEPINGPROCESSORCONTEXTMAINTAINED), + PowerSupplyPresenceDetected( + ReadingType.POWERSUPPLYPRESENCEDETECTED), + AcpiS2SleepingProcessorContextLost( + ReadingType.ACPIS2SLEEPINGPROCESSORCONTEXTLOST), + PowerSupplyFailureDetected( + ReadingType.POWERSUPPLYFAILUREDETECTED), + TimerInterrupt(ReadingType.TIMERINTERRUPT), + AcpiS3SleepingProcessorContextLostMemoryRetained( + ReadingType.ACPIS3SLEEPINGPROCESSORCONTEXTLOSTMEMORYRETAINED), + PowerSupplyPredictiveFailure( + ReadingType.POWERSUPPLYPREDICTIVEFAILURE), + Fan(ReadingType.FAN), + /** + * Unit has regained minimum resources needed for 'normal' operation. Entered from Non-redundant:Insufficient + * Resources. + */ + NonRedundant_SufficientResourcesFromInsufficientResources( + ReadingType.NONREDUNDANT_SUFFICIENTRESOURCESFROMINSUFFICIENTRESOURCES), + AcpiS4NonVolatileSleep( + ReadingType.ACPIS4NONVOLATILESLEEP), + PowerSupplyInputLost(ReadingType.POWERSUPPLYINPUTLOST), + /** + * Unit has regained minimum resources needed for 'normal' operation. Entered from Non-redundant:Insufficient + * Resources. + */ + NonRedundant_InsufficientResources(ReadingType.NONREDUNDANT_INSUFFICIENTRESOURCES), + AcpiS5G2SoftOff( + ReadingType.ACPIS5G2SOFTOFF), + PowerSupplyInputLostOrOutOfRange(ReadingType.POWERSUPPLYINPUTLOSTOROUTOFRANGE), + /** + * Unit has lost some redundant resource(s) but is still in a redundant state. Entered by a transition from Fully + * Redundant condition. + */ + RedundancyDegradedFromFullyRedundant(ReadingType.REDUNDANCYDEGRADEDFROMFULLYREDUNDANT), + PerformanceMet( + ReadingType.PERFORMANCEMET), + AcpiS4S5SoftOffStateUndetermined(ReadingType.ACPIS4S5SOFTOFFSTATEUNDETERMINED), + PowerSupplyInputOutOfRange( + ReadingType.POWERSUPPLYINPUTOUTOFRANGE), + /** + * Unit has regained some resource(s) and is redundant but not fully redundant. Entered from + * Non-redundant:Sufficient Resources or Non-redundant:Insufficient Resources. + */ + RedundancyDegradedFromNonRedundant(ReadingType.REDUNDANCYDEGRADEDFROMNONREDUNDANT), + PerformanceLags( + ReadingType.PERFORMANCELAGS), + AcpiG3MechanicalOff(ReadingType.ACPIG3MECHANICALOFF), + AcpiSleepingInS1S2OrS3( + ReadingType.ACPISLEEPINGINS1S2ORS3), + AcpiG1Sleeping(ReadingType.ACPIG1SLEEPING), + FrontPanelInterrupt( + ReadingType.FRONTPANELINTERRUPT), + Informational(ReadingType.INFORMATIONAL), + NoBootableMedia( + ReadingType.NOBOOTABLEMEDIA), + BusTimeout(ReadingType.BUSTIMEOUT), + NonBootableDisketteLeftInDrive( + ReadingType.NONBOOTABLEDISKETTELEFTINDRIVE), + IoChannelCheckNmi(ReadingType.IOCHANNELCHECKNMI), + PxeServerNotFound( + ReadingType.PXESERVERNOTFOUND), + Software(ReadingType.SOFTWARE), + InvalidBootSector( + ReadingType.INVALIDBOOTSECTOR), + PciPErr(ReadingType.PCIPERR), + GeneralChassisIntrusion( + ReadingType.GENERALCHASSISINTRUSION), + TransitionToIdle(ReadingType.TRANSITIONTOIDLE), + PciSErr( + ReadingType.PCISERR), + DriveBayIntrusion(ReadingType.DRIVEBAYINTRUSION), + TransitionToActive( + ReadingType.TRANSITIONTOACTIVE), + EisaFailSafeTimeout(ReadingType.EISAFAILSAFETIMEOUT), + IoCardAreaIntrusion( + ReadingType.IOCARDAREAINTRUSION), + TransitionToBusy(ReadingType.TRANSITIONTOBUSY), + BusCorrectableError( + ReadingType.BUSCORRECTABLEERROR), + ProcessorAreaIntrusion(ReadingType.PROCESSORAREAINTRUSION), + BusUncorrectableError( + ReadingType.BUSUNCORRECTABLEERROR), + FatalNmi(ReadingType.FATALNMI), + PowerButtonPressed( + ReadingType.POWERBUTTONPRESSED), + SleepButtonPressed(ReadingType.SLEEPBUTTONPRESSED), + FruNotInstalled( + ReadingType.FRUNOTINSTALLED), + SlotConnectorFaultStatusAsserted(ReadingType.SLOTCONNECTORFAULTSTATUSASSERTED), + PowerUp( + ReadingType.POWERUP), + ResetButtonPressed(ReadingType.RESETBUTTONPRESSED), + LowerNonCriticalGoingLow( + ReadingType.LOWERNONCRITICALGOINGLOW), + LowerNonCriticalGoingHigh(ReadingType.LOWERNONCRITICALGOINGHIGH), + LowerCriticalGoingLow( + ReadingType.LOWERCRITICALGOINGLOW), + LowerCriticalGoingHigh(ReadingType.LOWERCRITICALGOINGHIGH), + LowerNonRecoverableGoingLow( + ReadingType.LOWERNONRECOVERABLEGOINGLOW), + LowerNonRecoverableGoingHigh( + ReadingType.LOWERNONRECOVERABLEGOINGHIGH), + UpperNonCriticalGoingLow(ReadingType.UPPERNONCRITICALGOINGLOW), + UpperNonCriticalGoingHigh( + ReadingType.UPPERNONCRITICALGOINGHIGH), + UpperCriticalGoingLow(ReadingType.UPPERCRITICALGOINGLOW), + UpperCriticalGoingHigh( + ReadingType.UPPERCRITICALGOINGHIGH), + UpperNonRecoverableGoingLow(ReadingType.UPPERNONRECOVERABLEGOINGLOW), + UpperNonRecoverableGoingHigh( + ReadingType.UPPERNONRECOVERABLEGOINGHIGH), + UnknownOEMEvent(ReadingType.UNKNOWNOEM), + CoolingDevice( + ReadingType.COOLINGDEVICE), + OtherUnitsBasedSensor(ReadingType.OTHERUNITSBASEDSENSOR), + PostMemoryResize( + ReadingType.POSTMEMORYRESIZE), + ModuleBoard(ReadingType.MODULEBOARD), + MicrocontrollerCoprocessor( + ReadingType.MICROCONTROLLERCOPROCESSOR), + AddInCard(ReadingType.ADDINCARD), + Chassis(ReadingType.CHASSIS), + OtherFru( + ReadingType.OTHERFRU), + Terminator(ReadingType.TERMINATOR), + MonitorAsicIc(ReadingType.MONITORASICIC), + Unknown( + ReadingType.UNKNOWN),; - private static final int LOWERNONCRITICALGOINGHIGH = 257; + private static final int LOWERNONCRITICALGOINGLOW = 256; - private static final int LOWERCRITICALGOINGLOW = 258; + private static final int LOWERNONCRITICALGOINGHIGH = 257; - private static final int LOWERCRITICALGOINGHIGH = 259; + private static final int LOWERCRITICALGOINGLOW = 258; - private static final int LOWERNONRECOVERABLEGOINGLOW = 260; + private static final int LOWERCRITICALGOINGHIGH = 259; - private static final int LOWERNONRECOVERABLEGOINGHIGH = 261; + private static final int LOWERNONRECOVERABLEGOINGLOW = 260; - private static final int UPPERNONCRITICALGOINGLOW = 262; + private static final int LOWERNONRECOVERABLEGOINGHIGH = 261; - private static final int UPPERNONCRITICALGOINGHIGH = 263; + private static final int UPPERNONCRITICALGOINGLOW = 262; - private static final int UPPERCRITICALGOINGLOW = 264; + private static final int UPPERNONCRITICALGOINGHIGH = 263; - private static final int UPPERCRITICALGOINGHIGH = 265; + private static final int UPPERCRITICALGOINGLOW = 264; - private static final int UPPERNONRECOVERABLEGOINGLOW = 266; + private static final int UPPERCRITICALGOINGHIGH = 265; - private static final int UPPERNONRECOVERABLEGOINGHIGH = 267; + private static final int UPPERNONRECOVERABLEGOINGLOW = 266; - private static final int FRUINACTIVE = 2912001; + private static final int UPPERNONRECOVERABLEGOINGHIGH = 267; - private static final int SLOTCONNECTORIDENTIFYSTATUSASSERTED = 2191105; + private static final int FRUINACTIVE = 2912001; - private static final int HARDRESET = 1928961; + private static final int SLOTCONNECTORIDENTIFYSTATUSASSERTED = 2191105; - private static final int FRULATCHOPEN = 1339139; + private static final int HARDRESET = 1928961; - private static final int FRUACTIVATIONREQUESTED = 2912002; + private static final int FRULATCHOPEN = 1339139; - private static final int SLOTCONNECTORDEVICEINSTALLED = 2191106; + private static final int FRUACTIVATIONREQUESTED = 2912002; - private static final int WARMRESET = 1928962; + private static final int SLOTCONNECTORDEVICEINSTALLED = 2191106; - private static final int FRUACTIVATIONINPROGRESS = 2912003; + private static final int WARMRESET = 1928962; - private static final int SLOTCONNECTORREADYFORDEVICEINSTALLATION = 2191107; + private static final int FRUACTIVATIONINPROGRESS = 2912003; - private static final int PXEBOOTREQUESTED = 1928963; + private static final int SLOTCONNECTORREADYFORDEVICEINSTALLATION = 2191107; - private static final int FRUACTIVE = 2912004; + private static final int PXEBOOTREQUESTED = 1928963; - private static final int INVALIDUSERNAMEORPASSWORD = 2780930; + private static final int FRUACTIVE = 2912004; - private static final int SLOTCONNECTORREADYFORDEVICEREMOVAL = 2191108; + private static final int INVALIDUSERNAMEORPASSWORD = 2780930; - private static final int AUTOMATICBOOTTODIAGNOSTIC = 1928964; + private static final int SLOTCONNECTORREADYFORDEVICEREMOVAL = 2191108; - private static final int FRUDEACTIVATIONREQUESTED = 2912005; + private static final int AUTOMATICBOOTTODIAGNOSTIC = 1928964; - private static final int INVALIDPASSWORDDISABLE = 2780931; + private static final int FRUDEACTIVATIONREQUESTED = 2912005; - private static final int ENTITYPRESENT = 2453248; + private static final int INVALIDPASSWORDDISABLE = 2780931; - private static final int SLOTPOWEROFF = 2191109; + private static final int ENTITYPRESENT = 2453248; - private static final int SOFTWAREINITIATEDHARDRESET = 1928965; + private static final int SLOTPOWEROFF = 2191109; - private static final int FRUDEACTIVATIONINPROGRESS = 2912006; + private static final int SOFTWAREINITIATEDHARDRESET = 1928965; - private static final int SENSORFAILURE = 2649860; + private static final int FRUDEACTIVATIONINPROGRESS = 2912006; - private static final int ENTITYABSENT = 2453249; + private static final int SENSORFAILURE = 2649860; - private static final int SOFTWAREINITIATEDWARMRESET = 1928966; + private static final int ENTITYABSENT = 2453249; - private static final int FRUCOMMUNICATIONLOST = 2912007; + private static final int SOFTWAREINITIATEDWARMRESET = 1928966; - private static final int FRUFAILURE = 2649861; + private static final int FRUCOMMUNICATIONLOST = 2912007; - private static final int SYSTEMRESTART = 1928967; + private static final int FRUFAILURE = 2649861; - private static final int STATEDEASSERTED = 768; + private static final int SYSTEMRESTART = 1928967; - private static final int SYSTEMFIRMWAREERROR = 1011456; + private static final int STATEDEASSERTED = 768; - private static final int STATEASSERTED = 769; + private static final int SYSTEMFIRMWAREERROR = 1011456; - private static final int SYSTEMFIRMWAREHANG = 1011457; + private static final int STATEASSERTED = 769; - private static final int SYSTEMFIRMWAREPROGRESS = 1011458; + private static final int SYSTEMFIRMWAREHANG = 1011457; - private static final int HARDWARECHANGEDETECTED = 2846464; + private static final int SYSTEMFIRMWAREPROGRESS = 1011458; - private static final int FRB1BISTFAILURE = 487170; + private static final int HARDWARECHANGEDETECTED = 2846464; - private static final int FIRMWAREORSOFTWARECHANGEDETECTED = 2846465; + private static final int FRB1BISTFAILURE = 487170; - private static final int FRB2HANGINPOSTFAILURE = 487171; + private static final int FIRMWAREORSOFTWARECHANGEDETECTED = 2846465; - private static final int HARDWAREINCOMPATIBILITYDETECTED = 2846466; + private static final int FRB2HANGINPOSTFAILURE = 487171; - private static final int FRB3PROCESSORSTARTUPFAILURE = 487172; + private static final int HARDWAREINCOMPATIBILITYDETECTED = 2846466; - private static final int FIRMWAREORSOFTWAREINCOMPATIBILITYDETECTED = 2846467; + private static final int FRB3PROCESSORSTARTUPFAILURE = 487172; - private static final int DRIVEPRESENCE = 880384; + private static final int FIRMWAREORSOFTWAREINCOMPATIBILITYDETECTED = 2846467; - private static final int CONFIGURATIONERROR = 487173; + private static final int DRIVEPRESENCE = 880384; - private static final int INVALIDORUNSUPPORTEDHARDWARE = 2846468; + private static final int CONFIGURATIONERROR = 487173; - private static final int DRIVEFAULT = 880385; + private static final int INVALIDORUNSUPPORTEDHARDWARE = 2846468; - private static final int UNCORRECTABLECPUCOMPLEXERROR = 487174; + private static final int DRIVEFAULT = 880385; - private static final int INVALIDORUNSUPPORTEDFIRMWAREORSOFTWARE = 2846469; + private static final int UNCORRECTABLECPUCOMPLEXERROR = 487174; - private static final int PREDICTIVEFAILURE = 880386; + private static final int INVALIDORUNSUPPORTEDFIRMWAREORSOFTWARE = 2846469; - private static final int PROCESSORPRESENCEDETECTED = 487175; + private static final int PREDICTIVEFAILURE = 880386; - private static final int HOTSPARE = 880387; + private static final int PROCESSORPRESENCEDETECTED = 487175; - private static final int PROCESSORDISABLED = 487176; + private static final int HOTSPARE = 880387; - private static final int CONSISTENCYORPARITYCHECKINPROGRESS = 880388; + private static final int PROCESSORDISABLED = 487176; - private static final int TERMINATORPRESENCEDETECTED = 487177; + private static final int CONSISTENCYORPARITYCHECKINPROGRESS = 880388; - private static final int SECUREMODEVIOLATIONATTEMPT = 421632; + private static final int TERMINATORPRESENCEDETECTED = 487177; - private static final int OSGRACEFULSTOP = 2125570; + private static final int SECUREMODEVIOLATIONATTEMPT = 421632; - private static final int INCRITICALARRAY = 880389; + private static final int OSGRACEFULSTOP = 2125570; - private static final int PROCESSORAUTOMATICALLYTHROTTLED = 487178; + private static final int INCRITICALARRAY = 880389; - private static final int PREBOOTUSERPASSWORDVIOLATION = 421633; + private static final int PROCESSORAUTOMATICALLYTHROTTLED = 487178; - private static final int OSGRACEFULSHUTDOWN = 2125571; + private static final int PREBOOTUSERPASSWORDVIOLATION = 421633; - private static final int MACHINECHECKEXCEPTION = 487179; + private static final int OSGRACEFULSHUTDOWN = 2125571; - private static final int PREBOOTSETUPPASSWORDVIOLATION = 421634; + private static final int MACHINECHECKEXCEPTION = 487179; - private static final int SOFTOSSHUTDOWN = 2125572; + private static final int PREBOOTSETUPPASSWORDVIOLATION = 421634; - private static final int PREBOOTNETWORKPASSWORDVIOLATION = 421635; + private static final int SOFTOSSHUTDOWN = 2125572; - private static final int LANHEARTBEATLOST = 2584320; + private static final int PREBOOTNETWORKPASSWORDVIOLATION = 421635; - private static final int AGENTNOTRESPONDING = 2125573; + private static final int LANHEARTBEATLOST = 2584320; - private static final int OTHERPREBOOTPASSWORDVIOLATION = 421636; + private static final int AGENTNOTRESPONDING = 2125573; - private static final int LANHEARTBEAT = 2584321; + private static final int OTHERPREBOOTPASSWORDVIOLATION = 421636; - private static final int OUTOFBANDACCESSPASSWORDVIOLATION = 421637; + private static final int LANHEARTBEAT = 2584321; - private static final int CURRENT = 225024; + private static final int OUTOFBANDACCESSPASSWORDVIOLATION = 421637; - private static final int DEVICEABSENT = 2048; + private static final int CURRENT = 225024; - private static final int PARITY = 814850; + private static final int DEVICEABSENT = 2048; - private static final int DEVICEPRESENT = 2049; + private static final int PARITY = 814850; - private static final int MEMORYSCRUBFAILED = 814851; + private static final int DEVICEPRESENT = 2049; - private static final int MEMORYDEVICEDISABLED = 814852; + private static final int MEMORYSCRUBFAILED = 814851; - private static final int CORRECTABLEECCOTHERCORRECTABLEMEMORYERRORLOGGINGLIMITREACHED = 814853; + private static final int MEMORYDEVICEDISABLED = 814852; - private static final int MEMORYPRESENCEDETECTED = 814854; + private static final int CORRECTABLEECCOTHERCORRECTABLEMEMORYERRORLOGGINGLIMITREACHED = 814853; - private static final int MEMORYCONFIGURATIONERROR = 814855; + private static final int MEMORYPRESENCEDETECTED = 814854; - private static final int SPAREMEMORYUNIT = 814856; + private static final int MEMORYCONFIGURATIONERROR = 814855; - private static final int MEMORYAUTOMATICALLYTHROTTLED = 814857; + private static final int SPAREMEMORYUNIT = 814856; - private static final int MEMORYCRITICALOVERTEMPERATURE = 814858; + private static final int MEMORYAUTOMATICALLYTHROTTLED = 814857; - private static final int SYSTEMRECONFIGURED = 1208064; + private static final int MEMORYCRITICALOVERTEMPERATURE = 814858; - private static final int OEMSYSTEMBOOTEVENT = 1208065; + private static final int SYSTEMRECONFIGURED = 1208064; - private static final int ABOOTCOMPLETED = 2060032; + private static final int OEMSYSTEMBOOTEVENT = 1208065; - private static final int UNDETERMINEDSYSTEMHARDWAREFAILURE = 1208066; + private static final int ABOOTCOMPLETED = 2060032; - private static final int TRANSITIONTORUNNING = 2560; + private static final int UNDETERMINEDSYSTEMHARDWAREFAILURE = 1208066; - private static final int CBOOTCOMPLETED = 2060033; + private static final int TRANSITIONTORUNNING = 2560; - private static final int ENTRYADDEDTOAUXILIARYLOG = 1208067; + private static final int CBOOTCOMPLETED = 2060033; - private static final int TRANSITIONTOINTEST = 2561; + private static final int ENTRYADDEDTOAUXILIARYLOG = 1208067; - private static final int PXEBOOTCOMPLETED = 2060034; + private static final int TRANSITIONTOINTEST = 2561; - private static final int PEFACTION = 1208068; + private static final int PXEBOOTCOMPLETED = 2060034; - private static final int TRANSITIONTOPOWEROFF = 2562; + private static final int PEFACTION = 1208068; - private static final int DIAGNOSTICBOOTCOMPLETED = 2060035; + private static final int TRANSITIONTOPOWEROFF = 2562; - private static final int TIMESTAMPCLOCKSYNCH = 1208069; + private static final int DIAGNOSTICBOOTCOMPLETED = 2060035; - private static final int TRANSITIONTOONLINE = 2563; + private static final int TIMESTAMPCLOCKSYNCH = 1208069; - private static final int CDROMBOOTCOMPLETED = 2060036; + private static final int TRANSITIONTOONLINE = 2563; - private static final int BOOTSOURCESELECTIONTIMEOUT = 1994500; + private static final int CDROMBOOTCOMPLETED = 2060036; - private static final int POWERSUPPLYCONFIGURATIONERROR = 552710; + private static final int BOOTSOURCESELECTIONTIMEOUT = 1994500; - private static final int TRANSITIONTOOFFLINE = 2564; + private static final int POWERSUPPLYCONFIGURATIONERROR = 552710; - private static final int TIMEREXPIRED = 2322176; + private static final int TRANSITIONTOOFFLINE = 2564; - private static final int ROMBOOTCOMPLETED = 2060037; + private static final int TIMEREXPIRED = 2322176; - private static final int TRANSITIONTOOFFDUTY = 2565; + private static final int ROMBOOTCOMPLETED = 2060037; - private static final int TIMERHARDRESET = 2322177; + private static final int TRANSITIONTOOFFDUTY = 2565; - private static final int BOOTCOMPLETED = 2060038; + private static final int TIMERHARDRESET = 2322177; - private static final int PREDICTIVEFAILUREDEASSERTED = 1024; + private static final int BOOTCOMPLETED = 2060038; - private static final int TRANSITIONTODEGRADED = 2566; + private static final int PREDICTIVEFAILUREDEASSERTED = 1024; - private static final int TIMERPOWERDOWN = 2322178; + private static final int TRANSITIONTODEGRADED = 2566; - private static final int ACPIS5ENTEREDBYOVERRIDE = 2256650; + private static final int TIMERPOWERDOWN = 2322178; - private static final int LANLEASHLOST = 356100; + private static final int ACPIS5ENTEREDBYOVERRIDE = 2256650; - private static final int PREDICTIVE = 1025; + private static final int LANLEASHLOST = 356100; - private static final int TRANSITIONTOPOWERSAVE = 2567; + private static final int PREDICTIVE = 1025; - private static final int TIMERPOWERCYCLE = 2322179; + private static final int TRANSITIONTOPOWERSAVE = 2567; - private static final int ACPILEGACYONSTATE = 2256651; + private static final int TIMERPOWERCYCLE = 2322179; - private static final int POWEROFFORDOWN = 618240; + private static final int ACPILEGACYONSTATE = 2256651; - private static final int UNAUTHORIZEDDOCK = 356101; + private static final int POWEROFFORDOWN = 618240; - private static final int INSTALLERROR = 2568; + private static final int UNAUTHORIZEDDOCK = 356101; - private static final int ACPILEGACYOFFSTATE = 2256652; + private static final int INSTALLERROR = 2568; - private static final int POWERCYCLE = 618241; + private static final int ACPILEGACYOFFSTATE = 2256652; - private static final int FANAREAINTRUSION = 356102; + private static final int POWERCYCLE = 618241; - private static final int FULLYREDUNDANT = 2816; + private static final int FANAREAINTRUSION = 356102; - private static final int CABLEINTERCONNECTCONNECTED = 1797888; + private static final int FULLYREDUNDANT = 2816; - private static final int POWERDOWN240V = 618242; + private static final int CABLEINTERCONNECTCONNECTED = 1797888; - private static final int REDUNDANCYLOST = 2817; + private static final int POWERDOWN240V = 618242; - private static final int ACPIUNKNOWN = 2256654; + private static final int REDUNDANCYLOST = 2817; - private static final int CABLEINTERCONNECTCONFIGURATIONERROR = 1797889; + private static final int ACPIUNKNOWN = 2256654; - private static final int INTERLOCKPOWERDOWN = 618243; + private static final int CABLEINTERCONNECTCONFIGURATIONERROR = 1797889; - private static final int REDUNDANCYDEGRADED = 2818; + private static final int INTERLOCKPOWERDOWN = 618243; - private static final int BATTERYLOW = 2715392; + private static final int REDUNDANCYDEGRADED = 2818; - private static final int POWERINPUTLOST = 618244; + private static final int BATTERYLOW = 2715392; - private static final int NONREDUNDANT_SUFFICIENTRESOURCESFROMREDUNDANT = 2819; + private static final int POWERINPUTLOST = 618244; - private static final int BATTERYFAILED = 2715393; + private static final int NONREDUNDANT_SUFFICIENTRESOURCESFROMREDUNDANT = 2819; - private static final int POWERUNITSOFTPOWERCONTROLFAILURE = 618245; + private static final int BATTERYFAILED = 2715393; - private static final int VOLTAGE = 159488; + private static final int POWERUNITSOFTPOWERCONTROLFAILURE = 618245; - private static final int BATTERYPRESENCEDETECTED = 2715394; + private static final int VOLTAGE = 159488; - private static final int POWERUNITFAILURE = 618246; + private static final int BATTERYPRESENCEDETECTED = 2715394; - private static final int POWERUNITPREDICTIVEFAILURE = 618247; + private static final int POWERUNITFAILURE = 618246; - private static final int BUSFATALERROR = 1273610; + private static final int POWERUNITPREDICTIVEFAILURE = 618247; - private static final int CORRECTABLEMEMORYERRORLOGGINGDISABLED = 1076992; + private static final int BUSFATALERROR = 1273610; - private static final int BUSDEGRADED = 1273611; + private static final int CORRECTABLEMEMORYERRORLOGGINGDISABLED = 1076992; - private static final int EVENTTYPELOGGINGDISABLED = 1076993; + private static final int BUSDEGRADED = 1273611; - private static final int LOGAREARESET = 1076994; + private static final int EVENTTYPELOGGINGDISABLED = 1076993; - private static final int TRANSITIONTOOK = 1792; + private static final int LOGAREARESET = 1076994; - private static final int ALLEVENTLOGGINGDISABLED = 1076995; + private static final int TRANSITIONTOOK = 1792; - private static final int TRANSITIONTONONCRITICALFROMOK = 1793; + private static final int ALLEVENTLOGGINGDISABLED = 1076995; - private static final int FRUSERVICEREQUESTBUTTONPRESSED = 1339140; + private static final int TRANSITIONTONONCRITICALFROMOK = 1793; - private static final int SELFULL = 1076996; + private static final int FRUSERVICEREQUESTBUTTONPRESSED = 1339140; - private static final int TRANSITIONTOCRITICALFROMLESSSEVERE = 1794; + private static final int SELFULL = 1076996; - private static final int SELALMOSTFULL = 1076997; + private static final int TRANSITIONTOCRITICALFROMLESSSEVERE = 1794; - private static final int TRANSITIONTONONRECOVERABLEFROMLESSSEVERE = 1795; + private static final int SELALMOSTFULL = 1076997; - private static final int CORRECTABLEMACHINECHECKERRORLOGGINGDISABLED = 1076998; + private static final int TRANSITIONTONONRECOVERABLEFROMLESSSEVERE = 1795; - private static final int TRANSITIONTONONCRITICALFROMMORESEVERE = 1796; + private static final int CORRECTABLEMACHINECHECKERRORLOGGINGDISABLED = 1076998; - private static final int TRANSITIONTOCRITICALFROMNONRECOVERABLE = 1797; + private static final int TRANSITIONTONONCRITICALFROMMORESEVERE = 1796; - private static final int SLOTCONNECTORDEVICEREMOVALREQUEST = 2191110; + private static final int TRANSITIONTOCRITICALFROMNONRECOVERABLE = 1797; - private static final int TRANSITIONTONONRECOVERABLE = 1798; + private static final int SLOTCONNECTORDEVICEREMOVALREQUEST = 2191110; - private static final int ENTITYDISABLED = 2453250; + private static final int TRANSITIONTONONRECOVERABLE = 1798; - private static final int INTERLOCKASSERTED = 2191111; + private static final int ENTITYDISABLED = 2453250; - private static final int MONITOR = 1799; + private static final int INTERLOCKASSERTED = 2191111; - private static final int SLOTDISABLED = 2191112; + private static final int MONITOR = 1799; - private static final int SLOTHOLDSSPAREDEVICE = 2191113; + private static final int SLOTDISABLED = 2191112; - private static final int PLATFORMGENERATEDPAGE = 2387712; + private static final int SLOTHOLDSSPAREDEVICE = 2191113; - private static final int PLATFORMGENERATEDLANALERT = 2387713; + private static final int PLATFORMGENERATEDPAGE = 2387712; - private static final int PLATFORMEVENTTRAPGENERATED = 2387714; + private static final int PLATFORMGENERATEDLANALERT = 2387713; - private static final int PLATFORMGENERATEDSNMPTRAP = 2387715; + private static final int PLATFORMEVENTTRAPGENERATED = 2387714; - private static final int SESSIONACTIVATED = 2780928; + private static final int PLATFORMGENERATEDSNMPTRAP = 2387715; - private static final int SENSORACCESSUNAVAILABLE = 2649856; + private static final int SESSIONACTIVATED = 2780928; - private static final int SESSIONDEACTIVATED = 2780929; + private static final int SENSORACCESSUNAVAILABLE = 2649856; - private static final int CONTROLLERACCESSUNAVAILABLE = 2649857; + private static final int SESSIONDEACTIVATED = 2780929; - private static final int MANAGEMENTCONTROLLEROFFLINE = 2649858; + private static final int CONTROLLERACCESSUNAVAILABLE = 2649857; - private static final int SUCCESSFULHARDWARECHANGEDETECTED = 2846470; + private static final int MANAGEMENTCONTROLLEROFFLINE = 2649858; - private static final int MANAGEMENTCONTROLLERUNAVAILABLE = 2649859; + private static final int SUCCESSFULHARDWARECHANGEDETECTED = 2846470; - private static final int SUCCESSFULSOFTWAREORFWCHANGEDETECTED = 2846471; + private static final int MANAGEMENTCONTROLLERUNAVAILABLE = 2649859; - private static final int INFAILEDARRAY = 880390; + private static final int SUCCESSFULSOFTWAREORFWCHANGEDETECTED = 2846471; - private static final int REBUILDREMAPINPROGRESS = 880391; + private static final int INFAILEDARRAY = 880390; - private static final int CORRECTABLEMACHINECHECKERROR = 487180; + private static final int REBUILDREMAPINPROGRESS = 880391; - private static final int REBUILDREMAPABORTED = 880392; + private static final int CORRECTABLEMACHINECHECKERROR = 487180; - private static final int IERR = 487168; + private static final int REBUILDREMAPABORTED = 880392; - private static final int CHIPSETSOFTPOWERCONTROLFAILURE = 1666816; + private static final int IERR = 487168; - private static final int PROCESSORTHERMALTRIP = 487169; + private static final int CHIPSETSOFTPOWERCONTROLFAILURE = 1666816; - private static final int CHIPSETTHERMALTRIP = 1666817; + private static final int PROCESSORTHERMALTRIP = 487169; - private static final int D0POWERSTATE = 3072; + private static final int CHIPSETTHERMALTRIP = 1666817; - private static final int D1POWERSTATE = 3073; + private static final int D0POWERSTATE = 3072; - private static final int TEMPERATURE = 93952; + private static final int D1POWERSTATE = 3073; - private static final int D2POWERSTATE = 3074; + private static final int TEMPERATURE = 93952; - private static final int D3POWERSTATE = 3075; + private static final int D2POWERSTATE = 3074; - private static final int CRITICALSTOPDURINGOSLOAD = 2125568; + private static final int D3POWERSTATE = 3075; - private static final int RUNTIMECRITICALSTOP = 2125569; + private static final int CRITICALSTOPDURINGOSLOAD = 2125568; - private static final int DEVICEDISABLED = 2304; + private static final int RUNTIMECRITICALSTOP = 2125569; - private static final int DEVICEENABLED = 2305; + private static final int DEVICEDISABLED = 2304; - private static final int CORRECTABLEECC = 814848; + private static final int DEVICEENABLED = 2305; - private static final int UNCORRECTABLEECC = 814849; + private static final int CORRECTABLEECC = 814848; - private static final int LIMITNOTEXCEEDED = 1280; + private static final int UNCORRECTABLEECC = 814849; - private static final int LIMITEXCEEDED = 1281; + private static final int LIMITNOTEXCEEDED = 1280; - private static final int ACPIS0G0WORKING = 2256640; + private static final int LIMITEXCEEDED = 1281; - private static final int ACPIS1SLEEPINGPROCESSORCONTEXTMAINTAINED = 2256641; + private static final int ACPIS0G0WORKING = 2256640; - private static final int POWERSUPPLYPRESENCEDETECTED = 552704; + private static final int ACPIS1SLEEPINGPROCESSORCONTEXTMAINTAINED = 2256641; - private static final int ACPIS2SLEEPINGPROCESSORCONTEXTLOST = 2256642; + private static final int POWERSUPPLYPRESENCEDETECTED = 552704; - private static final int POWERSUPPLYFAILUREDETECTED = 552705; + private static final int ACPIS2SLEEPINGPROCESSORCONTEXTLOST = 2256642; - private static final int TIMERINTERRUPT = 2322184; + private static final int POWERSUPPLYFAILUREDETECTED = 552705; - private static final int ACPIS3SLEEPINGPROCESSORCONTEXTLOSTMEMORYRETAINED = 2256643; + private static final int TIMERINTERRUPT = 2322184; - private static final int POWERSUPPLYPREDICTIVEFAILURE = 552706; + private static final int ACPIS3SLEEPINGPROCESSORCONTEXTLOSTMEMORYRETAINED = 2256643; - private static final int FAN = 290560; + private static final int POWERSUPPLYPREDICTIVEFAILURE = 552706; - private static final int NONREDUNDANT_SUFFICIENTRESOURCESFROMINSUFFICIENTRESOURCES = 2820; + private static final int FAN = 290560; - private static final int ACPIS4NONVOLATILESLEEP = 2256644; + private static final int NONREDUNDANT_SUFFICIENTRESOURCESFROMINSUFFICIENTRESOURCES = 2820; - private static final int POWERSUPPLYINPUTLOST = 552707; + private static final int ACPIS4NONVOLATILESLEEP = 2256644; - private static final int NONREDUNDANT_INSUFFICIENTRESOURCES = 2821; + private static final int POWERSUPPLYINPUTLOST = 552707; - private static final int ACPIS5G2SOFTOFF = 2256645; + private static final int NONREDUNDANT_INSUFFICIENTRESOURCES = 2821; - private static final int POWERSUPPLYINPUTLOSTOROUTOFRANGE = 552708; + private static final int ACPIS5G2SOFTOFF = 2256645; - private static final int REDUNDANCYDEGRADEDFROMFULLYREDUNDANT = 2822; + private static final int POWERSUPPLYINPUTLOSTOROUTOFRANGE = 552708; - private static final int PERFORMANCEMET = 1536; + private static final int REDUNDANCYDEGRADEDFROMFULLYREDUNDANT = 2822; - private static final int ACPIS4S5SOFTOFFSTATEUNDETERMINED = 2256646; + private static final int PERFORMANCEMET = 1536; - private static final int POWERSUPPLYINPUTOUTOFRANGE = 552709; + private static final int ACPIS4S5SOFTOFFSTATEUNDETERMINED = 2256646; - private static final int REDUNDANCYDEGRADEDFROMNONREDUNDANT = 2823; + private static final int POWERSUPPLYINPUTOUTOFRANGE = 552709; - private static final int PERFORMANCELAGS = 1537; + private static final int REDUNDANCYDEGRADEDFROMNONREDUNDANT = 2823; - private static final int ACPIG3MECHANICALOFF = 2256647; + private static final int PERFORMANCELAGS = 1537; - private static final int ACPISLEEPINGINS1S2ORS3 = 2256648; + private static final int ACPIG3MECHANICALOFF = 2256647; - private static final int ACPIG1SLEEPING = 2256649; + private static final int ACPISLEEPINGINS1S2ORS3 = 2256648; - private static final int FRONTPANELINTERRUPT = 1273600; + private static final int ACPIG1SLEEPING = 2256649; - private static final int INFORMATIONAL = 1800; + private static final int FRONTPANELINTERRUPT = 1273600; - private static final int NOBOOTABLEMEDIA = 1994496; + private static final int INFORMATIONAL = 1800; - private static final int BUSTIMEOUT = 1273601; + private static final int NOBOOTABLEMEDIA = 1994496; - private static final int NONBOOTABLEDISKETTELEFTINDRIVE = 1994497; + private static final int BUSTIMEOUT = 1273601; - private static final int IOCHANNELCHECKNMI = 1273602; + private static final int NONBOOTABLEDISKETTELEFTINDRIVE = 1994497; - private static final int PXESERVERNOTFOUND = 1994498; + private static final int IOCHANNELCHECKNMI = 1273602; - private static final int SOFTWARE = 1273603; + private static final int PXESERVERNOTFOUND = 1994498; - private static final int INVALIDBOOTSECTOR = 1994499; + private static final int SOFTWARE = 1273603; - private static final int PCIPERR = 1273604; + private static final int INVALIDBOOTSECTOR = 1994499; - private static final int GENERALCHASSISINTRUSION = 356096; + private static final int PCIPERR = 1273604; - private static final int TRANSITIONTOIDLE = 512; + private static final int GENERALCHASSISINTRUSION = 356096; - private static final int PCISERR = 1273605; + private static final int TRANSITIONTOIDLE = 512; - private static final int DRIVEBAYINTRUSION = 356097; + private static final int PCISERR = 1273605; - private static final int TRANSITIONTOACTIVE = 513; + private static final int DRIVEBAYINTRUSION = 356097; - private static final int EISAFAILSAFETIMEOUT = 1273606; + private static final int TRANSITIONTOACTIVE = 513; - private static final int IOCARDAREAINTRUSION = 356098; + private static final int EISAFAILSAFETIMEOUT = 1273606; - private static final int TRANSITIONTOBUSY = 514; + private static final int IOCARDAREAINTRUSION = 356098; - private static final int BUSCORRECTABLEERROR = 1273607; + private static final int TRANSITIONTOBUSY = 514; - private static final int PROCESSORAREAINTRUSION = 356099; + private static final int BUSCORRECTABLEERROR = 1273607; - private static final int BUSUNCORRECTABLEERROR = 1273608; + private static final int PROCESSORAREAINTRUSION = 356099; - private static final int FATALNMI = 1273609; + private static final int BUSUNCORRECTABLEERROR = 1273608; - private static final int POWERBUTTONPRESSED = 1339136; + private static final int FATALNMI = 1273609; - private static final int SLEEPBUTTONPRESSED = 1339137; + private static final int POWERBUTTONPRESSED = 1339136; - private static final int FRUNOTINSTALLED = 2912000; + private static final int SLEEPBUTTONPRESSED = 1339137; - private static final int SLOTCONNECTORFAULTSTATUSASSERTED = 2191104; + private static final int FRUNOTINSTALLED = 2912000; - private static final int POWERUP = 1928960; + private static final int SLOTCONNECTORFAULTSTATUSASSERTED = 2191104; - private static final int RESETBUTTONPRESSED = 1339138; + private static final int POWERUP = 1928960; - private static final int UNKNOWNOEM = 192; + private static final int RESETBUTTONPRESSED = 1339138; - private static final int COOLINGDEVICE = 683776; + private static final int UNKNOWNOEM = 192; - private static final int OTHERUNITSBASEDSENSOR = 749312; + private static final int COOLINGDEVICE = 683776; - private static final int POSTMEMORYRESIZE = 945920; + private static final int OTHERUNITSBASEDSENSOR = 749312; - private static final int MODULEBOARD = 1404672; + private static final int POSTMEMORYRESIZE = 945920; - private static final int MICROCONTROLLERCOPROCESSOR = 1470208; + private static final int MODULEBOARD = 1404672; - private static final int ADDINCARD = 1535744; + private static final int MICROCONTROLLERCOPROCESSOR = 1470208; - private static final int CHASSIS = 1601280; + private static final int ADDINCARD = 1535744; - private static final int OTHERFRU = 1732352; + private static final int CHASSIS = 1601280; - private static final int TERMINATOR = 1863424; + private static final int OTHERFRU = 1732352; - private static final int MONITORASICIC = 2518784; + private static final int TERMINATOR = 1863424; - private static final int UNKNOWN = 0; - - private static Logger logger = LoggerFactory.getLogger(ReadingType.class); + private static final int MONITORASICIC = 2518784; - private int code; + private static final int UNKNOWN = 0; - ReadingType(int code) { - this.code = code; - } + private static Logger logger = LoggerFactory.getLogger(ReadingType.class); - public int getCode() { - return code; - } + private int code; - /** - * Determines type of discrete sensor reading. - * @param sensorType - * - {@link SensorType} of the sensor - * @param eventReadingType - * - value received via {@link FullSensorRecord#getEventReadingType()}, - * {@link CompactSensorRecord#getEventReadingType()} or {@link EventOnlyRecord#getEventReadingType()} - * @param offset - * - index of the state asserted - * @return Type of the discrete sensor reading. - */ - public static ReadingType parseInt(SensorType sensorType, int eventReadingType, int offset) { - - if (sensorType == SensorType.Oem) { - return UnknownOEMEvent; - } - - int actualOffset = (eventReadingType == 0x6f && sensorType.getCode() <= 0x4) ? 0 : offset; - - int value = (eventReadingType << 8) | actualOffset; - - if (eventReadingType == 0x6f) { // sensor-specific reading type - value |= sensorType.getCode() << 16; - } - - switch (value) { - case LOWERNONCRITICALGOINGLOW: - return LowerNonCriticalGoingLow; - case LOWERNONCRITICALGOINGHIGH: - return LowerNonCriticalGoingHigh; - case LOWERCRITICALGOINGLOW: - return LowerCriticalGoingLow; - case LOWERCRITICALGOINGHIGH: - return LowerCriticalGoingHigh; - case LOWERNONRECOVERABLEGOINGLOW: - return LowerNonRecoverableGoingLow; - case LOWERNONRECOVERABLEGOINGHIGH: - return LowerNonRecoverableGoingHigh; - case UPPERNONCRITICALGOINGLOW: - return UpperNonCriticalGoingLow; - case UPPERNONCRITICALGOINGHIGH: - return UpperNonCriticalGoingHigh; - case UPPERCRITICALGOINGLOW: - return UpperCriticalGoingLow; - case UPPERCRITICALGOINGHIGH: - return UpperCriticalGoingHigh; - case UPPERNONRECOVERABLEGOINGLOW: - return UpperNonRecoverableGoingLow; - case UPPERNONRECOVERABLEGOINGHIGH: - return UpperNonRecoverableGoingHigh; - case FRUINACTIVE: - return FruInactive; - case SLOTCONNECTORIDENTIFYSTATUSASSERTED: - return SlotConnectorIdentifyStatusAsserted; - case HARDRESET: - return HardReset; - case FRULATCHOPEN: - return FruLatchOpen; - case FRUACTIVATIONREQUESTED: - return FruActivationRequested; - case SLOTCONNECTORDEVICEINSTALLED: - return SlotConnectorDeviceInstalled; - case WARMRESET: - return WarmReset; - case FRUACTIVATIONINPROGRESS: - return FruActivationInProgress; - case SLOTCONNECTORREADYFORDEVICEINSTALLATION: - return SlotConnectorReadyForDeviceInstallation; - case PXEBOOTREQUESTED: - return PxeBootRequested; - case FRUACTIVE: - return FruActive; - case INVALIDUSERNAMEORPASSWORD: - return InvalidUsernameOrPassword; - case SLOTCONNECTORREADYFORDEVICEREMOVAL: - return SlotConnectorReadyForDeviceRemoval; - case AUTOMATICBOOTTODIAGNOSTIC: - return AutomaticBootToDiagnostic; - case FRUDEACTIVATIONREQUESTED: - return FruDeactivationRequested; - case INVALIDPASSWORDDISABLE: - return InvalidPasswordDisable; - case ENTITYPRESENT: - return EntityPresent; - case SLOTPOWEROFF: - return SlotPowerOff; - case SOFTWAREINITIATEDHARDRESET: - return SoftwareInitiatedHardReset; - case FRUDEACTIVATIONINPROGRESS: - return FruDeactivationInProgress; - case SENSORFAILURE: - return SensorFailure; - case ENTITYABSENT: - return EntityAbsent; - case SOFTWAREINITIATEDWARMRESET: - return SoftwareInitiatedWarmReset; - case FRUCOMMUNICATIONLOST: - return FruCommunicationLost; - case FRUFAILURE: - return FruFailure; - case SYSTEMRESTART: - return SystemRestart; - case STATEDEASSERTED: - return StateDeasserted; - case SYSTEMFIRMWAREERROR: - return SystemFirmwareError; - case STATEASSERTED: - return StateAsserted; - case SYSTEMFIRMWAREHANG: - return SystemFirmwareHang; - case SYSTEMFIRMWAREPROGRESS: - return SystemFirmwareProgress; - case HARDWARECHANGEDETECTED: - return HardwareChangeDetected; - case FRB1BISTFAILURE: - return Frb1BistFailure; - case FIRMWAREORSOFTWARECHANGEDETECTED: - return FirmwareOrSoftwareChangeDetected; - case FRB2HANGINPOSTFAILURE: - return Frb2HangInPostFailure; - case HARDWAREINCOMPATIBILITYDETECTED: - return HardwareIncompatibilityDetected; - case FRB3PROCESSORSTARTUPFAILURE: - return Frb3ProcessorStartupFailure; - case FIRMWAREORSOFTWAREINCOMPATIBILITYDETECTED: - return FirmwareOrSoftwareIncompatibilityDetected; - case DRIVEPRESENCE: - return DrivePresence; - case CONFIGURATIONERROR: - return ConfigurationError; - case INVALIDORUNSUPPORTEDHARDWARE: - return InvalidOrUnsupportedHardware; - case DRIVEFAULT: - return DriveFault; - case UNCORRECTABLECPUCOMPLEXERROR: - return UncorrectableCpuComplexError; - case INVALIDORUNSUPPORTEDFIRMWAREORSOFTWARE: - return InvalidOrUnsupportedFirmwareOrSoftware; - case PREDICTIVEFAILURE: - return PredictiveFailure; - case PROCESSORPRESENCEDETECTED: - return ProcessorPresenceDetected; - case HOTSPARE: - return HotSpare; - case PROCESSORDISABLED: - return ProcessorDisabled; - case CONSISTENCYORPARITYCHECKINPROGRESS: - return ConsistencyOrParityCheckInProgress; - case TERMINATORPRESENCEDETECTED: - return TerminatorPresenceDetected; - case SECUREMODEVIOLATIONATTEMPT: - return SecureModeViolationAttempt; - case OSGRACEFULSTOP: - return OsGracefulStop; - case INCRITICALARRAY: - return InCriticalArray; - case PROCESSORAUTOMATICALLYTHROTTLED: - return ProcessorAutomaticallyThrottled; - case PREBOOTUSERPASSWORDVIOLATION: - return PreBootUserPasswordViolation; - case OSGRACEFULSHUTDOWN: - return OsGracefulShutdown; - case MACHINECHECKEXCEPTION: - return MachineCheckException; - case PREBOOTSETUPPASSWORDVIOLATION: - return PreBootSetupPasswordViolation; - case SOFTOSSHUTDOWN: - return SoftOsShutdown; - case PREBOOTNETWORKPASSWORDVIOLATION: - return PreBootNetworkPasswordViolation; - case LANHEARTBEATLOST: - return LANHeartbeatLost; - case AGENTNOTRESPONDING: - return AgentNotResponding; - case OTHERPREBOOTPASSWORDVIOLATION: - return OtherPreBootPasswordViolation; - case LANHEARTBEAT: - return LANHeartbeat; - case OUTOFBANDACCESSPASSWORDVIOLATION: - return OutOfBandAccessPasswordViolation; - case CURRENT: - return Current; - case DEVICEABSENT: - return DeviceAbsent; - case PARITY: - return Parity; - case DEVICEPRESENT: - return DevicePresent; - case MEMORYSCRUBFAILED: - return MemoryScrubFailed; - case MEMORYDEVICEDISABLED: - return MemoryDeviceDisabled; - case CORRECTABLEECCOTHERCORRECTABLEMEMORYERRORLOGGINGLIMITREACHED: - return CorrectableEccOtherCorrectableMemoryErrorLoggingLimitReached; - case MEMORYPRESENCEDETECTED: - return MemoryPresenceDetected; - case MEMORYCONFIGURATIONERROR: - return MemoryConfigurationError; - case SPAREMEMORYUNIT: - return SpareMemoryUnit; - case MEMORYAUTOMATICALLYTHROTTLED: - return MemoryAutomaticallyThrottled; - case MEMORYCRITICALOVERTEMPERATURE: - return MemoryCriticalOvertemperature; - case SYSTEMRECONFIGURED: - return SystemReconfigured; - case OEMSYSTEMBOOTEVENT: - return OemSystemBootEvent; - case ABOOTCOMPLETED: - return ABootCompleted; - case UNDETERMINEDSYSTEMHARDWAREFAILURE: - return UndeterminedSystemHardwareFailure; - case TRANSITIONTORUNNING: - return TransitionToRunning; - case CBOOTCOMPLETED: - return CBootCompleted; - case ENTRYADDEDTOAUXILIARYLOG: - return EntryAddedToAuxiliaryLog; - case TRANSITIONTOINTEST: - return TransitionToInTest; - case PXEBOOTCOMPLETED: - return PxeBootCompleted; - case PEFACTION: - return PefAction; - case TRANSITIONTOPOWEROFF: - return TransitionToPowerOff; - case DIAGNOSTICBOOTCOMPLETED: - return DiagnosticBootCompleted; - case TIMESTAMPCLOCKSYNCH: - return TimestampClockSynch; - case TRANSITIONTOONLINE: - return TransitionToOnLine; - case CDROMBOOTCOMPLETED: - return CdRomBootCompleted; - case BOOTSOURCESELECTIONTIMEOUT: - return BootSourceSelectionTimeout; - case POWERSUPPLYCONFIGURATIONERROR: - return PowerSupplyConfigurationError; - case TRANSITIONTOOFFLINE: - return TransitionToOffLine; - case TIMEREXPIRED: - return TimerExpired; - case ROMBOOTCOMPLETED: - return RomBootCompleted; - case TRANSITIONTOOFFDUTY: - return TransitionToOffDuty; - case TIMERHARDRESET: - return TimerHardReset; - case BOOTCOMPLETED: - return BootCompleted; - case PREDICTIVEFAILUREDEASSERTED: - return PredictiveFailureDeasserted; - case TRANSITIONTODEGRADED: - return TransitionToDegraded; - case TIMERPOWERDOWN: - return TimerPowerDown; - case ACPIS5ENTEREDBYOVERRIDE: - return AcpiS5EnteredByOverride; - case LANLEASHLOST: - return LANLeashLost; - case PREDICTIVE: - return Predictive; - case TRANSITIONTOPOWERSAVE: - return TransitionToPowerSave; - case TIMERPOWERCYCLE: - return TimerPowerCycle; - case ACPILEGACYONSTATE: - return AcpiLegacyOnState; - case POWEROFFORDOWN: - return PowerOffOrDown; - case UNAUTHORIZEDDOCK: - return UnauthorizedDock; - case INSTALLERROR: - return InstallError; - case ACPILEGACYOFFSTATE: - return AcpiLegacyOffState; - case POWERCYCLE: - return PowerCycle; - case FANAREAINTRUSION: - return FANAreaIntrusion; - case FULLYREDUNDANT: - return FullyRedundant; - case CABLEINTERCONNECTCONNECTED: - return CableInterconnectConnected; - case POWERDOWN240V: - return PowerDown240V; - case REDUNDANCYLOST: - return RedundancyLost; - case ACPIUNKNOWN: - return AcpiUnknown; - case CABLEINTERCONNECTCONFIGURATIONERROR: - return CableInterconnectConfigurationError; - case INTERLOCKPOWERDOWN: - return InterlockPowerDown; - case REDUNDANCYDEGRADED: - return RedundancyDegraded; - case BATTERYLOW: - return BatteryLow; - case POWERINPUTLOST: - return PowerInputLost; - case NONREDUNDANT_SUFFICIENTRESOURCESFROMREDUNDANT: - return NonRedundant_SufficientResourcesFromRedundant; - case BATTERYFAILED: - return BatteryFailed; - case POWERUNITSOFTPOWERCONTROLFAILURE: - return PowerUnitSoftPowerControlFailure; - case VOLTAGE: - return Voltage; - case BATTERYPRESENCEDETECTED: - return BatteryPresenceDetected; - case POWERUNITFAILURE: - return PowerUnitFailure; - case POWERUNITPREDICTIVEFAILURE: - return PowerUnitPredictiveFailure; - case BUSFATALERROR: - return BusFatalError; - case CORRECTABLEMEMORYERRORLOGGINGDISABLED: - return CorrectableMemoryErrorLoggingDisabled; - case BUSDEGRADED: - return BusDegraded; - case EVENTTYPELOGGINGDISABLED: - return EventTypeLoggingDisabled; - case LOGAREARESET: - return LogAreaReset; - case TRANSITIONTOOK: - return TransitionToOK; - case ALLEVENTLOGGINGDISABLED: - return AllEventLoggingDisabled; - case TRANSITIONTONONCRITICALFROMOK: - return TransitionToNonCriticalFromOK; - case FRUSERVICEREQUESTBUTTONPRESSED: - return FruServiceRequestButtonPressed; - case SELFULL: - return SelFull; - case TRANSITIONTOCRITICALFROMLESSSEVERE: - return TransitionToCriticalFromLessSevere; - case SELALMOSTFULL: - return SelAlmostFull; - case TRANSITIONTONONRECOVERABLEFROMLESSSEVERE: - return TransitionToNonRecoverableFromLessSevere; - case CORRECTABLEMACHINECHECKERRORLOGGINGDISABLED: - return CorrectableMachineCheckErrorLoggingDisabled; - case TRANSITIONTONONCRITICALFROMMORESEVERE: - return TransitionToNonCriticalFromMoreSevere; - case TRANSITIONTOCRITICALFROMNONRECOVERABLE: - return TransitionToCriticalFromNonRecoverable; - case SLOTCONNECTORDEVICEREMOVALREQUEST: - return SlotConnectorDeviceRemovalRequest; - case TRANSITIONTONONRECOVERABLE: - return TransitionToNonRecoverable; - case ENTITYDISABLED: - return EntityDisabled; - case INTERLOCKASSERTED: - return InterlockAsserted; - case MONITOR: - return Monitor; - case SLOTDISABLED: - return SlotDisabled; - case SLOTHOLDSSPAREDEVICE: - return SlotHoldsSpareDevice; - case PLATFORMGENERATEDPAGE: - return PlatformGeneratedPage; - case PLATFORMGENERATEDLANALERT: - return PlatformGeneratedLanAlert; - case PLATFORMEVENTTRAPGENERATED: - return PlatformEventTrapGenerated; - case PLATFORMGENERATEDSNMPTRAP: - return PlatformGeneratedSnmpTrap; - case SESSIONACTIVATED: - return SessionActivated; - case SENSORACCESSUNAVAILABLE: - return SensorAccessUnavailable; - case SESSIONDEACTIVATED: - return SessionDeactivated; - case CONTROLLERACCESSUNAVAILABLE: - return ControllerAccessUnavailable; - case MANAGEMENTCONTROLLEROFFLINE: - return ManagementControllerOffLine; - case SUCCESSFULHARDWARECHANGEDETECTED: - return SuccessfulHardwareChangeDetected; - case MANAGEMENTCONTROLLERUNAVAILABLE: - return ManagementControllerUnavailable; - case SUCCESSFULSOFTWAREORFWCHANGEDETECTED: - return SuccessfulSoftwareOrFWChangeDetected; - case INFAILEDARRAY: - return InFailedArray; - case REBUILDREMAPINPROGRESS: - return RebuildRemapInProgress; - case CORRECTABLEMACHINECHECKERROR: - return CorrectableMachineCheckError; - case REBUILDREMAPABORTED: - return RebuildRemapAborted; - case IERR: - return Ierr; - case CHIPSETSOFTPOWERCONTROLFAILURE: - return ChipsetSoftPowerControlFailure; - case PROCESSORTHERMALTRIP: - return ProcessorThermalTrip; - case CHIPSETTHERMALTRIP: - return ChipsetThermalTrip; - case D0POWERSTATE: - return D0PowerState; - case D1POWERSTATE: - return D1PowerState; - case TEMPERATURE: - return Temperature; - case D2POWERSTATE: - return D2PowerState; - case D3POWERSTATE: - return D3PowerState; - case CRITICALSTOPDURINGOSLOAD: - return CriticalStopDuringOsLoad; - case RUNTIMECRITICALSTOP: - return RunTimeCriticalStop; - case DEVICEDISABLED: - return DeviceDisabled; - case DEVICEENABLED: - return DeviceEnabled; - case CORRECTABLEECC: - return CorrectableEcc; - case UNCORRECTABLEECC: - return UncorrectableECC; - case LIMITNOTEXCEEDED: - return LimitNotExceeded; - case LIMITEXCEEDED: - return LimitExceeded; - case ACPIS0G0WORKING: - return AcpiS0G0Working; - case ACPIS1SLEEPINGPROCESSORCONTEXTMAINTAINED: - return AcpiS1SleepingProcessorContextMaintained; - case POWERSUPPLYPRESENCEDETECTED: - return PowerSupplyPresenceDetected; - case ACPIS2SLEEPINGPROCESSORCONTEXTLOST: - return AcpiS2SleepingProcessorContextLost; - case POWERSUPPLYFAILUREDETECTED: - return PowerSupplyFailureDetected; - case TIMERINTERRUPT: - return TimerInterrupt; - case ACPIS3SLEEPINGPROCESSORCONTEXTLOSTMEMORYRETAINED: - return AcpiS3SleepingProcessorContextLostMemoryRetained; - case POWERSUPPLYPREDICTIVEFAILURE: - return PowerSupplyPredictiveFailure; - case FAN: - return Fan; - case NONREDUNDANT_SUFFICIENTRESOURCESFROMINSUFFICIENTRESOURCES: - return NonRedundant_SufficientResourcesFromInsufficientResources; - case ACPIS4NONVOLATILESLEEP: - return AcpiS4NonVolatileSleep; - case POWERSUPPLYINPUTLOST: - return PowerSupplyInputLost; - case NONREDUNDANT_INSUFFICIENTRESOURCES: - return NonRedundant_InsufficientResources; - case ACPIS5G2SOFTOFF: - return AcpiS5G2SoftOff; - case POWERSUPPLYINPUTLOSTOROUTOFRANGE: - return PowerSupplyInputLostOrOutOfRange; - case REDUNDANCYDEGRADEDFROMFULLYREDUNDANT: - return RedundancyDegradedFromFullyRedundant; - case PERFORMANCEMET: - return PerformanceMet; - case ACPIS4S5SOFTOFFSTATEUNDETERMINED: - return AcpiS4S5SoftOffStateUndetermined; - case POWERSUPPLYINPUTOUTOFRANGE: - return PowerSupplyInputOutOfRange; - case REDUNDANCYDEGRADEDFROMNONREDUNDANT: - return RedundancyDegradedFromNonRedundant; - case PERFORMANCELAGS: - return PerformanceLags; - case ACPIG3MECHANICALOFF: - return AcpiG3MechanicalOff; - case ACPISLEEPINGINS1S2ORS3: - return AcpiSleepingInS1S2OrS3; - case ACPIG1SLEEPING: - return AcpiG1Sleeping; - case FRONTPANELINTERRUPT: - return FrontPanelInterrupt; - case INFORMATIONAL: - return Informational; - case NOBOOTABLEMEDIA: - return NoBootableMedia; - case BUSTIMEOUT: - return BusTimeout; - case NONBOOTABLEDISKETTELEFTINDRIVE: - return NonBootableDisketteLeftInDrive; - case IOCHANNELCHECKNMI: - return IoChannelCheckNmi; - case PXESERVERNOTFOUND: - return PxeServerNotFound; - case SOFTWARE: - return Software; - case INVALIDBOOTSECTOR: - return InvalidBootSector; - case PCIPERR: - return PciPErr; - case GENERALCHASSISINTRUSION: - return GeneralChassisIntrusion; - case TRANSITIONTOIDLE: - return TransitionToIdle; - case PCISERR: - return PciSErr; - case DRIVEBAYINTRUSION: - return DriveBayIntrusion; - case TRANSITIONTOACTIVE: - return TransitionToActive; - case EISAFAILSAFETIMEOUT: - return EisaFailSafeTimeout; - case IOCARDAREAINTRUSION: - return IoCardAreaIntrusion; - case TRANSITIONTOBUSY: - return TransitionToBusy; - case BUSCORRECTABLEERROR: - return BusCorrectableError; - case PROCESSORAREAINTRUSION: - return ProcessorAreaIntrusion; - case BUSUNCORRECTABLEERROR: - return BusUncorrectableError; - case FATALNMI: - return FatalNmi; - case POWERBUTTONPRESSED: - return PowerButtonPressed; - case SLEEPBUTTONPRESSED: - return SleepButtonPressed; - case FRUNOTINSTALLED: - return FruNotInstalled; - case SLOTCONNECTORFAULTSTATUSASSERTED: - return SlotConnectorFaultStatusAsserted; - case POWERUP: - return PowerUp; - case RESETBUTTONPRESSED: - return ResetButtonPressed; - case COOLINGDEVICE: - return CoolingDevice; - case OTHERUNITSBASEDSENSOR: - return OtherUnitsBasedSensor; - case POSTMEMORYRESIZE: - return PostMemoryResize; - case MODULEBOARD: - return ModuleBoard; - case MICROCONTROLLERCOPROCESSOR: - return MicrocontrollerCoprocessor; - case ADDINCARD: - return AddInCard; - case CHASSIS: - return Chassis; - case OTHERFRU: - return OtherFru; - case TERMINATOR: - return Terminator; - case MONITORASICIC: - return MonitorAsicIc; - default: - logger.warn("Invalid value: " + value + " (" + Integer.toHexString(value) - + ") for sensor " + sensorType); - return Unknown; - } - } + ReadingType(int code) { + this.code = code; + } + + public int getCode() { + return code; + } + + /** + * Determines type of discrete sensor reading. + * + * @param sensorType + * - {@link SensorType} of the sensor + * @param eventReadingType + * - value received via {@link FullSensorRecord#getEventReadingType()}, + * {@link CompactSensorRecord#getEventReadingType()} or {@link EventOnlyRecord#getEventReadingType()} + * @param offset + * - index of the state asserted + * @return Type of the discrete sensor reading. + */ + public static ReadingType parseInt(SensorType sensorType, int eventReadingType, int offset) { + + if (sensorType == SensorType.Oem) { + return UnknownOEMEvent; + } + + int actualOffset = (eventReadingType == 0x6f && sensorType.getCode() <= 0x4) ? 0 : offset; + + int value = (eventReadingType << 8) | actualOffset; + + if (eventReadingType == 0x6f) { // sensor-specific reading type + value |= sensorType.getCode() << 16; + } + + switch (value) { + case LOWERNONCRITICALGOINGLOW: + return LowerNonCriticalGoingLow; + case LOWERNONCRITICALGOINGHIGH: + return LowerNonCriticalGoingHigh; + case LOWERCRITICALGOINGLOW: + return LowerCriticalGoingLow; + case LOWERCRITICALGOINGHIGH: + return LowerCriticalGoingHigh; + case LOWERNONRECOVERABLEGOINGLOW: + return LowerNonRecoverableGoingLow; + case LOWERNONRECOVERABLEGOINGHIGH: + return LowerNonRecoverableGoingHigh; + case UPPERNONCRITICALGOINGLOW: + return UpperNonCriticalGoingLow; + case UPPERNONCRITICALGOINGHIGH: + return UpperNonCriticalGoingHigh; + case UPPERCRITICALGOINGLOW: + return UpperCriticalGoingLow; + case UPPERCRITICALGOINGHIGH: + return UpperCriticalGoingHigh; + case UPPERNONRECOVERABLEGOINGLOW: + return UpperNonRecoverableGoingLow; + case UPPERNONRECOVERABLEGOINGHIGH: + return UpperNonRecoverableGoingHigh; + case FRUINACTIVE: + return FruInactive; + case SLOTCONNECTORIDENTIFYSTATUSASSERTED: + return SlotConnectorIdentifyStatusAsserted; + case HARDRESET: + return HardReset; + case FRULATCHOPEN: + return FruLatchOpen; + case FRUACTIVATIONREQUESTED: + return FruActivationRequested; + case SLOTCONNECTORDEVICEINSTALLED: + return SlotConnectorDeviceInstalled; + case WARMRESET: + return WarmReset; + case FRUACTIVATIONINPROGRESS: + return FruActivationInProgress; + case SLOTCONNECTORREADYFORDEVICEINSTALLATION: + return SlotConnectorReadyForDeviceInstallation; + case PXEBOOTREQUESTED: + return PxeBootRequested; + case FRUACTIVE: + return FruActive; + case INVALIDUSERNAMEORPASSWORD: + return InvalidUsernameOrPassword; + case SLOTCONNECTORREADYFORDEVICEREMOVAL: + return SlotConnectorReadyForDeviceRemoval; + case AUTOMATICBOOTTODIAGNOSTIC: + return AutomaticBootToDiagnostic; + case FRUDEACTIVATIONREQUESTED: + return FruDeactivationRequested; + case INVALIDPASSWORDDISABLE: + return InvalidPasswordDisable; + case ENTITYPRESENT: + return EntityPresent; + case SLOTPOWEROFF: + return SlotPowerOff; + case SOFTWAREINITIATEDHARDRESET: + return SoftwareInitiatedHardReset; + case FRUDEACTIVATIONINPROGRESS: + return FruDeactivationInProgress; + case SENSORFAILURE: + return SensorFailure; + case ENTITYABSENT: + return EntityAbsent; + case SOFTWAREINITIATEDWARMRESET: + return SoftwareInitiatedWarmReset; + case FRUCOMMUNICATIONLOST: + return FruCommunicationLost; + case FRUFAILURE: + return FruFailure; + case SYSTEMRESTART: + return SystemRestart; + case STATEDEASSERTED: + return StateDeasserted; + case SYSTEMFIRMWAREERROR: + return SystemFirmwareError; + case STATEASSERTED: + return StateAsserted; + case SYSTEMFIRMWAREHANG: + return SystemFirmwareHang; + case SYSTEMFIRMWAREPROGRESS: + return SystemFirmwareProgress; + case HARDWARECHANGEDETECTED: + return HardwareChangeDetected; + case FRB1BISTFAILURE: + return Frb1BistFailure; + case FIRMWAREORSOFTWARECHANGEDETECTED: + return FirmwareOrSoftwareChangeDetected; + case FRB2HANGINPOSTFAILURE: + return Frb2HangInPostFailure; + case HARDWAREINCOMPATIBILITYDETECTED: + return HardwareIncompatibilityDetected; + case FRB3PROCESSORSTARTUPFAILURE: + return Frb3ProcessorStartupFailure; + case FIRMWAREORSOFTWAREINCOMPATIBILITYDETECTED: + return FirmwareOrSoftwareIncompatibilityDetected; + case DRIVEPRESENCE: + return DrivePresence; + case CONFIGURATIONERROR: + return ConfigurationError; + case INVALIDORUNSUPPORTEDHARDWARE: + return InvalidOrUnsupportedHardware; + case DRIVEFAULT: + return DriveFault; + case UNCORRECTABLECPUCOMPLEXERROR: + return UncorrectableCpuComplexError; + case INVALIDORUNSUPPORTEDFIRMWAREORSOFTWARE: + return InvalidOrUnsupportedFirmwareOrSoftware; + case PREDICTIVEFAILURE: + return PredictiveFailure; + case PROCESSORPRESENCEDETECTED: + return ProcessorPresenceDetected; + case HOTSPARE: + return HotSpare; + case PROCESSORDISABLED: + return ProcessorDisabled; + case CONSISTENCYORPARITYCHECKINPROGRESS: + return ConsistencyOrParityCheckInProgress; + case TERMINATORPRESENCEDETECTED: + return TerminatorPresenceDetected; + case SECUREMODEVIOLATIONATTEMPT: + return SecureModeViolationAttempt; + case OSGRACEFULSTOP: + return OsGracefulStop; + case INCRITICALARRAY: + return InCriticalArray; + case PROCESSORAUTOMATICALLYTHROTTLED: + return ProcessorAutomaticallyThrottled; + case PREBOOTUSERPASSWORDVIOLATION: + return PreBootUserPasswordViolation; + case OSGRACEFULSHUTDOWN: + return OsGracefulShutdown; + case MACHINECHECKEXCEPTION: + return MachineCheckException; + case PREBOOTSETUPPASSWORDVIOLATION: + return PreBootSetupPasswordViolation; + case SOFTOSSHUTDOWN: + return SoftOsShutdown; + case PREBOOTNETWORKPASSWORDVIOLATION: + return PreBootNetworkPasswordViolation; + case LANHEARTBEATLOST: + return LANHeartbeatLost; + case AGENTNOTRESPONDING: + return AgentNotResponding; + case OTHERPREBOOTPASSWORDVIOLATION: + return OtherPreBootPasswordViolation; + case LANHEARTBEAT: + return LANHeartbeat; + case OUTOFBANDACCESSPASSWORDVIOLATION: + return OutOfBandAccessPasswordViolation; + case CURRENT: + return Current; + case DEVICEABSENT: + return DeviceAbsent; + case PARITY: + return Parity; + case DEVICEPRESENT: + return DevicePresent; + case MEMORYSCRUBFAILED: + return MemoryScrubFailed; + case MEMORYDEVICEDISABLED: + return MemoryDeviceDisabled; + case CORRECTABLEECCOTHERCORRECTABLEMEMORYERRORLOGGINGLIMITREACHED: + return CorrectableEccOtherCorrectableMemoryErrorLoggingLimitReached; + case MEMORYPRESENCEDETECTED: + return MemoryPresenceDetected; + case MEMORYCONFIGURATIONERROR: + return MemoryConfigurationError; + case SPAREMEMORYUNIT: + return SpareMemoryUnit; + case MEMORYAUTOMATICALLYTHROTTLED: + return MemoryAutomaticallyThrottled; + case MEMORYCRITICALOVERTEMPERATURE: + return MemoryCriticalOvertemperature; + case SYSTEMRECONFIGURED: + return SystemReconfigured; + case OEMSYSTEMBOOTEVENT: + return OemSystemBootEvent; + case ABOOTCOMPLETED: + return ABootCompleted; + case UNDETERMINEDSYSTEMHARDWAREFAILURE: + return UndeterminedSystemHardwareFailure; + case TRANSITIONTORUNNING: + return TransitionToRunning; + case CBOOTCOMPLETED: + return CBootCompleted; + case ENTRYADDEDTOAUXILIARYLOG: + return EntryAddedToAuxiliaryLog; + case TRANSITIONTOINTEST: + return TransitionToInTest; + case PXEBOOTCOMPLETED: + return PxeBootCompleted; + case PEFACTION: + return PefAction; + case TRANSITIONTOPOWEROFF: + return TransitionToPowerOff; + case DIAGNOSTICBOOTCOMPLETED: + return DiagnosticBootCompleted; + case TIMESTAMPCLOCKSYNCH: + return TimestampClockSynch; + case TRANSITIONTOONLINE: + return TransitionToOnLine; + case CDROMBOOTCOMPLETED: + return CdRomBootCompleted; + case BOOTSOURCESELECTIONTIMEOUT: + return BootSourceSelectionTimeout; + case POWERSUPPLYCONFIGURATIONERROR: + return PowerSupplyConfigurationError; + case TRANSITIONTOOFFLINE: + return TransitionToOffLine; + case TIMEREXPIRED: + return TimerExpired; + case ROMBOOTCOMPLETED: + return RomBootCompleted; + case TRANSITIONTOOFFDUTY: + return TransitionToOffDuty; + case TIMERHARDRESET: + return TimerHardReset; + case BOOTCOMPLETED: + return BootCompleted; + case PREDICTIVEFAILUREDEASSERTED: + return PredictiveFailureDeasserted; + case TRANSITIONTODEGRADED: + return TransitionToDegraded; + case TIMERPOWERDOWN: + return TimerPowerDown; + case ACPIS5ENTEREDBYOVERRIDE: + return AcpiS5EnteredByOverride; + case LANLEASHLOST: + return LANLeashLost; + case PREDICTIVE: + return Predictive; + case TRANSITIONTOPOWERSAVE: + return TransitionToPowerSave; + case TIMERPOWERCYCLE: + return TimerPowerCycle; + case ACPILEGACYONSTATE: + return AcpiLegacyOnState; + case POWEROFFORDOWN: + return PowerOffOrDown; + case UNAUTHORIZEDDOCK: + return UnauthorizedDock; + case INSTALLERROR: + return InstallError; + case ACPILEGACYOFFSTATE: + return AcpiLegacyOffState; + case POWERCYCLE: + return PowerCycle; + case FANAREAINTRUSION: + return FANAreaIntrusion; + case FULLYREDUNDANT: + return FullyRedundant; + case CABLEINTERCONNECTCONNECTED: + return CableInterconnectConnected; + case POWERDOWN240V: + return PowerDown240V; + case REDUNDANCYLOST: + return RedundancyLost; + case ACPIUNKNOWN: + return AcpiUnknown; + case CABLEINTERCONNECTCONFIGURATIONERROR: + return CableInterconnectConfigurationError; + case INTERLOCKPOWERDOWN: + return InterlockPowerDown; + case REDUNDANCYDEGRADED: + return RedundancyDegraded; + case BATTERYLOW: + return BatteryLow; + case POWERINPUTLOST: + return PowerInputLost; + case NONREDUNDANT_SUFFICIENTRESOURCESFROMREDUNDANT: + return NonRedundant_SufficientResourcesFromRedundant; + case BATTERYFAILED: + return BatteryFailed; + case POWERUNITSOFTPOWERCONTROLFAILURE: + return PowerUnitSoftPowerControlFailure; + case VOLTAGE: + return Voltage; + case BATTERYPRESENCEDETECTED: + return BatteryPresenceDetected; + case POWERUNITFAILURE: + return PowerUnitFailure; + case POWERUNITPREDICTIVEFAILURE: + return PowerUnitPredictiveFailure; + case BUSFATALERROR: + return BusFatalError; + case CORRECTABLEMEMORYERRORLOGGINGDISABLED: + return CorrectableMemoryErrorLoggingDisabled; + case BUSDEGRADED: + return BusDegraded; + case EVENTTYPELOGGINGDISABLED: + return EventTypeLoggingDisabled; + case LOGAREARESET: + return LogAreaReset; + case TRANSITIONTOOK: + return TransitionToOK; + case ALLEVENTLOGGINGDISABLED: + return AllEventLoggingDisabled; + case TRANSITIONTONONCRITICALFROMOK: + return TransitionToNonCriticalFromOK; + case FRUSERVICEREQUESTBUTTONPRESSED: + return FruServiceRequestButtonPressed; + case SELFULL: + return SelFull; + case TRANSITIONTOCRITICALFROMLESSSEVERE: + return TransitionToCriticalFromLessSevere; + case SELALMOSTFULL: + return SelAlmostFull; + case TRANSITIONTONONRECOVERABLEFROMLESSSEVERE: + return TransitionToNonRecoverableFromLessSevere; + case CORRECTABLEMACHINECHECKERRORLOGGINGDISABLED: + return CorrectableMachineCheckErrorLoggingDisabled; + case TRANSITIONTONONCRITICALFROMMORESEVERE: + return TransitionToNonCriticalFromMoreSevere; + case TRANSITIONTOCRITICALFROMNONRECOVERABLE: + return TransitionToCriticalFromNonRecoverable; + case SLOTCONNECTORDEVICEREMOVALREQUEST: + return SlotConnectorDeviceRemovalRequest; + case TRANSITIONTONONRECOVERABLE: + return TransitionToNonRecoverable; + case ENTITYDISABLED: + return EntityDisabled; + case INTERLOCKASSERTED: + return InterlockAsserted; + case MONITOR: + return Monitor; + case SLOTDISABLED: + return SlotDisabled; + case SLOTHOLDSSPAREDEVICE: + return SlotHoldsSpareDevice; + case PLATFORMGENERATEDPAGE: + return PlatformGeneratedPage; + case PLATFORMGENERATEDLANALERT: + return PlatformGeneratedLanAlert; + case PLATFORMEVENTTRAPGENERATED: + return PlatformEventTrapGenerated; + case PLATFORMGENERATEDSNMPTRAP: + return PlatformGeneratedSnmpTrap; + case SESSIONACTIVATED: + return SessionActivated; + case SENSORACCESSUNAVAILABLE: + return SensorAccessUnavailable; + case SESSIONDEACTIVATED: + return SessionDeactivated; + case CONTROLLERACCESSUNAVAILABLE: + return ControllerAccessUnavailable; + case MANAGEMENTCONTROLLEROFFLINE: + return ManagementControllerOffLine; + case SUCCESSFULHARDWARECHANGEDETECTED: + return SuccessfulHardwareChangeDetected; + case MANAGEMENTCONTROLLERUNAVAILABLE: + return ManagementControllerUnavailable; + case SUCCESSFULSOFTWAREORFWCHANGEDETECTED: + return SuccessfulSoftwareOrFWChangeDetected; + case INFAILEDARRAY: + return InFailedArray; + case REBUILDREMAPINPROGRESS: + return RebuildRemapInProgress; + case CORRECTABLEMACHINECHECKERROR: + return CorrectableMachineCheckError; + case REBUILDREMAPABORTED: + return RebuildRemapAborted; + case IERR: + return Ierr; + case CHIPSETSOFTPOWERCONTROLFAILURE: + return ChipsetSoftPowerControlFailure; + case PROCESSORTHERMALTRIP: + return ProcessorThermalTrip; + case CHIPSETTHERMALTRIP: + return ChipsetThermalTrip; + case D0POWERSTATE: + return D0PowerState; + case D1POWERSTATE: + return D1PowerState; + case TEMPERATURE: + return Temperature; + case D2POWERSTATE: + return D2PowerState; + case D3POWERSTATE: + return D3PowerState; + case CRITICALSTOPDURINGOSLOAD: + return CriticalStopDuringOsLoad; + case RUNTIMECRITICALSTOP: + return RunTimeCriticalStop; + case DEVICEDISABLED: + return DeviceDisabled; + case DEVICEENABLED: + return DeviceEnabled; + case CORRECTABLEECC: + return CorrectableEcc; + case UNCORRECTABLEECC: + return UncorrectableECC; + case LIMITNOTEXCEEDED: + return LimitNotExceeded; + case LIMITEXCEEDED: + return LimitExceeded; + case ACPIS0G0WORKING: + return AcpiS0G0Working; + case ACPIS1SLEEPINGPROCESSORCONTEXTMAINTAINED: + return AcpiS1SleepingProcessorContextMaintained; + case POWERSUPPLYPRESENCEDETECTED: + return PowerSupplyPresenceDetected; + case ACPIS2SLEEPINGPROCESSORCONTEXTLOST: + return AcpiS2SleepingProcessorContextLost; + case POWERSUPPLYFAILUREDETECTED: + return PowerSupplyFailureDetected; + case TIMERINTERRUPT: + return TimerInterrupt; + case ACPIS3SLEEPINGPROCESSORCONTEXTLOSTMEMORYRETAINED: + return AcpiS3SleepingProcessorContextLostMemoryRetained; + case POWERSUPPLYPREDICTIVEFAILURE: + return PowerSupplyPredictiveFailure; + case FAN: + return Fan; + case NONREDUNDANT_SUFFICIENTRESOURCESFROMINSUFFICIENTRESOURCES: + return NonRedundant_SufficientResourcesFromInsufficientResources; + case ACPIS4NONVOLATILESLEEP: + return AcpiS4NonVolatileSleep; + case POWERSUPPLYINPUTLOST: + return PowerSupplyInputLost; + case NONREDUNDANT_INSUFFICIENTRESOURCES: + return NonRedundant_InsufficientResources; + case ACPIS5G2SOFTOFF: + return AcpiS5G2SoftOff; + case POWERSUPPLYINPUTLOSTOROUTOFRANGE: + return PowerSupplyInputLostOrOutOfRange; + case REDUNDANCYDEGRADEDFROMFULLYREDUNDANT: + return RedundancyDegradedFromFullyRedundant; + case PERFORMANCEMET: + return PerformanceMet; + case ACPIS4S5SOFTOFFSTATEUNDETERMINED: + return AcpiS4S5SoftOffStateUndetermined; + case POWERSUPPLYINPUTOUTOFRANGE: + return PowerSupplyInputOutOfRange; + case REDUNDANCYDEGRADEDFROMNONREDUNDANT: + return RedundancyDegradedFromNonRedundant; + case PERFORMANCELAGS: + return PerformanceLags; + case ACPIG3MECHANICALOFF: + return AcpiG3MechanicalOff; + case ACPISLEEPINGINS1S2ORS3: + return AcpiSleepingInS1S2OrS3; + case ACPIG1SLEEPING: + return AcpiG1Sleeping; + case FRONTPANELINTERRUPT: + return FrontPanelInterrupt; + case INFORMATIONAL: + return Informational; + case NOBOOTABLEMEDIA: + return NoBootableMedia; + case BUSTIMEOUT: + return BusTimeout; + case NONBOOTABLEDISKETTELEFTINDRIVE: + return NonBootableDisketteLeftInDrive; + case IOCHANNELCHECKNMI: + return IoChannelCheckNmi; + case PXESERVERNOTFOUND: + return PxeServerNotFound; + case SOFTWARE: + return Software; + case INVALIDBOOTSECTOR: + return InvalidBootSector; + case PCIPERR: + return PciPErr; + case GENERALCHASSISINTRUSION: + return GeneralChassisIntrusion; + case TRANSITIONTOIDLE: + return TransitionToIdle; + case PCISERR: + return PciSErr; + case DRIVEBAYINTRUSION: + return DriveBayIntrusion; + case TRANSITIONTOACTIVE: + return TransitionToActive; + case EISAFAILSAFETIMEOUT: + return EisaFailSafeTimeout; + case IOCARDAREAINTRUSION: + return IoCardAreaIntrusion; + case TRANSITIONTOBUSY: + return TransitionToBusy; + case BUSCORRECTABLEERROR: + return BusCorrectableError; + case PROCESSORAREAINTRUSION: + return ProcessorAreaIntrusion; + case BUSUNCORRECTABLEERROR: + return BusUncorrectableError; + case FATALNMI: + return FatalNmi; + case POWERBUTTONPRESSED: + return PowerButtonPressed; + case SLEEPBUTTONPRESSED: + return SleepButtonPressed; + case FRUNOTINSTALLED: + return FruNotInstalled; + case SLOTCONNECTORFAULTSTATUSASSERTED: + return SlotConnectorFaultStatusAsserted; + case POWERUP: + return PowerUp; + case RESETBUTTONPRESSED: + return ResetButtonPressed; + case COOLINGDEVICE: + return CoolingDevice; + case OTHERUNITSBASEDSENSOR: + return OtherUnitsBasedSensor; + case POSTMEMORYRESIZE: + return PostMemoryResize; + case MODULEBOARD: + return ModuleBoard; + case MICROCONTROLLERCOPROCESSOR: + return MicrocontrollerCoprocessor; + case ADDINCARD: + return AddInCard; + case CHASSIS: + return Chassis; + case OTHERFRU: + return OtherFru; + case TERMINATOR: + return Terminator; + case MONITORASICIC: + return MonitorAsicIc; + default: + logger + .warn( + "Invalid value: " + value + " (" + Integer.toHexString(value) + + ") for sensor " + sensorType); + return Unknown; + } + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/RecordTypes.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/RecordTypes.java index e655aad..0c720dd 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/RecordTypes.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/RecordTypes.java @@ -28,35 +28,33 @@ * Class holding codes for SDR types. Byte constants are encoded as pseudo * unsigned bytes. IpmiLanConstants doesn't use {@link TypeConverter} because * fields need to be runtime constants. - * + * * @see TypeConverter#byteToInt(byte) * @see TypeConverter#intToByte(int) - * */ public final class RecordTypes { - public static final byte FULL_SENSOR_RECORD = 0x01; + public static final byte FULL_SENSOR_RECORD = 0x01; - public static final byte COMPACT_SENSOR_RECORD = 0x02; + public static final byte COMPACT_SENSOR_RECORD = 0x02; - public static final byte EVENT_ONLY_RECORD = 0x03; + public static final byte EVENT_ONLY_RECORD = 0x03; - public static final byte ENTITY_ASSOCIATION_RECORD = 0x08; + public static final byte ENTITY_ASSOCIATION_RECORD = 0x08; - public static final byte DEVICE_RELATIVE_ENTITY_ASSOCIATION_RECORD = 0x09; + public static final byte DEVICE_RELATIVE_ENTITY_ASSOCIATION_RECORD = 0x09; - public static final byte GENERIC_DEVICE_LOCATOR_RECORD = 0x10; + public static final byte GENERIC_DEVICE_LOCATOR_RECORD = 0x10; - public static final byte FRU_DEVICE_LOCATOR_RECORD = 0x11; + public static final byte FRU_DEVICE_LOCATOR_RECORD = 0x11; - public static final byte MANAGEMENT_CONTROLLER_DEVICE_LOCATOR_RECORD = 0x12; + public static final byte MANAGEMENT_CONTROLLER_DEVICE_LOCATOR_RECORD = 0x12; - public static final byte MANAGEMENT_CONTROLLER_CONFIRMATION_RECORD = 0x13; + public static final byte MANAGEMENT_CONTROLLER_CONFIRMATION_RECORD = 0x13; - public static final byte BMC_MESSAGE_CHANNEL_INFO_RECORD = 0x14; + public static final byte BMC_MESSAGE_CHANNEL_INFO_RECORD = 0x14; - public static final byte OEM_RECORD = (byte) (0xc0 - 256); + public static final byte OEM_RECORD = (byte) (0xc0 - 256); - private RecordTypes() { - } + private RecordTypes() {} } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/SensorDirection.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/SensorDirection.java index 18c7c9a..8331fc9 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/SensorDirection.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/SensorDirection.java @@ -28,38 +28,38 @@ * specify whether it is an input voltage or an output voltage. */ public enum SensorDirection { - Unspecified(SensorDirection.UNSPECIFIED), - Input(SensorDirection.INPUT), - Output(SensorDirection.OUTPUT), - Reserved(SensorDirection.RESERVED), ; + Unspecified(SensorDirection.UNSPECIFIED), + Input(SensorDirection.INPUT), + Output(SensorDirection.OUTPUT), + Reserved(SensorDirection.RESERVED),; - private static final int UNSPECIFIED = 0; - private static final int INPUT = 1; - private static final int OUTPUT = 2; - private static final int RESERVED = 3; + private static final int UNSPECIFIED = 0; + private static final int INPUT = 1; + private static final int OUTPUT = 2; + private static final int RESERVED = 3; - private int code; + private int code; - SensorDirection(int code) { - this.code = code; - } + SensorDirection(int code) { + this.code = code; + } - public int getCode() { - return code; - } + public int getCode() { + return code; + } - public static SensorDirection parseInt(int value) { - switch (value) { - case UNSPECIFIED: - return Unspecified; - case INPUT: - return Input; - case OUTPUT: - return Output; - case RESERVED: - return Reserved; - default: - throw new IllegalArgumentException("Invalid value: " + value); - } - } + public static SensorDirection parseInt(int value) { + switch (value) { + case UNSPECIFIED: + return Unspecified; + case INPUT: + return Input; + case OUTPUT: + return Output; + case RESERVED: + return Reserved; + default: + throw new IllegalArgumentException("Invalid value: " + value); + } + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/SensorRecord.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/SensorRecord.java index 17cd9dd..bc77c13 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/SensorRecord.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/SensorRecord.java @@ -31,162 +31,167 @@ */ public abstract class SensorRecord { - private int id; - private int sdrVersion; - private byte recordType; - private int recordLength; - - /** - * Parses sensor record raw data - * @param recordData - * @return {@link SensorRecord} populated with data - * @throws IllegalArgumentException - */ - public static SensorRecord populateSensorRecord(byte[] recordData) { - - if (recordData.length < 5) { - throw new IllegalArgumentException("Record data is too short"); - } - - SensorRecord sensorRecord = null; - - byte recType = recordData[3]; - - switch (recType) { - case RecordTypes.FULL_SENSOR_RECORD:// - sensorRecord = new FullSensorRecord(); - break; - case RecordTypes.BMC_MESSAGE_CHANNEL_INFO_RECORD: - //Deprecated - throw new IllegalArgumentException("This format is deprecated"); - case RecordTypes.COMPACT_SENSOR_RECORD:// - sensorRecord = new CompactSensorRecord(); - break; - case RecordTypes.DEVICE_RELATIVE_ENTITY_ASSOCIATION_RECORD: - // TODO: Test if server with such records will be available - sensorRecord = new DeviceRelativeEntityAssiciationRecord(); - break; - case RecordTypes.ENTITY_ASSOCIATION_RECORD:// - sensorRecord = new EntityAssociationRecord(); - break; - case RecordTypes.EVENT_ONLY_RECORD: - // TODO: Test if server with such records will be available - sensorRecord = new EventOnlyRecord(); - break; - case RecordTypes.FRU_DEVICE_LOCATOR_RECORD:// - sensorRecord = new FruDeviceLocatorRecord(); - break; - case RecordTypes.GENERIC_DEVICE_LOCATOR_RECORD: - //TODO: Test if server with such records will be available - sensorRecord = new GenericDeviceLocatorRecord(); - break; - case RecordTypes.MANAGEMENT_CONTROLLER_CONFIRMATION_RECORD: - //TODO: Test if server with such records will be available - sensorRecord = new ManagementControllerConfirmationRecord(); - break; - case RecordTypes.MANAGEMENT_CONTROLLER_DEVICE_LOCATOR_RECORD:// - sensorRecord = new ManagementControllerDeviceLocatorRecord(); - break; - case RecordTypes.OEM_RECORD:// - sensorRecord = new OemRecord(); - break; - default: - // IPMI 2.0 Table 43-1 reserves C0h-FFh for OEM records; vendors use - // values above C0h (e.g. NVIDIA/GIGABYTE emit D0h). Never abort the - // SDR repository walk on a record type we don't model. - if (TypeConverter.byteToInt(recType) >= TypeConverter.byteToInt(RecordTypes.OEM_RECORD)) { - sensorRecord = new OemRecord(); - break; - } - throw new IllegalArgumentException("Invalid record type: " - + recType); - } - - byte[] buffer = new byte[4]; - - buffer[0] = recordData[0]; - buffer[1] = recordData[1]; - buffer[2] = 0; - buffer[3] = 0; - - sensorRecord.setId(TypeConverter.littleEndianByteArrayToInt(buffer)); - - sensorRecord.setSdrVersion(TypeConverter - .littleEndianBcdByteToInt(recordData[2])); - - sensorRecord.setRecordType(recordData[3]); - - sensorRecord.setRecordLength(TypeConverter.byteToInt(recordData[4])); - - sensorRecord.populateTypeSpecficValues(recordData, sensorRecord); - - return sensorRecord; - } - - /** - * Decodes record data which depends on record type - * - * @param recordData - * - raw data containing whole record - * @param record - * - {@link SensorRecord} being populated - */ - protected abstract void populateTypeSpecficValues(byte[] recordData, - SensorRecord record); - - public void setId(int id) { - this.id = id; - } - - public int getId() { - return id; - } - - public void setSdrVersion(int sdrVersion) { - this.sdrVersion = sdrVersion; - } - - public int getSdrVersion() { - return sdrVersion; - } - - public void setRecordType(byte recordType) { - this.recordType = recordType; - } - - public byte getRecordType() { - return recordType; - } - - public void setRecordLength(int recordLength) { - this.recordLength = recordLength; - } - - public int getRecordLength() { - return recordLength; - } - - /** - * Decodes name encoded in one of the available formats. - * - * @param codingType - * - byte containing Sensor 'ID' String Type - * @param name - * - Sensor ID String bytes - * @return decoded name - */ - protected String decodeName(byte codingType, byte[] name) { - switch ((TypeConverter.byteToInt(codingType) & 0xc0) >> 6) { - case 0: // unicode - return new String(name, Charset.forName("UTF-8")); - case 1: // BCD plus - return TypeConverter.decodeBcdPlus(name); - case 2: // 6-bit packed ASCII - return TypeConverter.decode6bitAscii(name); - case 3: // 8-bit ASCII + Latin 1 - return new String(name, Charset.forName("ISO-8859-1")); - default: - throw new IllegalArgumentException("Invalid coding type."); - } - } + private int id; + private int sdrVersion; + private byte recordType; + private int recordLength; + + /** + * Parses sensor record raw data + * + * @param recordData + * @return {@link SensorRecord} populated with data + * @throws IllegalArgumentException + */ + public static SensorRecord populateSensorRecord(byte[] recordData) { + + if (recordData.length < 5) { + throw new IllegalArgumentException("Record data is too short"); + } + + SensorRecord sensorRecord = null; + + byte recType = recordData[3]; + + switch (recType) { + case RecordTypes.FULL_SENSOR_RECORD:// + sensorRecord = new FullSensorRecord(); + break; + case RecordTypes.BMC_MESSAGE_CHANNEL_INFO_RECORD: + // Deprecated + throw new IllegalArgumentException("This format is deprecated"); + case RecordTypes.COMPACT_SENSOR_RECORD:// + sensorRecord = new CompactSensorRecord(); + break; + case RecordTypes.DEVICE_RELATIVE_ENTITY_ASSOCIATION_RECORD: + // TODO: Test if server with such records will be available + sensorRecord = new DeviceRelativeEntityAssiciationRecord(); + break; + case RecordTypes.ENTITY_ASSOCIATION_RECORD:// + sensorRecord = new EntityAssociationRecord(); + break; + case RecordTypes.EVENT_ONLY_RECORD: + // TODO: Test if server with such records will be available + sensorRecord = new EventOnlyRecord(); + break; + case RecordTypes.FRU_DEVICE_LOCATOR_RECORD:// + sensorRecord = new FruDeviceLocatorRecord(); + break; + case RecordTypes.GENERIC_DEVICE_LOCATOR_RECORD: + // TODO: Test if server with such records will be available + sensorRecord = new GenericDeviceLocatorRecord(); + break; + case RecordTypes.MANAGEMENT_CONTROLLER_CONFIRMATION_RECORD: + // TODO: Test if server with such records will be available + sensorRecord = new ManagementControllerConfirmationRecord(); + break; + case RecordTypes.MANAGEMENT_CONTROLLER_DEVICE_LOCATOR_RECORD:// + sensorRecord = new ManagementControllerDeviceLocatorRecord(); + break; + case RecordTypes.OEM_RECORD:// + sensorRecord = new OemRecord(); + break; + default: + // IPMI 2.0 Table 43-1 reserves C0h-FFh for OEM records; vendors use + // values above C0h (e.g. NVIDIA/GIGABYTE emit D0h). Never abort the + // SDR repository walk on a record type we don't model. + if (TypeConverter.byteToInt(recType) >= TypeConverter.byteToInt(RecordTypes.OEM_RECORD)) { + sensorRecord = new OemRecord(); + break; + } + throw new IllegalArgumentException( + "Invalid record type: " + + recType); + } + + byte[] buffer = new byte[4]; + + buffer[0] = recordData[0]; + buffer[1] = recordData[1]; + buffer[2] = 0; + buffer[3] = 0; + + sensorRecord.setId(TypeConverter.littleEndianByteArrayToInt(buffer)); + + sensorRecord + .setSdrVersion( + TypeConverter + .littleEndianBcdByteToInt(recordData[2])); + + sensorRecord.setRecordType(recordData[3]); + + sensorRecord.setRecordLength(TypeConverter.byteToInt(recordData[4])); + + sensorRecord.populateTypeSpecficValues(recordData, sensorRecord); + + return sensorRecord; + } + + /** + * Decodes record data which depends on record type + * + * @param recordData + * - raw data containing whole record + * @param record + * - {@link SensorRecord} being populated + */ + protected abstract void populateTypeSpecficValues( + byte[] recordData, + SensorRecord record); + + public void setId(int id) { + this.id = id; + } + + public int getId() { + return id; + } + + public void setSdrVersion(int sdrVersion) { + this.sdrVersion = sdrVersion; + } + + public int getSdrVersion() { + return sdrVersion; + } + + public void setRecordType(byte recordType) { + this.recordType = recordType; + } + + public byte getRecordType() { + return recordType; + } + + public void setRecordLength(int recordLength) { + this.recordLength = recordLength; + } + + public int getRecordLength() { + return recordLength; + } + + /** + * Decodes name encoded in one of the available formats. + * + * @param codingType + * - byte containing Sensor 'ID' String Type + * @param name + * - Sensor ID String bytes + * @return decoded name + */ + protected String decodeName(byte codingType, byte[] name) { + switch ((TypeConverter.byteToInt(codingType) & 0xc0) >> 6) { + case 0: // unicode + return new String(name, Charset.forName("UTF-8")); + case 1: // BCD plus + return TypeConverter.decodeBcdPlus(name); + case 2: // 6-bit packed ASCII + return TypeConverter.decode6bitAscii(name); + case 3: // 8-bit ASCII + Latin 1 + return new String(name, Charset.forName("ISO-8859-1")); + default: + throw new IllegalArgumentException("Invalid coding type."); + } + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/SensorType.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/SensorType.java index 9bf5d4d..18eb0ce 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/SensorType.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/SensorType.java @@ -30,208 +30,209 @@ */ public enum SensorType { - CoolingDevice(SensorType.COOLINGDEVICE), - OtherUnitsBasedSensor(SensorType.OTHERUNITSBASEDSENSOR), - Memory(SensorType.MEMORY), - DriveBay(SensorType.DRIVEBAY), - PostMemoryResize(SensorType.POSTMEMORYRESIZE), - SystemFirmwareProgess(SensorType.SYSTEMFIRMWAREPROGESS), - EventLoggingDisabled(SensorType.EVENTLOGGINGDISABLED), - BootError(SensorType.BOOTERROR), - Watchdog1(SensorType.WATCHDOG1), - OsBoot(SensorType.OSBOOT), - SystemEvent(SensorType.SYSTEMEVENT), - OsStop(SensorType.OSSTOP), - CriticalInterrupt(SensorType.CRITICALINTERRUPT), - SlotConnector(SensorType.SLOTCONNECTOR), - SystemAcpiPowerState(SensorType.SYSTEMACPIPOWERSTATE), - Watchdog2(SensorType.WATCHDOG2), - PlatformAlert(SensorType.PLATFORMALERT), - EntityPresence(SensorType.ENTITYPRESENCE), - MonitorAsicIc(SensorType.MONITORASICIC), - Lan(SensorType.LAN), - Temperature(SensorType.TEMPERATURE), - Voltage(SensorType.VOLTAGE), - Current(SensorType.CURRENT), - Fan(SensorType.FAN), - PhysicalSecurity(SensorType.PHYSICALSECURITY), - PlatformSecurityViolationAttempt(SensorType.PLATFORMSECURITYVIOLATIONATTEMPT), - Processor(SensorType.PROCESSOR), - PowerSupply(SensorType.POWERSUPPLY), - PowerUnit(SensorType.POWERUNIT), - ButtonSwitch(SensorType.BUTTONSWITCH), - ModuleBoard(SensorType.MODULEBOARD), - MicrocontrollerCoprocessor(SensorType.MICROCONTROLLERCOPROCESSOR), - AddInCard(SensorType.ADDINCARD), - Chassis(SensorType.CHASSIS), - Chipset(SensorType.CHIPSET), - OtherFru(SensorType.OTHERFRU), - ManagementSubsystemHealth(SensorType.MANAGEMENTSUBSYSTEMHEALTH), - CableInterconnect(SensorType.CABLEINTERCONNECT), - Battery(SensorType.BATTERY), - Terminator(SensorType.TERMINATOR), - SessionAudit(SensorType.SESSIONAUDIT), - SystemBoot(SensorType.SYSTEMBOOT), - VersionChange(SensorType.VERSIONCHANGE), - FruState(SensorType.FRUSTATE), - Oem(SensorType.OEM), - OemReserved(SensorType.OEMRESERVED) - ; + CoolingDevice(SensorType.COOLINGDEVICE), + OtherUnitsBasedSensor(SensorType.OTHERUNITSBASEDSENSOR), + Memory(SensorType.MEMORY), + DriveBay(SensorType.DRIVEBAY), + PostMemoryResize(SensorType.POSTMEMORYRESIZE), + SystemFirmwareProgess(SensorType.SYSTEMFIRMWAREPROGESS), + EventLoggingDisabled(SensorType.EVENTLOGGINGDISABLED), + BootError(SensorType.BOOTERROR), + Watchdog1(SensorType.WATCHDOG1), + OsBoot(SensorType.OSBOOT), + SystemEvent(SensorType.SYSTEMEVENT), + OsStop(SensorType.OSSTOP), + CriticalInterrupt(SensorType.CRITICALINTERRUPT), + SlotConnector(SensorType.SLOTCONNECTOR), + SystemAcpiPowerState(SensorType.SYSTEMACPIPOWERSTATE), + Watchdog2(SensorType.WATCHDOG2), + PlatformAlert(SensorType.PLATFORMALERT), + EntityPresence(SensorType.ENTITYPRESENCE), + MonitorAsicIc(SensorType.MONITORASICIC), + Lan(SensorType.LAN), + Temperature(SensorType.TEMPERATURE), + Voltage(SensorType.VOLTAGE), + Current(SensorType.CURRENT), + Fan(SensorType.FAN), + PhysicalSecurity(SensorType.PHYSICALSECURITY), + PlatformSecurityViolationAttempt(SensorType.PLATFORMSECURITYVIOLATIONATTEMPT), + Processor(SensorType.PROCESSOR), + PowerSupply(SensorType.POWERSUPPLY), + PowerUnit(SensorType.POWERUNIT), + ButtonSwitch(SensorType.BUTTONSWITCH), + ModuleBoard(SensorType.MODULEBOARD), + MicrocontrollerCoprocessor(SensorType.MICROCONTROLLERCOPROCESSOR), + AddInCard(SensorType.ADDINCARD), + Chassis(SensorType.CHASSIS), + Chipset(SensorType.CHIPSET), + OtherFru(SensorType.OTHERFRU), + ManagementSubsystemHealth(SensorType.MANAGEMENTSUBSYSTEMHEALTH), + CableInterconnect(SensorType.CABLEINTERCONNECT), + Battery(SensorType.BATTERY), + Terminator(SensorType.TERMINATOR), + SessionAudit(SensorType.SESSIONAUDIT), + SystemBoot(SensorType.SYSTEMBOOT), + VersionChange(SensorType.VERSIONCHANGE), + FruState(SensorType.FRUSTATE), + Oem(SensorType.OEM), + OemReserved(SensorType.OEMRESERVED); - private static final int COOLINGDEVICE = 10; - private static final int OTHERUNITSBASEDSENSOR = 11; - private static final int MEMORY = 12; - private static final int DRIVEBAY = 13; - private static final int POSTMEMORYRESIZE = 14; - private static final int SYSTEMFIRMWAREPROGESS = 15; - private static final int EVENTLOGGINGDISABLED = 16; - private static final int BOOTERROR = 30; - private static final int WATCHDOG1 = 17; - private static final int OSBOOT = 31; - private static final int SYSTEMEVENT = 18; - private static final int OSSTOP = 32; - private static final int CRITICALINTERRUPT = 19; - private static final int SLOTCONNECTOR = 33; - private static final int SYSTEMACPIPOWERSTATE = 34; - private static final int WATCHDOG2 = 35; - private static final int PLATFORMALERT = 36; - private static final int ENTITYPRESENCE = 37; - private static final int MONITORASICIC = 38; - private static final int LAN = 39; - private static final int TEMPERATURE = 1; - private static final int VOLTAGE = 2; - private static final int CURRENT = 3; - private static final int FAN = 4; - private static final int PHYSICALSECURITY = 5; - private static final int PLATFORMSECURITYVIOLATIONATTEMPT = 6; - private static final int PROCESSOR = 7; - private static final int POWERSUPPLY = 8; - private static final int POWERUNIT = 9; - private static final int BUTTONSWITCH = 20; - private static final int MODULEBOARD = 21; - private static final int MICROCONTROLLERCOPROCESSOR = 22; - private static final int ADDINCARD = 23; - private static final int CHASSIS = 24; - private static final int CHIPSET = 25; - private static final int OTHERFRU = 26; - private static final int MANAGEMENTSUBSYSTEMHEALTH = 40; - private static final int CABLEINTERCONNECT = 27; - private static final int BATTERY = 41; - private static final int TERMINATOR = 28; - private static final int SESSIONAUDIT = 42; - private static final int SYSTEMBOOT = 29; - private static final int VERSIONCHANGE = 43; - private static final int FRUSTATE = 44; - private static final int OEM = 192; - private static final int OEMRESERVED = 118; + private static final int COOLINGDEVICE = 10; + private static final int OTHERUNITSBASEDSENSOR = 11; + private static final int MEMORY = 12; + private static final int DRIVEBAY = 13; + private static final int POSTMEMORYRESIZE = 14; + private static final int SYSTEMFIRMWAREPROGESS = 15; + private static final int EVENTLOGGINGDISABLED = 16; + private static final int BOOTERROR = 30; + private static final int WATCHDOG1 = 17; + private static final int OSBOOT = 31; + private static final int SYSTEMEVENT = 18; + private static final int OSSTOP = 32; + private static final int CRITICALINTERRUPT = 19; + private static final int SLOTCONNECTOR = 33; + private static final int SYSTEMACPIPOWERSTATE = 34; + private static final int WATCHDOG2 = 35; + private static final int PLATFORMALERT = 36; + private static final int ENTITYPRESENCE = 37; + private static final int MONITORASICIC = 38; + private static final int LAN = 39; + private static final int TEMPERATURE = 1; + private static final int VOLTAGE = 2; + private static final int CURRENT = 3; + private static final int FAN = 4; + private static final int PHYSICALSECURITY = 5; + private static final int PLATFORMSECURITYVIOLATIONATTEMPT = 6; + private static final int PROCESSOR = 7; + private static final int POWERSUPPLY = 8; + private static final int POWERUNIT = 9; + private static final int BUTTONSWITCH = 20; + private static final int MODULEBOARD = 21; + private static final int MICROCONTROLLERCOPROCESSOR = 22; + private static final int ADDINCARD = 23; + private static final int CHASSIS = 24; + private static final int CHIPSET = 25; + private static final int OTHERFRU = 26; + private static final int MANAGEMENTSUBSYSTEMHEALTH = 40; + private static final int CABLEINTERCONNECT = 27; + private static final int BATTERY = 41; + private static final int TERMINATOR = 28; + private static final int SESSIONAUDIT = 42; + private static final int SYSTEMBOOT = 29; + private static final int VERSIONCHANGE = 43; + private static final int FRUSTATE = 44; + private static final int OEM = 192; + private static final int OEMRESERVED = 118; - private int code; - private static Logger logger = LoggerFactory.getLogger(SensorType.class); + private int code; + private static Logger logger = LoggerFactory.getLogger(SensorType.class); - SensorType(int code) { - this.code = code; - } - public int getCode() { - return code; - } - public static SensorType parseInt(int value) { - switch(value) { - case COOLINGDEVICE: - return CoolingDevice; - case OTHERUNITSBASEDSENSOR: - return OtherUnitsBasedSensor; - case MEMORY: - return Memory; - case DRIVEBAY: - return DriveBay; - case POSTMEMORYRESIZE: - return PostMemoryResize; - case SYSTEMFIRMWAREPROGESS: - return SystemFirmwareProgess; - case EVENTLOGGINGDISABLED: - return EventLoggingDisabled; - case BOOTERROR: - return BootError; - case WATCHDOG1: - return Watchdog1; - case OSBOOT: - return OsBoot; - case SYSTEMEVENT: - return SystemEvent; - case OSSTOP: - return OsStop; - case CRITICALINTERRUPT: - return CriticalInterrupt; - case SLOTCONNECTOR: - return SlotConnector; - case SYSTEMACPIPOWERSTATE: - return SystemAcpiPowerState; - case WATCHDOG2: - return Watchdog2; - case PLATFORMALERT: - return PlatformAlert; - case ENTITYPRESENCE: - return EntityPresence; - case MONITORASICIC: - return MonitorAsicIc; - case LAN: - return Lan; - case TEMPERATURE: - return Temperature; - case VOLTAGE: - return Voltage; - case CURRENT: - return Current; - case FAN: - return Fan; - case PHYSICALSECURITY: - return PhysicalSecurity; - case PLATFORMSECURITYVIOLATIONATTEMPT: - return PlatformSecurityViolationAttempt; - case PROCESSOR: - return Processor; - case POWERSUPPLY: - return PowerSupply; - case POWERUNIT: - return PowerUnit; - case BUTTONSWITCH: - return ButtonSwitch; - case MODULEBOARD: - return ModuleBoard; - case MICROCONTROLLERCOPROCESSOR: - return MicrocontrollerCoprocessor; - case ADDINCARD: - return AddInCard; - case CHASSIS: - return Chassis; - case CHIPSET: - return Chipset; - case OTHERFRU: - return OtherFru; - case MANAGEMENTSUBSYSTEMHEALTH: - return ManagementSubsystemHealth; - case CABLEINTERCONNECT: - return CableInterconnect; - case BATTERY: - return Battery; - case TERMINATOR: - return Terminator; - case SESSIONAUDIT: - return SessionAudit; - case SYSTEMBOOT: - return SystemBoot; - case VERSIONCHANGE: - return VersionChange; - case FRUSTATE: - return FruState; - case OEMRESERVED: - return OemReserved; - default: - if(value >= OEM) { - return Oem; - } - logger.error("Invalid value: " + value); - return Oem; - } - } + SensorType(int code) { + this.code = code; + } + + public int getCode() { + return code; + } + + public static SensorType parseInt(int value) { + switch (value) { + case COOLINGDEVICE: + return CoolingDevice; + case OTHERUNITSBASEDSENSOR: + return OtherUnitsBasedSensor; + case MEMORY: + return Memory; + case DRIVEBAY: + return DriveBay; + case POSTMEMORYRESIZE: + return PostMemoryResize; + case SYSTEMFIRMWAREPROGESS: + return SystemFirmwareProgess; + case EVENTLOGGINGDISABLED: + return EventLoggingDisabled; + case BOOTERROR: + return BootError; + case WATCHDOG1: + return Watchdog1; + case OSBOOT: + return OsBoot; + case SYSTEMEVENT: + return SystemEvent; + case OSSTOP: + return OsStop; + case CRITICALINTERRUPT: + return CriticalInterrupt; + case SLOTCONNECTOR: + return SlotConnector; + case SYSTEMACPIPOWERSTATE: + return SystemAcpiPowerState; + case WATCHDOG2: + return Watchdog2; + case PLATFORMALERT: + return PlatformAlert; + case ENTITYPRESENCE: + return EntityPresence; + case MONITORASICIC: + return MonitorAsicIc; + case LAN: + return Lan; + case TEMPERATURE: + return Temperature; + case VOLTAGE: + return Voltage; + case CURRENT: + return Current; + case FAN: + return Fan; + case PHYSICALSECURITY: + return PhysicalSecurity; + case PLATFORMSECURITYVIOLATIONATTEMPT: + return PlatformSecurityViolationAttempt; + case PROCESSOR: + return Processor; + case POWERSUPPLY: + return PowerSupply; + case POWERUNIT: + return PowerUnit; + case BUTTONSWITCH: + return ButtonSwitch; + case MODULEBOARD: + return ModuleBoard; + case MICROCONTROLLERCOPROCESSOR: + return MicrocontrollerCoprocessor; + case ADDINCARD: + return AddInCard; + case CHASSIS: + return Chassis; + case CHIPSET: + return Chipset; + case OTHERFRU: + return OtherFru; + case MANAGEMENTSUBSYSTEMHEALTH: + return ManagementSubsystemHealth; + case CABLEINTERCONNECT: + return CableInterconnect; + case BATTERY: + return Battery; + case TERMINATOR: + return Terminator; + case SESSIONAUDIT: + return SessionAudit; + case SYSTEMBOOT: + return SystemBoot; + case VERSIONCHANGE: + return VersionChange; + case FRUSTATE: + return FruState; + case OEMRESERVED: + return OemReserved; + default: + if (value >= OEM) { + return Oem; + } + logger.error("Invalid value: " + value); + return Oem; + } + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/SensorUnit.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/SensorUnit.java index b3070b2..5ed5c76 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/SensorUnit.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/SensorUnit.java @@ -24,422 +24,516 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; + /** * Specifies available units for sensors' measurements. */ public enum SensorUnit { - Nits(SensorUnit.NITS), Lumen(SensorUnit.LUMEN), Lux(SensorUnit.LUX), Candela(SensorUnit.CANDELA), kPa( - SensorUnit.KPA), Psi(SensorUnit.PSI), Newton(SensorUnit.NEWTON), CuIn(SensorUnit.CUIN), Cfm(SensorUnit.CFM), Cufeet( - SensorUnit.CUFEET), Rpm(SensorUnit.RPM), mm(SensorUnit.MM), Hz(SensorUnit.HZ), cm(SensorUnit.CM), m( - SensorUnit.M), CuCm(SensorUnit.CUCM), CuM(SensorUnit.CUM), Henry(SensorUnit.HENRY), Liters( - SensorUnit.LITERS), Millihenry(SensorUnit.MILLIHENRY), FluidOunce(SensorUnit.FLUIDOUNCE), Farad( - SensorUnit.FARAD), Radians(SensorUnit.RADIANS), Microfarad(SensorUnit.MICROFARAD), Ohms(SensorUnit.OHMS), Siemens( - SensorUnit.SIEMENS), Unspecified(SensorUnit.UNSPECIFIED), Mole(SensorUnit.MOLE), DegreesC( - SensorUnit.DEGREESC), Becquerel(SensorUnit.BECQUEREL), Byte(SensorUnit.BYTE), DegreesF(SensorUnit.DEGREESF), PartsPerMilion( - SensorUnit.PARTSPERMILION), DegreesK(SensorUnit.DEGREESK), Kilobyte(SensorUnit.KILOBYTE), Megabyte( - SensorUnit.MEGABYTE), Volts(SensorUnit.VOLTS), Gigabyte(SensorUnit.GIGABYTE), Amps(SensorUnit.AMPS), Word( - SensorUnit.WORD), Watts(SensorUnit.WATTS), Dword(SensorUnit.DWORD), Joules(SensorUnit.JOULES), Qword( - SensorUnit.QWORD), Coulombs(SensorUnit.COULOMBS), UncorrectableError(SensorUnit.UNCORRECTABLEERROR), Line( - SensorUnit.LINE), Va(SensorUnit.VA), FatalError(SensorUnit.FATALERROR), Hit(SensorUnit.HIT), Grams( - SensorUnit.GRAMS), Miss(SensorUnit.MISS), Microsecond(SensorUnit.MICROSECOND), Millisecond( - SensorUnit.MILLISECOND), Second(SensorUnit.SECOND), Minute(SensorUnit.MINUTE), Hour(SensorUnit.HOUR), Day( - SensorUnit.DAY), Week(SensorUnit.WEEK), Mil(SensorUnit.MIL), Steradians(SensorUnit.STERADIANS), Inches( - SensorUnit.INCHES), Revolutions(SensorUnit.REVOLUTIONS), Feet(SensorUnit.FEET), Cycles(SensorUnit.CYCLES), Gravities( - SensorUnit.GRAVITIES), Ounce(SensorUnit.OUNCE), Pound(SensorUnit.POUND), FtLb(SensorUnit.FTLB), Decibels( - SensorUnit.DECIBELS), OzIn(SensorUnit.OZIN), DbA(SensorUnit.DBA), Gauss(SensorUnit.GAUSS), DbC( - SensorUnit.DBC), Gilberts(SensorUnit.GILBERTS), Gray(SensorUnit.GRAY), Sievert(SensorUnit.SIEVERT), ColorTempDegK( - SensorUnit.COLORTEMPDEGK), bit(SensorUnit.BIT), kilobit(SensorUnit.KILOBIT), Retry(SensorUnit.RETRY), Reset( - SensorUnit.RESET), Megabit(SensorUnit.MEGABIT), OverrunOverflow(SensorUnit.OVERRUNOVERFLOW), Gigabit( - SensorUnit.GIGABIT), Underrun(SensorUnit.UNDERRUN), Collision(SensorUnit.COLLISION), Packets( - SensorUnit.PACKETS), Messages(SensorUnit.MESSAGES), Characters(SensorUnit.CHARACTERS), Error( - SensorUnit.ERROR), CorrectableError(SensorUnit.CORRECTABLEERROR), Other(SensorUnit.OTHER), ; - private static final int NITS = 10; + Nits(SensorUnit.NITS), + Lumen(SensorUnit.LUMEN), + Lux(SensorUnit.LUX), + Candela(SensorUnit.CANDELA), + kPa( + SensorUnit.KPA), + Psi(SensorUnit.PSI), + Newton(SensorUnit.NEWTON), + CuIn(SensorUnit.CUIN), + Cfm(SensorUnit.CFM), + Cufeet( + SensorUnit.CUFEET), + Rpm(SensorUnit.RPM), + mm(SensorUnit.MM), + Hz(SensorUnit.HZ), + cm(SensorUnit.CM), + m( + SensorUnit.M), + CuCm(SensorUnit.CUCM), + CuM(SensorUnit.CUM), + Henry(SensorUnit.HENRY), + Liters( + SensorUnit.LITERS), + Millihenry(SensorUnit.MILLIHENRY), + FluidOunce(SensorUnit.FLUIDOUNCE), + Farad( + SensorUnit.FARAD), + Radians(SensorUnit.RADIANS), + Microfarad(SensorUnit.MICROFARAD), + Ohms(SensorUnit.OHMS), + Siemens( + SensorUnit.SIEMENS), + Unspecified(SensorUnit.UNSPECIFIED), + Mole(SensorUnit.MOLE), + DegreesC( + SensorUnit.DEGREESC), + Becquerel(SensorUnit.BECQUEREL), + Byte(SensorUnit.BYTE), + DegreesF(SensorUnit.DEGREESF), + PartsPerMilion( + SensorUnit.PARTSPERMILION), + DegreesK(SensorUnit.DEGREESK), + Kilobyte(SensorUnit.KILOBYTE), + Megabyte( + SensorUnit.MEGABYTE), + Volts(SensorUnit.VOLTS), + Gigabyte(SensorUnit.GIGABYTE), + Amps(SensorUnit.AMPS), + Word( + SensorUnit.WORD), + Watts(SensorUnit.WATTS), + Dword(SensorUnit.DWORD), + Joules(SensorUnit.JOULES), + Qword( + SensorUnit.QWORD), + Coulombs(SensorUnit.COULOMBS), + UncorrectableError(SensorUnit.UNCORRECTABLEERROR), + Line( + SensorUnit.LINE), + Va(SensorUnit.VA), + FatalError(SensorUnit.FATALERROR), + Hit(SensorUnit.HIT), + Grams( + SensorUnit.GRAMS), + Miss(SensorUnit.MISS), + Microsecond(SensorUnit.MICROSECOND), + Millisecond( + SensorUnit.MILLISECOND), + Second(SensorUnit.SECOND), + Minute(SensorUnit.MINUTE), + Hour(SensorUnit.HOUR), + Day( + SensorUnit.DAY), + Week(SensorUnit.WEEK), + Mil(SensorUnit.MIL), + Steradians(SensorUnit.STERADIANS), + Inches( + SensorUnit.INCHES), + Revolutions(SensorUnit.REVOLUTIONS), + Feet(SensorUnit.FEET), + Cycles(SensorUnit.CYCLES), + Gravities( + SensorUnit.GRAVITIES), + Ounce(SensorUnit.OUNCE), + Pound(SensorUnit.POUND), + FtLb(SensorUnit.FTLB), + Decibels( + SensorUnit.DECIBELS), + OzIn(SensorUnit.OZIN), + DbA(SensorUnit.DBA), + Gauss(SensorUnit.GAUSS), + DbC( + SensorUnit.DBC), + Gilberts(SensorUnit.GILBERTS), + Gray(SensorUnit.GRAY), + Sievert(SensorUnit.SIEVERT), + ColorTempDegK( + SensorUnit.COLORTEMPDEGK), + bit(SensorUnit.BIT), + kilobit(SensorUnit.KILOBIT), + Retry(SensorUnit.RETRY), + Reset( + SensorUnit.RESET), + Megabit(SensorUnit.MEGABIT), + OverrunOverflow(SensorUnit.OVERRUNOVERFLOW), + Gigabit( + SensorUnit.GIGABIT), + Underrun(SensorUnit.UNDERRUN), + Collision(SensorUnit.COLLISION), + Packets( + SensorUnit.PACKETS), + Messages(SensorUnit.MESSAGES), + Characters(SensorUnit.CHARACTERS), + Error( + SensorUnit.ERROR), + CorrectableError(SensorUnit.CORRECTABLEERROR), + Other(SensorUnit.OTHER),; + + private static final int NITS = 10; - private static final int LUMEN = 11; + private static final int LUMEN = 11; - private static final int LUX = 12; + private static final int LUX = 12; - private static final int CANDELA = 13; + private static final int CANDELA = 13; - private static final int KPA = 14; + private static final int KPA = 14; - private static final int PSI = 15; + private static final int PSI = 15; - private static final int NEWTON = 16; + private static final int NEWTON = 16; - private static final int CUIN = 30; + private static final int CUIN = 30; - private static final int CFM = 17; + private static final int CFM = 17; - private static final int CUFEET = 31; + private static final int CUFEET = 31; - private static final int RPM = 18; + private static final int RPM = 18; - private static final int MM = 32; + private static final int MM = 32; - private static final int HZ = 19; + private static final int HZ = 19; - private static final int CM = 33; + private static final int CM = 33; - private static final int M = 34; + private static final int M = 34; - private static final int CUCM = 35; + private static final int CUCM = 35; - private static final int CUM = 36; + private static final int CUM = 36; - private static final int HENRY = 50; + private static final int HENRY = 50; - private static final int LITERS = 37; + private static final int LITERS = 37; - private static final int MILLIHENRY = 51; + private static final int MILLIHENRY = 51; - private static final int FLUIDOUNCE = 38; + private static final int FLUIDOUNCE = 38; - private static final int FARAD = 52; + private static final int FARAD = 52; - private static final int RADIANS = 39; + private static final int RADIANS = 39; - private static final int MICROFARAD = 53; + private static final int MICROFARAD = 53; - private static final int OHMS = 54; + private static final int OHMS = 54; - private static final int SIEMENS = 55; + private static final int SIEMENS = 55; - private static final int UNSPECIFIED = 0; + private static final int UNSPECIFIED = 0; - private static final int MOLE = 56; + private static final int MOLE = 56; - private static final int DEGREESC = 1; + private static final int DEGREESC = 1; - private static final int BECQUEREL = 57; + private static final int BECQUEREL = 57; - private static final int BYTE = 70; + private static final int BYTE = 70; - private static final int DEGREESF = 2; + private static final int DEGREESF = 2; - private static final int PARTSPERMILION = 58; + private static final int PARTSPERMILION = 58; - private static final int DEGREESK = 3; + private static final int DEGREESK = 3; - private static final int KILOBYTE = 71; + private static final int KILOBYTE = 71; - private static final int MEGABYTE = 72; + private static final int MEGABYTE = 72; - private static final int VOLTS = 4; + private static final int VOLTS = 4; - private static final int GIGABYTE = 73; + private static final int GIGABYTE = 73; - private static final int AMPS = 5; + private static final int AMPS = 5; - private static final int WORD = 74; + private static final int WORD = 74; - private static final int WATTS = 6; + private static final int WATTS = 6; - private static final int DWORD = 75; + private static final int DWORD = 75; - private static final int JOULES = 7; + private static final int JOULES = 7; - private static final int QWORD = 76; + private static final int QWORD = 76; - private static final int COULOMBS = 8; + private static final int COULOMBS = 8; - private static final int UNCORRECTABLEERROR = 90; + private static final int UNCORRECTABLEERROR = 90; - private static final int LINE = 77; + private static final int LINE = 77; - private static final int VA = 9; + private static final int VA = 9; - private static final int FATALERROR = 91; + private static final int FATALERROR = 91; - private static final int HIT = 78; + private static final int HIT = 78; - private static final int GRAMS = 92; + private static final int GRAMS = 92; - private static final int MISS = 79; + private static final int MISS = 79; - private static final int MICROSECOND = 20; + private static final int MICROSECOND = 20; - private static final int MILLISECOND = 21; + private static final int MILLISECOND = 21; - private static final int SECOND = 22; + private static final int SECOND = 22; - private static final int MINUTE = 23; + private static final int MINUTE = 23; - private static final int HOUR = 24; + private static final int HOUR = 24; - private static final int DAY = 25; + private static final int DAY = 25; - private static final int WEEK = 26; + private static final int WEEK = 26; - private static final int MIL = 27; + private static final int MIL = 27; - private static final int STERADIANS = 40; + private static final int STERADIANS = 40; - private static final int INCHES = 28; + private static final int INCHES = 28; - private static final int REVOLUTIONS = 41; + private static final int REVOLUTIONS = 41; - private static final int FEET = 29; + private static final int FEET = 29; - private static final int CYCLES = 42; + private static final int CYCLES = 42; - private static final int GRAVITIES = 43; + private static final int GRAVITIES = 43; - private static final int OUNCE = 44; + private static final int OUNCE = 44; - private static final int POUND = 45; + private static final int POUND = 45; - private static final int FTLB = 46; + private static final int FTLB = 46; - private static final int DECIBELS = 60; + private static final int DECIBELS = 60; - private static final int OZIN = 47; + private static final int OZIN = 47; - private static final int DBA = 61; + private static final int DBA = 61; - private static final int GAUSS = 48; + private static final int GAUSS = 48; - private static final int DBC = 62; + private static final int DBC = 62; - private static final int GILBERTS = 49; + private static final int GILBERTS = 49; - private static final int GRAY = 63; + private static final int GRAY = 63; - private static final int SIEVERT = 64; + private static final int SIEVERT = 64; - private static final int COLORTEMPDEGK = 65; + private static final int COLORTEMPDEGK = 65; - private static final int BIT = 66; + private static final int BIT = 66; - private static final int KILOBIT = 67; + private static final int KILOBIT = 67; - private static final int RETRY = 80; + private static final int RETRY = 80; - private static final int RESET = 81; + private static final int RESET = 81; - private static final int MEGABIT = 68; + private static final int MEGABIT = 68; - private static final int OVERRUNOVERFLOW = 82; + private static final int OVERRUNOVERFLOW = 82; - private static final int GIGABIT = 69; + private static final int GIGABIT = 69; - private static final int UNDERRUN = 83; + private static final int UNDERRUN = 83; - private static final int COLLISION = 84; + private static final int COLLISION = 84; - private static final int PACKETS = 85; + private static final int PACKETS = 85; - private static final int MESSAGES = 86; + private static final int MESSAGES = 86; - private static final int CHARACTERS = 87; + private static final int CHARACTERS = 87; - private static final int ERROR = 88; + private static final int ERROR = 88; - private static final int CORRECTABLEERROR = 89; + private static final int CORRECTABLEERROR = 89; - private static final int OTHER = 0; + private static final int OTHER = 0; - private static Logger logger = LoggerFactory.getLogger(SensorUnit.class); + private static Logger logger = LoggerFactory.getLogger(SensorUnit.class); - private int code; + private int code; - SensorUnit(int code) { - this.code = code; - } + SensorUnit(int code) { + this.code = code; + } - public int getCode() { - return code; - } - - public static SensorUnit parseInt(int value) { - switch (value) { - case NITS: - return Nits; - case LUMEN: - return Lumen; - case LUX: - return Lux; - case CANDELA: - return Candela; - case KPA: - return kPa; - case PSI: - return Psi; - case NEWTON: - return Newton; - case CUIN: - return CuIn; - case CFM: - return Cfm; - case CUFEET: - return Cufeet; - case RPM: - return Rpm; - case MM: - return mm; - case HZ: - return Hz; - case CM: - return cm; - case M: - return m; - case CUCM: - return CuCm; - case CUM: - return CuM; - case HENRY: - return Henry; - case LITERS: - return Liters; - case MILLIHENRY: - return Millihenry; - case FLUIDOUNCE: - return FluidOunce; - case FARAD: - return Farad; - case RADIANS: - return Radians; - case MICROFARAD: - return Microfarad; - case OHMS: - return Ohms; - case SIEMENS: - return Siemens; - case UNSPECIFIED: - return Unspecified; - case MOLE: - return Mole; - case DEGREESC: - return DegreesC; - case BECQUEREL: - return Becquerel; - case BYTE: - return Byte; - case DEGREESF: - return DegreesF; - case PARTSPERMILION: - return PartsPerMilion; - case DEGREESK: - return DegreesK; - case KILOBYTE: - return Kilobyte; - case MEGABYTE: - return Megabyte; - case VOLTS: - return Volts; - case GIGABYTE: - return Gigabyte; - case AMPS: - return Amps; - case WORD: - return Word; - case WATTS: - return Watts; - case DWORD: - return Dword; - case JOULES: - return Joules; - case QWORD: - return Qword; - case COULOMBS: - return Coulombs; - case UNCORRECTABLEERROR: - return UncorrectableError; - case LINE: - return Line; - case VA: - return Va; - case FATALERROR: - return FatalError; - case HIT: - return Hit; - case GRAMS: - return Grams; - case MISS: - return Miss; - case MICROSECOND: - return Microsecond; - case MILLISECOND: - return Millisecond; - case SECOND: - return Second; - case MINUTE: - return Minute; - case HOUR: - return Hour; - case DAY: - return Day; - case WEEK: - return Week; - case MIL: - return Mil; - case STERADIANS: - return Steradians; - case INCHES: - return Inches; - case REVOLUTIONS: - return Revolutions; - case FEET: - return Feet; - case CYCLES: - return Cycles; - case GRAVITIES: - return Gravities; - case OUNCE: - return Ounce; - case POUND: - return Pound; - case FTLB: - return FtLb; - case DECIBELS: - return Decibels; - case OZIN: - return OzIn; - case DBA: - return DbA; - case GAUSS: - return Gauss; - case DBC: - return DbC; - case GILBERTS: - return Gilberts; - case GRAY: - return Gray; - case SIEVERT: - return Sievert; - case COLORTEMPDEGK: - return ColorTempDegK; - case BIT: - return bit; - case KILOBIT: - return kilobit; - case RETRY: - return Retry; - case RESET: - return Reset; - case MEGABIT: - return Megabit; - case OVERRUNOVERFLOW: - return OverrunOverflow; - case GIGABIT: - return Gigabit; - case UNDERRUN: - return Underrun; - case COLLISION: - return Collision; - case PACKETS: - return Packets; - case MESSAGES: - return Messages; - case CHARACTERS: - return Characters; - case ERROR: - return Error; - case CORRECTABLEERROR: - return CorrectableError; - default: - logger.error("Invalid value: " + value); - return Other; - } - } + public int getCode() { + return code; + } + + public static SensorUnit parseInt(int value) { + switch (value) { + case NITS: + return Nits; + case LUMEN: + return Lumen; + case LUX: + return Lux; + case CANDELA: + return Candela; + case KPA: + return kPa; + case PSI: + return Psi; + case NEWTON: + return Newton; + case CUIN: + return CuIn; + case CFM: + return Cfm; + case CUFEET: + return Cufeet; + case RPM: + return Rpm; + case MM: + return mm; + case HZ: + return Hz; + case CM: + return cm; + case M: + return m; + case CUCM: + return CuCm; + case CUM: + return CuM; + case HENRY: + return Henry; + case LITERS: + return Liters; + case MILLIHENRY: + return Millihenry; + case FLUIDOUNCE: + return FluidOunce; + case FARAD: + return Farad; + case RADIANS: + return Radians; + case MICROFARAD: + return Microfarad; + case OHMS: + return Ohms; + case SIEMENS: + return Siemens; + case UNSPECIFIED: + return Unspecified; + case MOLE: + return Mole; + case DEGREESC: + return DegreesC; + case BECQUEREL: + return Becquerel; + case BYTE: + return Byte; + case DEGREESF: + return DegreesF; + case PARTSPERMILION: + return PartsPerMilion; + case DEGREESK: + return DegreesK; + case KILOBYTE: + return Kilobyte; + case MEGABYTE: + return Megabyte; + case VOLTS: + return Volts; + case GIGABYTE: + return Gigabyte; + case AMPS: + return Amps; + case WORD: + return Word; + case WATTS: + return Watts; + case DWORD: + return Dword; + case JOULES: + return Joules; + case QWORD: + return Qword; + case COULOMBS: + return Coulombs; + case UNCORRECTABLEERROR: + return UncorrectableError; + case LINE: + return Line; + case VA: + return Va; + case FATALERROR: + return FatalError; + case HIT: + return Hit; + case GRAMS: + return Grams; + case MISS: + return Miss; + case MICROSECOND: + return Microsecond; + case MILLISECOND: + return Millisecond; + case SECOND: + return Second; + case MINUTE: + return Minute; + case HOUR: + return Hour; + case DAY: + return Day; + case WEEK: + return Week; + case MIL: + return Mil; + case STERADIANS: + return Steradians; + case INCHES: + return Inches; + case REVOLUTIONS: + return Revolutions; + case FEET: + return Feet; + case CYCLES: + return Cycles; + case GRAVITIES: + return Gravities; + case OUNCE: + return Ounce; + case POUND: + return Pound; + case FTLB: + return FtLb; + case DECIBELS: + return Decibels; + case OZIN: + return OzIn; + case DBA: + return DbA; + case GAUSS: + return Gauss; + case DBC: + return DbC; + case GILBERTS: + return Gilberts; + case GRAY: + return Gray; + case SIEVERT: + return Sievert; + case COLORTEMPDEGK: + return ColorTempDegK; + case BIT: + return bit; + case KILOBIT: + return kilobit; + case RETRY: + return Retry; + case RESET: + return Reset; + case MEGABIT: + return Megabit; + case OVERRUNOVERFLOW: + return OverrunOverflow; + case GIGABIT: + return Gigabit; + case UNDERRUN: + return Underrun; + case COLLISION: + return Collision; + case PACKETS: + return Packets; + case MESSAGES: + return Messages; + case CHARACTERS: + return Characters; + case ERROR: + return Error; + case CORRECTABLEERROR: + return CorrectableError; + default: + logger.error("Invalid value: " + value); + return Other; + } + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/sel/EventDirection.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/sel/EventDirection.java index ab3a084..5e61dab 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/sel/EventDirection.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/sel/EventDirection.java @@ -24,30 +24,30 @@ public enum EventDirection { - Assertion(EventDirection.ASSERTION), - Deassertion(EventDirection.DEASSERTION), ; - - private static final int ASSERTION = 0; - private static final int DEASSERTION = 1; - - private int code; - - EventDirection(int code) { - this.code = code; - } - - public int getCode() { - return code; - } - - public static EventDirection parseInt(int value) { - switch (value) { - case ASSERTION: - return Assertion; - case DEASSERTION: - return Deassertion; - default: - throw new IllegalArgumentException("Invalid value: " + value); - } - } + Assertion(EventDirection.ASSERTION), + Deassertion(EventDirection.DEASSERTION),; + + private static final int ASSERTION = 0; + private static final int DEASSERTION = 1; + + private int code; + + EventDirection(int code) { + this.code = code; + } + + public int getCode() { + return code; + } + + public static EventDirection parseInt(int value) { + switch (value) { + case ASSERTION: + return Assertion; + case DEASSERTION: + return Deassertion; + default: + throw new IllegalArgumentException("Invalid value: " + value); + } + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/sel/GetSelEntry.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/sel/GetSelEntry.java index 745a8fc..c57e05e 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/sel/GetSelEntry.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/sel/GetSelEntry.java @@ -45,108 +45,116 @@ */ public class GetSelEntry extends IpmiCommandCoder { - private int reservationId; - - private int recordId; - - /** - * Initiates GetSelEntry for both encoding and decoding. - * - * @param version - * - IPMI version of the command. - * @param cipherSuite - * - {@link CipherSuite} containing authentication, - * confidentiality and integrity algorithms for this session. - * @param authenticationType - * - Type of authentication used. Must be RMCPPlus for IPMI v2.0. - * @param reservationId - * - SEL reservation ID received via {@link ReserveSel} command - * or 0 if requesting for whole record - * @param recordId - * - ID of the record to get - */ - public GetSelEntry(IpmiVersion version, CipherSuite cipherSuite, - AuthenticationType authenticationType, int reservationId, - int recordId) { - super(version, cipherSuite, authenticationType); - this.recordId = recordId; - this.reservationId = reservationId; - } - - @Override - public byte getCommandCode() { - return CommandCodes.GET_SEL_ENTRY; - } - - @Override - public NetworkFunction getNetworkFunction() { - return NetworkFunction.StorageRequest; - } - - @Override - protected IpmiPayload preparePayload(int sequenceNumber) - throws NoSuchAlgorithmException, InvalidKeyException { - byte[] payload = new byte[6]; - - byte[] buffer = TypeConverter.intToByteArray(reservationId); - - payload[0] = buffer[3]; - payload[1] = buffer[2]; // reservation ID - - buffer = TypeConverter.intToByteArray(recordId); - - payload[2] = buffer[3]; - payload[3] = buffer[2]; // record ID - - payload[4] = 0; - payload[5] = TypeConverter.intToByte(0xff); - - return new IpmiLanRequest(getNetworkFunction(), getCommandCode(), - payload, TypeConverter.intToByte(sequenceNumber)); - } - - @Override - public ResponseData getResponseData(IpmiMessage message) throws IPMIException, - NoSuchAlgorithmException, InvalidKeyException { - if (!isCommandResponse(message)) { - throw new IllegalArgumentException( - "This is not a response for Get SEL Entry command"); - } - if (!(message.getPayload() instanceof IpmiLanResponse)) { - throw new IllegalArgumentException("Invalid response payload"); - } - if (((IpmiLanResponse) message.getPayload()).getCompletionCode() != CompletionCode.Ok) { - throw new IPMIException( - ((IpmiLanResponse) message.getPayload()) - .getCompletionCode()); - } - - byte[] raw = message.getPayload().getIpmiCommandData(); - - if (raw == null || raw.length < 3) { - throw new IllegalArgumentException( - "Invalid response payload length"); - } - - GetSelEntryResponseData responseData = new GetSelEntryResponseData(); - - byte[] buffer = new byte[4]; - - buffer[0] = raw[0]; - buffer[1] = raw[1]; - buffer[2] = 0; - buffer[3] = 0; - - responseData.setNextRecordId(TypeConverter - .littleEndianByteArrayToInt(buffer)); - - byte[] recordData = new byte[raw.length - 2]; - - System.arraycopy(raw, 2, recordData, 0, recordData.length); - - responseData.setSelRecord(SelRecord.populateSelRecord(recordData)); - - return responseData; - } + private int reservationId; + + private int recordId; + + /** + * Initiates GetSelEntry for both encoding and decoding. + * + * @param version + * - IPMI version of the command. + * @param cipherSuite + * - {@link CipherSuite} containing authentication, + * confidentiality and integrity algorithms for this session. + * @param authenticationType + * - Type of authentication used. Must be RMCPPlus for IPMI v2.0. + * @param reservationId + * - SEL reservation ID received via {@link ReserveSel} command + * or 0 if requesting for whole record + * @param recordId + * - ID of the record to get + */ + public GetSelEntry(IpmiVersion version, CipherSuite cipherSuite, + AuthenticationType authenticationType, int reservationId, + int recordId) { + super(version, cipherSuite, authenticationType); + this.recordId = recordId; + this.reservationId = reservationId; + } + + @Override + public byte getCommandCode() { + return CommandCodes.GET_SEL_ENTRY; + } + + @Override + public NetworkFunction getNetworkFunction() { + return NetworkFunction.StorageRequest; + } + + @Override + protected IpmiPayload preparePayload(int sequenceNumber) + throws NoSuchAlgorithmException, + InvalidKeyException { + byte[] payload = new byte[6]; + + byte[] buffer = TypeConverter.intToByteArray(reservationId); + + payload[0] = buffer[3]; + payload[1] = buffer[2]; // reservation ID + + buffer = TypeConverter.intToByteArray(recordId); + + payload[2] = buffer[3]; + payload[3] = buffer[2]; // record ID + + payload[4] = 0; + payload[5] = TypeConverter.intToByte(0xff); + + return new IpmiLanRequest( + getNetworkFunction(), + getCommandCode(), + payload, + TypeConverter.intToByte(sequenceNumber)); + } + + @Override + public ResponseData getResponseData(IpmiMessage message) + throws IPMIException, + NoSuchAlgorithmException, + InvalidKeyException { + if (!isCommandResponse(message)) { + throw new IllegalArgumentException( + "This is not a response for Get SEL Entry command"); + } + if (!(message.getPayload() instanceof IpmiLanResponse)) { + throw new IllegalArgumentException("Invalid response payload"); + } + if (((IpmiLanResponse) message.getPayload()).getCompletionCode() != CompletionCode.Ok) { + throw new IPMIException( + ((IpmiLanResponse) message.getPayload()) + .getCompletionCode()); + } + + byte[] raw = message.getPayload().getIpmiCommandData(); + + if (raw == null || raw.length < 3) { + throw new IllegalArgumentException( + "Invalid response payload length"); + } + + GetSelEntryResponseData responseData = new GetSelEntryResponseData(); + + byte[] buffer = new byte[4]; + + buffer[0] = raw[0]; + buffer[1] = raw[1]; + buffer[2] = 0; + buffer[3] = 0; + + responseData + .setNextRecordId( + TypeConverter + .littleEndianByteArrayToInt(buffer)); + + byte[] recordData = new byte[raw.length - 2]; + + System.arraycopy(raw, 2, recordData, 0, recordData.length); + + responseData.setSelRecord(SelRecord.populateSelRecord(recordData)); + + return responseData; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/sel/GetSelEntryResponseData.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/sel/GetSelEntryResponseData.java index dddccbe..0c17d04 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/sel/GetSelEntryResponseData.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/sel/GetSelEntryResponseData.java @@ -29,29 +29,29 @@ */ public class GetSelEntryResponseData implements ResponseData { - /** - * ID of the next record in the repository. - */ - private int nextRecordId; - - /** - * Sensor record data - */ - private SelRecord selRecord; - - public void setNextRecordId(int nextRecordId) { - this.nextRecordId = nextRecordId; - } - - public int getNextRecordId() { - return nextRecordId; - } - - public void setSelRecord(SelRecord selRecord) { - this.selRecord = selRecord; - } - - public SelRecord getSelRecord() { - return selRecord; - } + /** + * ID of the next record in the repository. + */ + private int nextRecordId; + + /** + * Sensor record data + */ + private SelRecord selRecord; + + public void setNextRecordId(int nextRecordId) { + this.nextRecordId = nextRecordId; + } + + public int getNextRecordId() { + return nextRecordId; + } + + public void setSelRecord(SelRecord selRecord) { + this.selRecord = selRecord; + } + + public SelRecord getSelRecord() { + return selRecord; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/sel/GetSelInfo.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/sel/GetSelInfo.java index 1f191bd..7127c28 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/sel/GetSelInfo.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/sel/GetSelInfo.java @@ -45,86 +45,103 @@ */ public class GetSelInfo extends IpmiCommandCoder { - /** - * Initiates GetSelInfo for both encoding and decoding. - * - * @param version - * - IPMI version of the command. - * @param cipherSuite - * - {@link CipherSuite} containing authentication, - * confidentiality and integrity algorithms for this session. - * @param authenticationType - * - Type of authentication used. Must be RMCPPlus for IPMI v2.0. - */ - public GetSelInfo(IpmiVersion version, CipherSuite cipherSuite, - AuthenticationType authenticationType) { - super(version, cipherSuite, authenticationType); - } - - @Override - public byte getCommandCode() { - return CommandCodes.GET_SEL_INFO; - } - - @Override - public NetworkFunction getNetworkFunction() { - return NetworkFunction.StorageRequest; - } - - @Override - protected IpmiPayload preparePayload(int sequenceNumber) - throws NoSuchAlgorithmException, InvalidKeyException { - return new IpmiLanRequest(getNetworkFunction(), getCommandCode(), null, - TypeConverter.intToByte(sequenceNumber)); - } - - @Override - public ResponseData getResponseData(IpmiMessage message) throws IPMIException, NoSuchAlgorithmException, InvalidKeyException { - if (!isCommandResponse(message)) { - throw new IllegalArgumentException( - "This is not a response for Get SEL Info command"); - } - if (!(message.getPayload() instanceof IpmiLanResponse)) { - throw new IllegalArgumentException("Invalid response payload"); - } - if (((IpmiLanResponse) message.getPayload()).getCompletionCode() != CompletionCode.Ok) { - throw new IPMIException( - ((IpmiLanResponse) message.getPayload()) - .getCompletionCode()); - } - - byte[] raw = message.getPayload().getIpmiCommandData(); - - if (raw == null || raw.length != 14) { - throw new IllegalArgumentException("Invalid response payload length: " + (raw != null ? raw.length : "null")); - } - - GetSelInfoResponseData responseData = new GetSelInfoResponseData(); - - responseData.setSelVersion(TypeConverter - .littleEndianBcdByteToInt(raw[0])); - - byte[] buffer = new byte[4]; - - buffer[0] = raw[1]; - buffer[1] = raw[2]; - buffer[2] = 0; - buffer[3] = 0; - - responseData.setEntriesCount(TypeConverter - .littleEndianByteArrayToInt(buffer)); - - System.arraycopy(raw, 5, buffer, 0, 4); - - responseData.setAdditionTimestamp(TypeConverter - .decodeDate(TypeConverter.littleEndianByteArrayToInt(buffer))); - - System.arraycopy(raw, 9, buffer, 0, 4); - - responseData.setEraseTimestamp(TypeConverter.decodeDate(TypeConverter - .littleEndianByteArrayToInt(buffer))); - - return responseData; - } + /** + * Initiates GetSelInfo for both encoding and decoding. + * + * @param version + * - IPMI version of the command. + * @param cipherSuite + * - {@link CipherSuite} containing authentication, + * confidentiality and integrity algorithms for this session. + * @param authenticationType + * - Type of authentication used. Must be RMCPPlus for IPMI v2.0. + */ + public GetSelInfo(IpmiVersion version, CipherSuite cipherSuite, + AuthenticationType authenticationType) { + super(version, cipherSuite, authenticationType); + } + + @Override + public byte getCommandCode() { + return CommandCodes.GET_SEL_INFO; + } + + @Override + public NetworkFunction getNetworkFunction() { + return NetworkFunction.StorageRequest; + } + + @Override + protected IpmiPayload preparePayload(int sequenceNumber) + throws NoSuchAlgorithmException, + InvalidKeyException { + return new IpmiLanRequest( + getNetworkFunction(), + getCommandCode(), + null, + TypeConverter.intToByte(sequenceNumber)); + } + + @Override + public ResponseData getResponseData(IpmiMessage message) + throws IPMIException, + NoSuchAlgorithmException, + InvalidKeyException { + if (!isCommandResponse(message)) { + throw new IllegalArgumentException( + "This is not a response for Get SEL Info command"); + } + if (!(message.getPayload() instanceof IpmiLanResponse)) { + throw new IllegalArgumentException("Invalid response payload"); + } + if (((IpmiLanResponse) message.getPayload()).getCompletionCode() != CompletionCode.Ok) { + throw new IPMIException( + ((IpmiLanResponse) message.getPayload()) + .getCompletionCode()); + } + + byte[] raw = message.getPayload().getIpmiCommandData(); + + if (raw == null || raw.length != 14) { + throw new IllegalArgumentException("Invalid response payload length: " + (raw != null ? raw.length : "null")); + } + + GetSelInfoResponseData responseData = new GetSelInfoResponseData(); + + responseData + .setSelVersion( + TypeConverter + .littleEndianBcdByteToInt(raw[0])); + + byte[] buffer = new byte[4]; + + buffer[0] = raw[1]; + buffer[1] = raw[2]; + buffer[2] = 0; + buffer[3] = 0; + + responseData + .setEntriesCount( + TypeConverter + .littleEndianByteArrayToInt(buffer)); + + System.arraycopy(raw, 5, buffer, 0, 4); + + responseData + .setAdditionTimestamp( + TypeConverter + .decodeDate(TypeConverter.littleEndianByteArrayToInt(buffer))); + + System.arraycopy(raw, 9, buffer, 0, 4); + + responseData + .setEraseTimestamp( + TypeConverter + .decodeDate( + TypeConverter + .littleEndianByteArrayToInt(buffer))); + + return responseData; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/sel/GetSelInfoResponseData.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/sel/GetSelInfoResponseData.java index 42320a3..5d77ff8 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/sel/GetSelInfoResponseData.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/sel/GetSelInfoResponseData.java @@ -30,49 +30,49 @@ * Wrapper for Get SEL Info response */ public class GetSelInfoResponseData implements ResponseData { - private int selVersion; + private int selVersion; - private int entriesCount; + private int entriesCount; - /** - * Most recent addition timestamp. - */ - private Date additionTimestamp; + /** + * Most recent addition timestamp. + */ + private Date additionTimestamp; - /** - * Most recent erase timestamp. - */ - private Date eraseTimestamp; + /** + * Most recent erase timestamp. + */ + private Date eraseTimestamp; - public int getSelVersion() { - return selVersion; - } + public int getSelVersion() { + return selVersion; + } - public void setSelVersion(int selVersion) { - this.selVersion = selVersion; - } + public void setSelVersion(int selVersion) { + this.selVersion = selVersion; + } - public int getEntriesCount() { - return entriesCount; - } + public int getEntriesCount() { + return entriesCount; + } - public void setEntriesCount(int entriesCount) { - this.entriesCount = entriesCount; - } + public void setEntriesCount(int entriesCount) { + this.entriesCount = entriesCount; + } - public Date getAdditionTimestamp() { - return additionTimestamp; - } + public Date getAdditionTimestamp() { + return additionTimestamp; + } - public void setAdditionTimestamp(Date additionTimestamp) { - this.additionTimestamp = additionTimestamp; - } + public void setAdditionTimestamp(Date additionTimestamp) { + this.additionTimestamp = additionTimestamp; + } - public Date getEraseTimestamp() { - return eraseTimestamp; - } + public Date getEraseTimestamp() { + return eraseTimestamp; + } - public void setEraseTimestamp(Date eraseTimestamp) { - this.eraseTimestamp = eraseTimestamp; - } + public void setEraseTimestamp(Date eraseTimestamp) { + this.eraseTimestamp = eraseTimestamp; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/sel/ReserveSel.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/sel/ReserveSel.java index becb89b..4b438ed 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/sel/ReserveSel.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/sel/ReserveSel.java @@ -45,77 +45,84 @@ */ public class ReserveSel extends IpmiCommandCoder { - /** - * Initiates ReserveSel for both encoding and decoding. - * - * @param version - * - IPMI version of the command. - * @param cipherSuite - * - {@link CipherSuite} containing authentication, - * confidentiality and integrity algorithms for this session. - * @param authenticationType - * - Type of authentication used. Must be RMCPPlus for IPMI v2.0. - */ - public ReserveSel(IpmiVersion version, CipherSuite cipherSuite, - AuthenticationType authenticationType) { - super(version, cipherSuite, authenticationType); - } - - @Override - public byte getCommandCode() { - return CommandCodes.RESERVE_SEL; - } - - @Override - public NetworkFunction getNetworkFunction() { - return NetworkFunction.StorageRequest; - } - - @Override - protected IpmiPayload preparePayload(int sequenceNumber) - throws NoSuchAlgorithmException, InvalidKeyException { - return new IpmiLanRequest(getNetworkFunction(), getCommandCode(), null, - TypeConverter.intToByte(sequenceNumber)); - } - - @Override - public ResponseData getResponseData(IpmiMessage message) - throws IPMIException, - NoSuchAlgorithmException, InvalidKeyException { - - if (!isCommandResponse(message)) { - throw new IllegalArgumentException( - "This is not a response for Reserve SEL command"); - } - if (!(message.getPayload() instanceof IpmiLanResponse)) { - throw new IllegalArgumentException("Invalid response payload"); - } - if (((IpmiLanResponse) message.getPayload()).getCompletionCode() != CompletionCode.Ok) { - throw new IPMIException( - ((IpmiLanResponse) message.getPayload()) - .getCompletionCode()); - } - - byte[] raw = message.getPayload().getIpmiCommandData(); - - if (raw == null || raw.length != 2) { - throw new IllegalArgumentException( - "Invalid response payload length: " + (raw != null ? raw.length : "null")); - } - - ReserveSelResponseData responseData = new ReserveSelResponseData(); - - byte[] buffer = new byte[4]; - - buffer[0] = raw[0]; - buffer[1] = raw[1]; - buffer[2] = 0; - buffer[3] = 0; - - responseData.setReservationId(TypeConverter - .littleEndianByteArrayToInt(buffer)); - - return responseData; - } + /** + * Initiates ReserveSel for both encoding and decoding. + * + * @param version + * - IPMI version of the command. + * @param cipherSuite + * - {@link CipherSuite} containing authentication, + * confidentiality and integrity algorithms for this session. + * @param authenticationType + * - Type of authentication used. Must be RMCPPlus for IPMI v2.0. + */ + public ReserveSel(IpmiVersion version, CipherSuite cipherSuite, + AuthenticationType authenticationType) { + super(version, cipherSuite, authenticationType); + } + + @Override + public byte getCommandCode() { + return CommandCodes.RESERVE_SEL; + } + + @Override + public NetworkFunction getNetworkFunction() { + return NetworkFunction.StorageRequest; + } + + @Override + protected IpmiPayload preparePayload(int sequenceNumber) + throws NoSuchAlgorithmException, + InvalidKeyException { + return new IpmiLanRequest( + getNetworkFunction(), + getCommandCode(), + null, + TypeConverter.intToByte(sequenceNumber)); + } + + @Override + public ResponseData getResponseData(IpmiMessage message) + throws IPMIException, + NoSuchAlgorithmException, + InvalidKeyException { + + if (!isCommandResponse(message)) { + throw new IllegalArgumentException( + "This is not a response for Reserve SEL command"); + } + if (!(message.getPayload() instanceof IpmiLanResponse)) { + throw new IllegalArgumentException("Invalid response payload"); + } + if (((IpmiLanResponse) message.getPayload()).getCompletionCode() != CompletionCode.Ok) { + throw new IPMIException( + ((IpmiLanResponse) message.getPayload()) + .getCompletionCode()); + } + + byte[] raw = message.getPayload().getIpmiCommandData(); + + if (raw == null || raw.length != 2) { + throw new IllegalArgumentException( + "Invalid response payload length: " + (raw != null ? raw.length : "null")); + } + + ReserveSelResponseData responseData = new ReserveSelResponseData(); + + byte[] buffer = new byte[4]; + + buffer[0] = raw[0]; + buffer[1] = raw[1]; + buffer[2] = 0; + buffer[3] = 0; + + responseData + .setReservationId( + TypeConverter + .littleEndianByteArrayToInt(buffer)); + + return responseData; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/sel/ReserveSelResponseData.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/sel/ReserveSelResponseData.java index 9569606..615c19d 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/sel/ReserveSelResponseData.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/sel/ReserveSelResponseData.java @@ -28,14 +28,14 @@ * Wrapper for Reserve SEL command response. */ public class ReserveSelResponseData implements ResponseData { - private int reservationId; + private int reservationId; - public void setReservationId(int reservationId) { - this.reservationId = reservationId; - } + public void setReservationId(int reservationId) { + this.reservationId = reservationId; + } - public int getReservationId() { - return reservationId; - } + public int getReservationId() { + return reservationId; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/sel/SelRecord.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/sel/SelRecord.java index 12d96f8..35aade7 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/sel/SelRecord.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/sel/SelRecord.java @@ -31,132 +31,132 @@ public class SelRecord { - private int recordId; + private int recordId; - private SelRecordType recordType; + private SelRecordType recordType; - private Date timestamp; + private Date timestamp; - /** - * {@link SensorType} code for sensor that generated the event - */ - private SensorType sensorType; + /** + * {@link SensorType} code for sensor that generated the event + */ + private SensorType sensorType; - /** - * Number of sensor that generated the event - */ - private int sensorNumber; + /** + * Number of sensor that generated the event + */ + private int sensorNumber; - private EventDirection eventDirection; + private EventDirection eventDirection; - private ReadingType event; + private ReadingType event; - /** - * Reading that triggered event. Provided in raw value (need to do - * {@link FullSensorRecord#calcFormula(int)}). Only for threshold sensors. - */ - private byte reading; + /** + * Reading that triggered event. Provided in raw value (need to do + * {@link FullSensorRecord#calcFormula(int)}). Only for threshold sensors. + */ + private byte reading; - public static SelRecord populateSelRecord(byte[] data) { - SelRecord record = new SelRecord(); + public static SelRecord populateSelRecord(byte[] data) { + SelRecord record = new SelRecord(); - byte[] buffer = new byte[4]; + byte[] buffer = new byte[4]; - buffer[0] = data[0]; - buffer[1] = data[1]; - buffer[2] = 0; - buffer[3] = 0; + buffer[0] = data[0]; + buffer[1] = data[1]; + buffer[2] = 0; + buffer[3] = 0; - record.setRecordId(TypeConverter.littleEndianByteArrayToInt(buffer)); + record.setRecordId(TypeConverter.littleEndianByteArrayToInt(buffer)); - record.setRecordType(SelRecordType.parseInt(TypeConverter.byteToInt(data[2]))); + record.setRecordType(SelRecordType.parseInt(TypeConverter.byteToInt(data[2]))); - System.arraycopy(data, 3, buffer, 0, 4); + System.arraycopy(data, 3, buffer, 0, 4); - record.setTimestamp(TypeConverter.decodeDate(TypeConverter.littleEndianByteArrayToInt(buffer))); + record.setTimestamp(TypeConverter.decodeDate(TypeConverter.littleEndianByteArrayToInt(buffer))); - record.setSensorType(SensorType.parseInt(TypeConverter.byteToInt(data[10]))); + record.setSensorType(SensorType.parseInt(TypeConverter.byteToInt(data[10]))); - record.setSensorNumber(TypeConverter.byteToInt(data[11])); + record.setSensorNumber(TypeConverter.byteToInt(data[11])); - record.setEventDirection(EventDirection.parseInt((TypeConverter.byteToInt(data[12]) & 0x80) >> 7)); + record.setEventDirection(EventDirection.parseInt((TypeConverter.byteToInt(data[12]) & 0x80) >> 7)); - int eventType = TypeConverter.byteToInt(data[12]) & 0x7f; + int eventType = TypeConverter.byteToInt(data[12]) & 0x7f; - int eventOffset = TypeConverter.byteToInt(data[13]) & 0xf; + int eventOffset = TypeConverter.byteToInt(data[13]) & 0xf; - record.setEvent(ReadingType.parseInt(record.getSensorType(), eventType, eventOffset)); + record.setEvent(ReadingType.parseInt(record.getSensorType(), eventType, eventOffset)); - record.setReading(data[14]); + record.setReading(data[14]); - return record; - } + return record; + } - public void setRecordId(int recordId) { - this.recordId = recordId; - } + public void setRecordId(int recordId) { + this.recordId = recordId; + } - public int getRecordId() { - return recordId; - } + public int getRecordId() { + return recordId; + } - public SelRecordType getRecordType() { - return recordType; - } + public SelRecordType getRecordType() { + return recordType; + } - public void setRecordType(SelRecordType recordType) { - this.recordType = recordType; - } + public void setRecordType(SelRecordType recordType) { + this.recordType = recordType; + } - public Date getTimestamp() { - return timestamp; - } + public Date getTimestamp() { + return timestamp; + } - public void setTimestamp(Date timestamp) { - this.timestamp = timestamp; - } + public void setTimestamp(Date timestamp) { + this.timestamp = timestamp; + } - public SensorType getSensorType() { - return sensorType; - } + public SensorType getSensorType() { + return sensorType; + } - public void setSensorType(SensorType sensorType) { - this.sensorType = sensorType; - } + public void setSensorType(SensorType sensorType) { + this.sensorType = sensorType; + } - public int getSensorNumber() { - return sensorNumber; - } + public int getSensorNumber() { + return sensorNumber; + } - public void setSensorNumber(int sensorNumber) { - this.sensorNumber = sensorNumber; - } + public void setSensorNumber(int sensorNumber) { + this.sensorNumber = sensorNumber; + } - public EventDirection getEventDirection() { - return eventDirection; - } + public EventDirection getEventDirection() { + return eventDirection; + } - public void setEventDirection(EventDirection eventDirection) { - this.eventDirection = eventDirection; - } + public void setEventDirection(EventDirection eventDirection) { + this.eventDirection = eventDirection; + } - public ReadingType getEvent() { - return event; - } + public ReadingType getEvent() { + return event; + } - public void setEvent(ReadingType event) { - this.event = event; - } + public void setEvent(ReadingType event) { + this.event = event; + } - /** - * Reading that triggered event. Provided in raw value (need to do - * {@link FullSensorRecord#calcFormula(int)}). Only for threshold sensors. - */ - public byte getReading() { - return reading; - } + /** + * Reading that triggered event. Provided in raw value (need to do + * {@link FullSensorRecord#calcFormula(int)}). Only for threshold sensors. + */ + public byte getReading() { + return reading; + } - public void setReading(byte reading) { - this.reading = reading; - } + public void setReading(byte reading) { + this.reading = reading; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/sel/SelRecordType.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/sel/SelRecordType.java index ed323b8..3d48b55 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/sel/SelRecordType.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/sel/SelRecordType.java @@ -23,38 +23,41 @@ */ public enum SelRecordType { - OemTimestamped(SelRecordType.OEMTIMESTAMPED), System(SelRecordType.SYSTEM), OemNonTimestamped( - SelRecordType.OEMNONTIMESTAMPED), ; - /** - * Represents OEM timestamped record type (C0h-DFh) - */ - private static final int OEMTIMESTAMPED = 192; - private static final int SYSTEM = 2; - /** - * Represents OEM timestamped record type (E0h-FFh) - */ - private static final int OEMNONTIMESTAMPED = 224; + OemTimestamped(SelRecordType.OEMTIMESTAMPED), + System(SelRecordType.SYSTEM), + OemNonTimestamped( + SelRecordType.OEMNONTIMESTAMPED),; - private int code; + /** + * Represents OEM timestamped record type (C0h-DFh) + */ + private static final int OEMTIMESTAMPED = 192; + private static final int SYSTEM = 2; + /** + * Represents OEM timestamped record type (E0h-FFh) + */ + private static final int OEMNONTIMESTAMPED = 224; - SelRecordType(int code) { - this.code = code; - } + private int code; - public int getCode() { - return code; - } + SelRecordType(int code) { + this.code = code; + } - public static SelRecordType parseInt(int value) { - if (value == SYSTEM) { - return System; - } - if (value > OEMNONTIMESTAMPED) { - return OemNonTimestamped; - } - if (value > OEMTIMESTAMPED) { - return OemTimestamped; - } - throw new IllegalArgumentException("Invalid value: " + value); - } + public int getCode() { + return code; + } + + public static SelRecordType parseInt(int value) { + if (value == SYSTEM) { + return System; + } + if (value > OEMNONTIMESTAMPED) { + return OemNonTimestamped; + } + if (value > OEMTIMESTAMPED) { + return OemTimestamped; + } + throw new IllegalArgumentException("Invalid value: " + value); + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/session/CloseSession.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/session/CloseSession.java index 82db63f..21a93d2 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/session/CloseSession.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/session/CloseSession.java @@ -42,55 +42,62 @@ */ public class CloseSession extends IpmiCommandCoder { - private int sessionId; + private int sessionId; - /** - * Initiates CloseSession for both encoding and decoding. - * - * @param version - * - IPMI version of the command. - * @param cipherSuite - * - {@link CipherSuite} containing authentication, - * confidentiality and integrity algorithms for this session. - * @param authenticationType - * - Type of authentication used. Must be RMCPPlus for IPMI v2.0. - * @param sessionId - * - Generated by managed system ID of the session to close. - */ - public CloseSession(IpmiVersion version, CipherSuite cipherSuite, - AuthenticationType authenticationType, int sessionId) { - super(version, cipherSuite, authenticationType); + /** + * Initiates CloseSession for both encoding and decoding. + * + * @param version + * - IPMI version of the command. + * @param cipherSuite + * - {@link CipherSuite} containing authentication, + * confidentiality and integrity algorithms for this session. + * @param authenticationType + * - Type of authentication used. Must be RMCPPlus for IPMI v2.0. + * @param sessionId + * - Generated by managed system ID of the session to close. + */ + public CloseSession(IpmiVersion version, CipherSuite cipherSuite, + AuthenticationType authenticationType, int sessionId) { + super(version, cipherSuite, authenticationType); - if (sessionId == 0) { - throw new IllegalArgumentException("Cannot close session '0'"); - } + if (sessionId == 0) { + throw new IllegalArgumentException("Cannot close session '0'"); + } - this.sessionId = sessionId; - } + this.sessionId = sessionId; + } - @Override - public byte getCommandCode() { - return TypeConverter.intToByte(0x3c); - } + @Override + public byte getCommandCode() { + return TypeConverter.intToByte(0x3c); + } - @Override - public NetworkFunction getNetworkFunction() { - return NetworkFunction.ApplicationRequest; - } + @Override + public NetworkFunction getNetworkFunction() { + return NetworkFunction.ApplicationRequest; + } - @Override - protected IpmiPayload preparePayload(int sequenceNumber) - throws NoSuchAlgorithmException, InvalidKeyException { + @Override + protected IpmiPayload preparePayload(int sequenceNumber) + throws NoSuchAlgorithmException, + InvalidKeyException { - byte[] payload = TypeConverter.intToLittleEndianByteArray(sessionId); + byte[] payload = TypeConverter.intToLittleEndianByteArray(sessionId); - return new IpmiLanRequest(getNetworkFunction(), getCommandCode(), - payload, TypeConverter.intToByte(sequenceNumber)); - } + return new IpmiLanRequest( + getNetworkFunction(), + getCommandCode(), + payload, + TypeConverter.intToByte(sequenceNumber)); + } - @Override - public ResponseData getResponseData(IpmiMessage message) throws IPMIException, NoSuchAlgorithmException, InvalidKeyException { - return new CloseSessionResponseData(); - } + @Override + public ResponseData getResponseData(IpmiMessage message) + throws IPMIException, + NoSuchAlgorithmException, + InvalidKeyException { + return new CloseSessionResponseData(); + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/session/GetChannelAuthenticationCapabilities.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/session/GetChannelAuthenticationCapabilities.java index 0f34d7f..cc0f39e 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/session/GetChannelAuthenticationCapabilities.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/session/GetChannelAuthenticationCapabilities.java @@ -48,275 +48,284 @@ */ public class GetChannelAuthenticationCapabilities extends IpmiCommandCoder { - private PrivilegeLevel requestedPrivilegeLevel; - - private byte channelNumber; - - private IpmiVersion requestVersion; - - public void setRequestedPrivilegeLevel( - PrivilegeLevel requestedPrivilegeLevel) { - this.requestedPrivilegeLevel = requestedPrivilegeLevel; - } - - public PrivilegeLevel getRequestedPrivilegeLevel() { - return requestedPrivilegeLevel; - } - - /** - * Sets the channel number that will be put into IPMI command. - * - * @param channelNumber - * - must be 0h-Bh or Eh-Fh
- * Eh = retrieve information for channel this request was issued - * on - * @throws IllegalArgumentException - */ - public void setChannelNumber(int channelNumber) { - if (channelNumber < 0 || channelNumber > 0xF || channelNumber == 0xC - || channelNumber == 0xD) { - throw new IllegalArgumentException("Invalid channel number"); - } - this.channelNumber = TypeConverter.intToByte(channelNumber); - } - - public int getChannelNumber() { - return TypeConverter.byteToInt(channelNumber); - } - - protected void setRequestVersion(IpmiVersion requestVersion) { - this.requestVersion = requestVersion; - } - - protected IpmiVersion getRequestVersion() { - return requestVersion; - } - - /** - * Initiates class for decoding in 1.5 version. Sets requested privilege - * level to user. Sets channel number to 14 indicating that response will - * contain information for channel this request was issued on. Sets session - * parameters to default. - * - * @see IpmiCommandCoder#setSessionParameters(IpmiVersion, CipherSuite, - * AuthenticationType) - * @see IpmiVersion - */ - public GetChannelAuthenticationCapabilities() { - super(); - setRequestedPrivilegeLevel(PrivilegeLevel.User); - setChannelNumber(14); - } - - /** - * Initiates class. Sets IPMI version to version. Sets requested privilege - * level to user. Sets channel number to 14 indicating that response will - * contain information for channel this request was issued on. - * - * @param version - * - Version of IPMI protocol used - * @param requestVersion - * - If Get Channel Authentication Capabilities command is sent - * to BMC with requestVersion = {@link IpmiVersion#V15} it will - * respond, that it does not support IPMI v2.0 even if it does. - * @param cipherSuite - * - {@link CipherSuite} containing authentication, - * confidentiality and integrity algorithms for this session. - * @see IpmiVersion - */ - public GetChannelAuthenticationCapabilities(IpmiVersion version, - IpmiVersion requestVersion, CipherSuite cipherSuite) { - super(version, cipherSuite, AuthenticationType.None); - this.setRequestVersion(requestVersion); - setRequestedPrivilegeLevel(PrivilegeLevel.User); - setChannelNumber(14); - } - - /** - * Initiates class. Sets IPMI version to version. Sets requested privilege - * level privilegeLevel. Sets channel number to channelNumber. - * - * @param version - * - Version of IPMI protocol used - * @param requestVersion - * - If Get Channel Authentication Capabilities command is sent - * to BMC with requestVersion = {@link IpmiVersion#V15} it will - * respond, that it does not support IPMI v2.0 even if it does. - * @param cipherSuite - * - {@link CipherSuite} containing authentication, - * confidentiality and integrity algorithms for this session. - * @param privilegeLevel - * - Maximum requested privilege level. Can't be - * {@link PrivilegeLevel#MaximumAvailable}. - * @param channelNumber - * - must be 0h-Bh or Eh-Fh
- * Eh = retrieve information for channel this request was issued - * on. - * @see IpmiVersion - * @see PrivilegeLevel - */ - public GetChannelAuthenticationCapabilities(IpmiVersion version, - IpmiVersion requestVersion, CipherSuite cipherSuite, - PrivilegeLevel privilegeLevel, byte channelNumber) { - super(version, cipherSuite, AuthenticationType.None); - this.setRequestVersion(requestVersion); - setRequestedPrivilegeLevel(privilegeLevel); - setChannelNumber(channelNumber); - } - - @Override - public IpmiMessage encodePayload(int messageSequenceNumber, int sessionSequenceNumber, int sessionId) - throws InvalidKeyException, NoSuchAlgorithmException { - if (getIpmiVersion() == IpmiVersion.V15) { - if (sessionId != 0) { - throw new IllegalArgumentException("Session ID must be 0"); - } - - Ipmiv15Message message = new Ipmiv15Message(); - - message.setAuthenticationType(getAuthenticationType()); - - message.setSessionSequenceNumber(0); - - message.setSessionID(0); - - message.setPayload(preparePayload(messageSequenceNumber)); - - return message; - } else { - setAuthenticationType(AuthenticationType.RMCPPlus); - - return super.encodePayload(messageSequenceNumber, sessionSequenceNumber, sessionId); - } - } - - @Override - protected IpmiPayload preparePayload(int sequenceNumber) { - byte[] payload = new byte[2]; - - payload[0] = 0; - - if (getRequestVersion() == IpmiVersion.V20) { - payload[0] |= TypeConverter.intToByte(0x80); - } - - payload[0] |= channelNumber; - - payload[1] = encodePrivilegeLevel(requestedPrivilegeLevel); - return new IpmiLanRequest(getNetworkFunction(), getCommandCode(), payload, - TypeConverter.intToByte(sequenceNumber)); - } - - @Override - public byte getCommandCode() { - return CommandCodes.GET_CHANNEL_AUTHENTICATION_CAPABILITIES; - } - - @Override - public NetworkFunction getNetworkFunction() { - return NetworkFunction.ApplicationRequest; - } - - @Override - public ResponseData getResponseData(IpmiMessage message) throws IPMIException { - if (!isCommandResponse(message)) { - throw new IllegalArgumentException( - "This is not a response for Get Channel Authentication Capabilities command"); - } - if (!(message.getPayload() instanceof IpmiLanResponse)) { - throw new IllegalArgumentException("Invalid response payload"); - } - if (((IpmiLanResponse) message.getPayload()).getCompletionCode() != CompletionCode.Ok) { - throw new IPMIException( - ((IpmiLanResponse) message.getPayload()) - .getCompletionCode()); - } - GetChannelAuthenticationCapabilitiesResponseData responseData = new GetChannelAuthenticationCapabilitiesResponseData(); - - byte[] raw = message.getPayload().getIpmiCommandData(); - - if (raw.length != 8) { - throw new IllegalArgumentException("Data has invalid length"); - } - - responseData.setChannelNumber(raw[0]); - - responseData.setIpmiv20Support((raw[1] & 0x80) != 0); - - responseData - .setAuthenticationTypes(new ArrayList()); - - if ((raw[1] & 0x20) != 0) { - responseData.getAuthenticationTypes().add(AuthenticationType.Oem); - } - - if ((raw[1] & 0x10) != 0) { - responseData.getAuthenticationTypes() - .add(AuthenticationType.Simple); - } + private PrivilegeLevel requestedPrivilegeLevel; + + private byte channelNumber; + + private IpmiVersion requestVersion; + + public void setRequestedPrivilegeLevel( + PrivilegeLevel requestedPrivilegeLevel) { + this.requestedPrivilegeLevel = requestedPrivilegeLevel; + } + + public PrivilegeLevel getRequestedPrivilegeLevel() { + return requestedPrivilegeLevel; + } + + /** + * Sets the channel number that will be put into IPMI command. + * + * @param channelNumber + * - must be 0h-Bh or Eh-Fh
+ * Eh = retrieve information for channel this request was issued + * on + * @throws IllegalArgumentException + */ + public void setChannelNumber(int channelNumber) { + if (channelNumber < 0 + || channelNumber > 0xF + || channelNumber == 0xC + || channelNumber == 0xD) { + throw new IllegalArgumentException("Invalid channel number"); + } + this.channelNumber = TypeConverter.intToByte(channelNumber); + } + + public int getChannelNumber() { + return TypeConverter.byteToInt(channelNumber); + } + + protected void setRequestVersion(IpmiVersion requestVersion) { + this.requestVersion = requestVersion; + } + + protected IpmiVersion getRequestVersion() { + return requestVersion; + } + + /** + * Initiates class for decoding in 1.5 version. Sets requested privilege + * level to user. Sets channel number to 14 indicating that response will + * contain information for channel this request was issued on. Sets session + * parameters to default. + * + * @see IpmiCommandCoder#setSessionParameters(IpmiVersion, CipherSuite, + * AuthenticationType) + * @see IpmiVersion + */ + public GetChannelAuthenticationCapabilities() { + super(); + setRequestedPrivilegeLevel(PrivilegeLevel.User); + setChannelNumber(14); + } + + /** + * Initiates class. Sets IPMI version to version. Sets requested privilege + * level to user. Sets channel number to 14 indicating that response will + * contain information for channel this request was issued on. + * + * @param version + * - Version of IPMI protocol used + * @param requestVersion + * - If Get Channel Authentication Capabilities command is sent + * to BMC with requestVersion = {@link IpmiVersion#V15} it will + * respond, that it does not support IPMI v2.0 even if it does. + * @param cipherSuite + * - {@link CipherSuite} containing authentication, + * confidentiality and integrity algorithms for this session. + * @see IpmiVersion + */ + public GetChannelAuthenticationCapabilities(IpmiVersion version, + IpmiVersion requestVersion, CipherSuite cipherSuite) { + super(version, cipherSuite, AuthenticationType.None); + this.setRequestVersion(requestVersion); + setRequestedPrivilegeLevel(PrivilegeLevel.User); + setChannelNumber(14); + } + + /** + * Initiates class. Sets IPMI version to version. Sets requested privilege + * level privilegeLevel. Sets channel number to channelNumber. + * + * @param version + * - Version of IPMI protocol used + * @param requestVersion + * - If Get Channel Authentication Capabilities command is sent + * to BMC with requestVersion = {@link IpmiVersion#V15} it will + * respond, that it does not support IPMI v2.0 even if it does. + * @param cipherSuite + * - {@link CipherSuite} containing authentication, + * confidentiality and integrity algorithms for this session. + * @param privilegeLevel + * - Maximum requested privilege level. Can't be + * {@link PrivilegeLevel#MaximumAvailable}. + * @param channelNumber + * - must be 0h-Bh or Eh-Fh
+ * Eh = retrieve information for channel this request was issued + * on. + * @see IpmiVersion + * @see PrivilegeLevel + */ + public GetChannelAuthenticationCapabilities(IpmiVersion version, + IpmiVersion requestVersion, CipherSuite cipherSuite, + PrivilegeLevel privilegeLevel, byte channelNumber) { + super(version, cipherSuite, AuthenticationType.None); + this.setRequestVersion(requestVersion); + setRequestedPrivilegeLevel(privilegeLevel); + setChannelNumber(channelNumber); + } + + @Override + public IpmiMessage encodePayload(int messageSequenceNumber, int sessionSequenceNumber, int sessionId) + throws InvalidKeyException, + NoSuchAlgorithmException { + if (getIpmiVersion() == IpmiVersion.V15) { + if (sessionId != 0) { + throw new IllegalArgumentException("Session ID must be 0"); + } + + Ipmiv15Message message = new Ipmiv15Message(); + + message.setAuthenticationType(getAuthenticationType()); + + message.setSessionSequenceNumber(0); + + message.setSessionID(0); + + message.setPayload(preparePayload(messageSequenceNumber)); + + return message; + } else { + setAuthenticationType(AuthenticationType.RMCPPlus); + + return super.encodePayload(messageSequenceNumber, sessionSequenceNumber, sessionId); + } + } + + @Override + protected IpmiPayload preparePayload(int sequenceNumber) { + byte[] payload = new byte[2]; + + payload[0] = 0; + + if (getRequestVersion() == IpmiVersion.V20) { + payload[0] |= TypeConverter.intToByte(0x80); + } + + payload[0] |= channelNumber; + + payload[1] = encodePrivilegeLevel(requestedPrivilegeLevel); + return new IpmiLanRequest( + getNetworkFunction(), + getCommandCode(), + payload, + TypeConverter.intToByte(sequenceNumber)); + } + + @Override + public byte getCommandCode() { + return CommandCodes.GET_CHANNEL_AUTHENTICATION_CAPABILITIES; + } + + @Override + public NetworkFunction getNetworkFunction() { + return NetworkFunction.ApplicationRequest; + } + + @Override + public ResponseData getResponseData(IpmiMessage message) throws IPMIException { + if (!isCommandResponse(message)) { + throw new IllegalArgumentException( + "This is not a response for Get Channel Authentication Capabilities command"); + } + if (!(message.getPayload() instanceof IpmiLanResponse)) { + throw new IllegalArgumentException("Invalid response payload"); + } + if (((IpmiLanResponse) message.getPayload()).getCompletionCode() != CompletionCode.Ok) { + throw new IPMIException( + ((IpmiLanResponse) message.getPayload()) + .getCompletionCode()); + } + GetChannelAuthenticationCapabilitiesResponseData responseData = new GetChannelAuthenticationCapabilitiesResponseData(); + + byte[] raw = message.getPayload().getIpmiCommandData(); + + if (raw.length != 8) { + throw new IllegalArgumentException("Data has invalid length"); + } + + responseData.setChannelNumber(raw[0]); + + responseData.setIpmiv20Support((raw[1] & 0x80) != 0); + + responseData + .setAuthenticationTypes(new ArrayList()); + + if ((raw[1] & 0x20) != 0) { + responseData.getAuthenticationTypes().add(AuthenticationType.Oem); + } + + if ((raw[1] & 0x10) != 0) { + responseData + .getAuthenticationTypes() + .add(AuthenticationType.Simple); + } - if ((raw[1] & 0x04) != 0) { - responseData.getAuthenticationTypes().add(AuthenticationType.Md5); - } + if ((raw[1] & 0x04) != 0) { + responseData.getAuthenticationTypes().add(AuthenticationType.Md5); + } - if ((raw[1] & 0x02) != 0) { - responseData.getAuthenticationTypes().add(AuthenticationType.Md2); - } + if ((raw[1] & 0x02) != 0) { + responseData.getAuthenticationTypes().add(AuthenticationType.Md2); + } - if ((raw[1] & 0x01) != 0) { - responseData.getAuthenticationTypes().add(AuthenticationType.None); - } + if ((raw[1] & 0x01) != 0) { + responseData.getAuthenticationTypes().add(AuthenticationType.None); + } - responseData.setKgEnabled((raw[2] & 0x20) != 0); + responseData.setKgEnabled((raw[2] & 0x20) != 0); - responseData.setPerMessageAuthenticationEnabled((raw[2] & 0x10) == 0); + responseData.setPerMessageAuthenticationEnabled((raw[2] & 0x10) == 0); - responseData.setUserLevelAuthenticationEnabled((raw[2] & 0x08) == 0); + responseData.setUserLevelAuthenticationEnabled((raw[2] & 0x08) == 0); - responseData.setNonNullUsernamesEnabled((raw[2] & 0x04) != 0); + responseData.setNonNullUsernamesEnabled((raw[2] & 0x04) != 0); - responseData.setNullUsernamesEnabled((raw[2] & 0x02) != 0); + responseData.setNullUsernamesEnabled((raw[2] & 0x02) != 0); + + responseData.setAnonymusLoginEnabled((raw[2] & 0x01) != 0); + + byte[] oemId = new byte[4]; + + System.arraycopy(raw, 4, oemId, 0, 3); + + oemId[3] = 0; + + responseData.setOemId(TypeConverter.littleEndianByteArrayToInt(oemId)); + + responseData.setOemData(raw[7]); + + return responseData; + } + + /** + * Sets session parameters. + * + * @param version + * - IPMI version of the command. + * @param cipherSuite + * - {@link CipherSuite} containing authentication, + * confidentiality and integrity algorithms for this session. + * @param authenticationType + * - Type of authentication used. Must be RMCPPlus for IPMI v2.0. + */ + @Override + public void setSessionParameters( + IpmiVersion version, + CipherSuite cipherSuite, + AuthenticationType authenticationType) { + + if (version == IpmiVersion.V20 + && authenticationType != AuthenticationType.RMCPPlus + && authenticationType != AuthenticationType.None) { + throw new IllegalArgumentException( + "Authentication Type must be RMCPPlus for IPMI v2.0 messages"); + } - responseData.setAnonymusLoginEnabled((raw[2] & 0x01) != 0); - - byte[] oemId = new byte[4]; - - System.arraycopy(raw, 4, oemId, 0, 3); - - oemId[3] = 0; - - responseData.setOemId(TypeConverter.littleEndianByteArrayToInt(oemId)); - - responseData.setOemData(raw[7]); - - return responseData; - } - - /** - * Sets session parameters. - * - * @param version - * - IPMI version of the command. - * @param cipherSuite - * - {@link CipherSuite} containing authentication, - * confidentiality and integrity algorithms for this session. - * @param authenticationType - * - Type of authentication used. Must be RMCPPlus for IPMI v2.0. - */ - @Override - public void setSessionParameters(IpmiVersion version, - CipherSuite cipherSuite, AuthenticationType authenticationType) { - - if (version == IpmiVersion.V20 - && authenticationType != AuthenticationType.RMCPPlus - && authenticationType != AuthenticationType.None) { - throw new IllegalArgumentException( - "Authentication Type must be RMCPPlus for IPMI v2.0 messages"); - } - - setIpmiVersion(version); - setAuthenticationType(authenticationType); - setCipherSuite(cipherSuite); - } + setIpmiVersion(version); + setAuthenticationType(authenticationType); + setCipherSuite(cipherSuite); + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/session/GetChannelAuthenticationCapabilitiesResponseData.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/session/GetChannelAuthenticationCapabilitiesResponseData.java index dc3124f..0968d4d 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/session/GetChannelAuthenticationCapabilitiesResponseData.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/session/GetChannelAuthenticationCapabilitiesResponseData.java @@ -29,152 +29,153 @@ /** * A wrapper for Get Channel Authentication Capabilities command response + * * @see GetChannelAuthenticationCapabilities */ public class GetChannelAuthenticationCapabilitiesResponseData implements ResponseData { - /** - * Channel number that the Authentication Capabilities is being returned for. - */ - private byte channelNumber; - - /** - * IPMI v2.0 support. - */ - private boolean ipmiv20Support; - - /** - * Authentication Types supported for requested privilege level. - */ - private Collection authenticationTypes; - - /** - * BMC key used for authentication. If false, then BMC uses user key. - */ - private boolean kgEnabled; - - /** - * If Mer-message Authentication is enabled, packets to the BMC must be authenticated per Authentication Type used - * to activate the session, and User Level Authentication setting, following. Otherwise, Authentication Type 'None' - * accepted for packets to the BMC after the session has been activated. - */ - private boolean perMessageAuthenticationEnabled; - - /** - * If User Level Authentication is enabled, User Level commands must be authenticated per Authentication Type used - * to activate the session. Otherwise, Authentication Type 'none' accepted for User Level commands to the BMC. - */ - private boolean userLevelAuthenticationEnabled; - - /** - * One or more users are enabled that have non-null usernames - */ - private boolean nonNullUsernamesEnabled; - - /** - * One or more users that have a null username, but non-null password, are presently enabled - */ - private boolean nullUsernamesEnabled; - - /** - * A user that has a null username and null password is presently enabled - */ - private boolean anonymusLoginEnabled; - - /** - * IANA Enterprise Number for OEM/Organization that specified the particular OEM Authentication Type for RMCP. - */ - private int oemId; - - /** - * Additional OEM-specific information for the OEM Authentication Type for RMCP. - */ - private byte oemData; - - public void setChannelNumber(byte channelNumber) { - this.channelNumber = channelNumber; - } - - public byte getChannelNumber() { - return channelNumber; - } - - public void setIpmiv20Support(boolean ipmiv20Support) { - this.ipmiv20Support = ipmiv20Support; - } - - public boolean isIpmiv20Support() { - return ipmiv20Support; - } - - public void setAuthenticationTypes(Collection authenticationTypes) { - this.authenticationTypes = authenticationTypes; - } - - public Collection getAuthenticationTypes() { - return authenticationTypes; - } - - public void setKgEnabled(boolean kgEnabled) { - this.kgEnabled = kgEnabled; - } - - public boolean isKgEnabled() { - return kgEnabled; - } - - public void setPerMessageAuthenticationEnabled(boolean perMessageAuthenticationEnabled) { - this.perMessageAuthenticationEnabled = perMessageAuthenticationEnabled; - } - - public boolean isPerMessageAuthenticationEnabled() { - return perMessageAuthenticationEnabled; - } - - public void setUserLevelAuthenticationEnabled(boolean userLevelAuthenticationEnabled) { - this.userLevelAuthenticationEnabled = userLevelAuthenticationEnabled; - } - - public boolean isUserLevelAuthenticationEnabled() { - return userLevelAuthenticationEnabled; - } - - public void setNonNullUsernamesEnabled(boolean nonNullUsernamesEnabled) { - this.nonNullUsernamesEnabled = nonNullUsernamesEnabled; - } - - public boolean isNonNullUsernamesEnabled() { - return nonNullUsernamesEnabled; - } - - public void setNullUsernamesEnabled(boolean nullUsernamesEnabled) { - this.nullUsernamesEnabled = nullUsernamesEnabled; - } - - public boolean isNullUsernamesEnabled() { - return nullUsernamesEnabled; - } - - public void setAnonymusLoginEnabled(boolean anonymusLoginEnabled) { - this.anonymusLoginEnabled = anonymusLoginEnabled; - } - - public boolean isAnonymusLoginEnabled() { - return anonymusLoginEnabled; - } - - public void setOemId(int oemId) { - this.oemId = oemId; - } - - public int getOemId() { - return oemId; - } - - public void setOemData(byte oemData) { - this.oemData = oemData; - } - - public byte getOemData() { - return oemData; - } + /** + * Channel number that the Authentication Capabilities is being returned for. + */ + private byte channelNumber; + + /** + * IPMI v2.0 support. + */ + private boolean ipmiv20Support; + + /** + * Authentication Types supported for requested privilege level. + */ + private Collection authenticationTypes; + + /** + * BMC key used for authentication. If false, then BMC uses user key. + */ + private boolean kgEnabled; + + /** + * If Mer-message Authentication is enabled, packets to the BMC must be authenticated per Authentication Type used + * to activate the session, and User Level Authentication setting, following. Otherwise, Authentication Type 'None' + * accepted for packets to the BMC after the session has been activated. + */ + private boolean perMessageAuthenticationEnabled; + + /** + * If User Level Authentication is enabled, User Level commands must be authenticated per Authentication Type used + * to activate the session. Otherwise, Authentication Type 'none' accepted for User Level commands to the BMC. + */ + private boolean userLevelAuthenticationEnabled; + + /** + * One or more users are enabled that have non-null usernames + */ + private boolean nonNullUsernamesEnabled; + + /** + * One or more users that have a null username, but non-null password, are presently enabled + */ + private boolean nullUsernamesEnabled; + + /** + * A user that has a null username and null password is presently enabled + */ + private boolean anonymusLoginEnabled; + + /** + * IANA Enterprise Number for OEM/Organization that specified the particular OEM Authentication Type for RMCP. + */ + private int oemId; + + /** + * Additional OEM-specific information for the OEM Authentication Type for RMCP. + */ + private byte oemData; + + public void setChannelNumber(byte channelNumber) { + this.channelNumber = channelNumber; + } + + public byte getChannelNumber() { + return channelNumber; + } + + public void setIpmiv20Support(boolean ipmiv20Support) { + this.ipmiv20Support = ipmiv20Support; + } + + public boolean isIpmiv20Support() { + return ipmiv20Support; + } + + public void setAuthenticationTypes(Collection authenticationTypes) { + this.authenticationTypes = authenticationTypes; + } + + public Collection getAuthenticationTypes() { + return authenticationTypes; + } + + public void setKgEnabled(boolean kgEnabled) { + this.kgEnabled = kgEnabled; + } + + public boolean isKgEnabled() { + return kgEnabled; + } + + public void setPerMessageAuthenticationEnabled(boolean perMessageAuthenticationEnabled) { + this.perMessageAuthenticationEnabled = perMessageAuthenticationEnabled; + } + + public boolean isPerMessageAuthenticationEnabled() { + return perMessageAuthenticationEnabled; + } + + public void setUserLevelAuthenticationEnabled(boolean userLevelAuthenticationEnabled) { + this.userLevelAuthenticationEnabled = userLevelAuthenticationEnabled; + } + + public boolean isUserLevelAuthenticationEnabled() { + return userLevelAuthenticationEnabled; + } + + public void setNonNullUsernamesEnabled(boolean nonNullUsernamesEnabled) { + this.nonNullUsernamesEnabled = nonNullUsernamesEnabled; + } + + public boolean isNonNullUsernamesEnabled() { + return nonNullUsernamesEnabled; + } + + public void setNullUsernamesEnabled(boolean nullUsernamesEnabled) { + this.nullUsernamesEnabled = nullUsernamesEnabled; + } + + public boolean isNullUsernamesEnabled() { + return nullUsernamesEnabled; + } + + public void setAnonymusLoginEnabled(boolean anonymusLoginEnabled) { + this.anonymusLoginEnabled = anonymusLoginEnabled; + } + + public boolean isAnonymusLoginEnabled() { + return anonymusLoginEnabled; + } + + public void setOemId(int oemId) { + this.oemId = oemId; + } + + public int getOemId() { + return oemId; + } + + public void setOemData(byte oemData) { + this.oemData = oemData; + } + + public byte getOemData() { + return oemData; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/session/GetChannelCipherSuites.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/session/GetChannelCipherSuites.java index d795e81..0a7efbe 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/session/GetChannelCipherSuites.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/session/GetChannelCipherSuites.java @@ -47,134 +47,155 @@ */ public class GetChannelCipherSuites extends IpmiCommandCoder { - private byte channelNumber; - - private byte index; - - /** - * Sets the channel number that will be put into IPMI command. - * - * @param channelNumber - * - must be 0h-Bh or Eh-Fh
- * Eh = retrieve information for channel this request was issued - * on - * @throws IllegalArgumentException - */ - public void setChannelNumber(int channelNumber) { - if (channelNumber < 0 || channelNumber > 0xF || channelNumber == 0xC - || channelNumber == 0xD) { - throw new IllegalArgumentException("Invalid channel number"); - } - this.channelNumber = TypeConverter.intToByte(channelNumber); - } - - public int getChannelNumber() { - return TypeConverter.byteToInt(channelNumber); - } - - public void setIndex(byte index) { - if (index > 0x3F || index < 0) { - throw new IllegalArgumentException("Index " + index + " invalid must be (00h-3Fh)."); - } - this.index = index; - } - - public byte getIndex() { - return index; - } - - /** - * Initiates class for decoding. - */ - public GetChannelCipherSuites() { - super(IpmiVersion.V20, new CipherSuite((byte) 0, (byte) 0, (byte) 0, - (byte) 0), AuthenticationType.RMCPPlus); - } - - /** - * Initiates class for both encoding and decoding. - * - * @param channelNumber - * - must be 0h-Bh or Eh-Fh
- * Eh = retrieve information for channel this request was issued - * on - * @param index - * - (00h-3Fh). 0h selects the first set of 16 cipher suites, 1h - * selects the next set of 16, and so on - */ - public GetChannelCipherSuites(byte channelNumber, byte index) { - super(IpmiVersion.V20, new CipherSuite((byte) 0, (byte) 0, (byte) 0, - (byte) 0), AuthenticationType.RMCPPlus); - setChannelNumber(channelNumber); - setIndex(index); - } - - @Override - public IpmiMessage encodePayload(int messageSequenceNumber, int sessionSequenceNumber, int sessionId) - throws NoSuchAlgorithmException, InvalidKeyException { - Ipmiv20Message message = new Ipmiv20Message(new ConfidentialityNone()); - - message.setAuthenticationType(getAuthenticationType()); - - message.setSessionID(0); - - message.setPayloadEncrypted(false); - - message.setPayloadAuthenticated(false); - - message.setSessionSequenceNumber(0); - - message.setPayloadType(PayloadType.Ipmi); - - message.setPayload(preparePayload(messageSequenceNumber)); - - return message; - } - - @Override - protected IpmiLanMessage preparePayload(int sequenceNumber) { - byte[] requestData = new byte[3]; - - requestData[0] = channelNumber; - - requestData[1] = 0; // payload type = IPMI - - requestData[2] = TypeConverter.intToByte(0x80 | getIndex()); - - return new IpmiLanRequest(getNetworkFunction(), getCommandCode(), - requestData, TypeConverter.intToByte(sequenceNumber)); - } - - @Override - public byte getCommandCode() { - return CommandCodes.GET_CHANNEL_CIPHER_SUITES; - } - - @Override - public NetworkFunction getNetworkFunction() { - return NetworkFunction.ApplicationRequest; - } - - @Override - public ResponseData getResponseData(IpmiMessage message) throws IPMIException, NoSuchAlgorithmException, InvalidKeyException { + private byte channelNumber; + + private byte index; + + /** + * Sets the channel number that will be put into IPMI command. + * + * @param channelNumber + * - must be 0h-Bh or Eh-Fh
+ * Eh = retrieve information for channel this request was issued + * on + * @throws IllegalArgumentException + */ + public void setChannelNumber(int channelNumber) { + if (channelNumber < 0 + || channelNumber > 0xF + || channelNumber == 0xC + || channelNumber == 0xD) { + throw new IllegalArgumentException("Invalid channel number"); + } + this.channelNumber = TypeConverter.intToByte(channelNumber); + } + + public int getChannelNumber() { + return TypeConverter.byteToInt(channelNumber); + } + + public void setIndex(byte index) { + if (index > 0x3F || index < 0) { + throw new IllegalArgumentException("Index " + index + " invalid must be (00h-3Fh)."); + } + this.index = index; + } + + public byte getIndex() { + return index; + } + + /** + * Initiates class for decoding. + */ + public GetChannelCipherSuites() { + super( + IpmiVersion.V20, + new CipherSuite( + (byte) 0, + (byte) 0, + (byte) 0, + (byte) 0), + AuthenticationType.RMCPPlus); + } + + /** + * Initiates class for both encoding and decoding. + * + * @param channelNumber + * - must be 0h-Bh or Eh-Fh
+ * Eh = retrieve information for channel this request was issued + * on + * @param index + * - (00h-3Fh). 0h selects the first set of 16 cipher suites, 1h + * selects the next set of 16, and so on + */ + public GetChannelCipherSuites(byte channelNumber, byte index) { + super( + IpmiVersion.V20, + new CipherSuite( + (byte) 0, + (byte) 0, + (byte) 0, + (byte) 0), + AuthenticationType.RMCPPlus); + setChannelNumber(channelNumber); + setIndex(index); + } + + @Override + public IpmiMessage encodePayload(int messageSequenceNumber, int sessionSequenceNumber, int sessionId) + throws NoSuchAlgorithmException, + InvalidKeyException { + Ipmiv20Message message = new Ipmiv20Message(new ConfidentialityNone()); + + message.setAuthenticationType(getAuthenticationType()); + + message.setSessionID(0); + + message.setPayloadEncrypted(false); + + message.setPayloadAuthenticated(false); + + message.setSessionSequenceNumber(0); + + message.setPayloadType(PayloadType.Ipmi); + + message.setPayload(preparePayload(messageSequenceNumber)); + + return message; + } + + @Override + protected IpmiLanMessage preparePayload(int sequenceNumber) { + byte[] requestData = new byte[3]; + + requestData[0] = channelNumber; + + requestData[1] = 0; // payload type = IPMI + + requestData[2] = TypeConverter.intToByte(0x80 | getIndex()); + + return new IpmiLanRequest( + getNetworkFunction(), + getCommandCode(), + requestData, + TypeConverter.intToByte(sequenceNumber)); + } + + @Override + public byte getCommandCode() { + return CommandCodes.GET_CHANNEL_CIPHER_SUITES; + } + + @Override + public NetworkFunction getNetworkFunction() { + return NetworkFunction.ApplicationRequest; + } + + @Override + public ResponseData getResponseData(IpmiMessage message) + throws IPMIException, + NoSuchAlgorithmException, + InvalidKeyException { + + GetChannelCipherSuitesResponseData data = new GetChannelCipherSuitesResponseData(); + + byte[] raw = message.getPayload().getIpmiCommandData(); + + data.setChannelNumber(raw[0]); + + if (raw.length > 1) { + byte[] cssData = new byte[raw.length - 1]; + + System.arraycopy(raw, 1, cssData, 0, cssData.length); + + data.setCipherSuiteData(cssData); + } else if (raw.length == 1) { + data.setCipherSuiteData(new byte[0]); + } - GetChannelCipherSuitesResponseData data = new GetChannelCipherSuitesResponseData(); - - byte[] raw = message.getPayload().getIpmiCommandData(); - - data.setChannelNumber(raw[0]); - - if (raw.length > 1) { - byte[] cssData = new byte[raw.length - 1]; - - System.arraycopy(raw, 1, cssData, 0, cssData.length); - - data.setCipherSuiteData(cssData); - } else if(raw.length == 1) { - data.setCipherSuiteData(new byte[0]); - } - - return data; - } + return data; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/session/GetChannelCipherSuitesResponseData.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/session/GetChannelCipherSuitesResponseData.java index 5a591f1..0e4e583 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/session/GetChannelCipherSuitesResponseData.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/session/GetChannelCipherSuitesResponseData.java @@ -29,23 +29,23 @@ */ public class GetChannelCipherSuitesResponseData implements ResponseData { - private byte channelNumber; + private byte channelNumber; - private byte[] cipherSuiteData; + private byte[] cipherSuiteData; - public void setChannelNumber(byte channelNumber) { - this.channelNumber = channelNumber; - } + public void setChannelNumber(byte channelNumber) { + this.channelNumber = channelNumber; + } - public byte getChannelNumber() { - return channelNumber; - } + public byte getChannelNumber() { + return channelNumber; + } - public void setCipherSuiteData(byte[] cipherSuiteData) { - this.cipherSuiteData = cipherSuiteData; - } + public void setCipherSuiteData(byte[] cipherSuiteData) { + this.cipherSuiteData = cipherSuiteData; + } - public byte[] getCipherSuiteData() { - return cipherSuiteData; - } + public byte[] getCipherSuiteData() { + return cipherSuiteData; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/session/OpenSession.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/session/OpenSession.java index a7f83ed..e8e6ad9 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/session/OpenSession.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/session/OpenSession.java @@ -47,243 +47,248 @@ */ public class OpenSession extends IpmiCommandCoder { - private PrivilegeLevel requestedPrivilegeLevel; - - /** - * Remote console Session ID. - */ - private int sessionID; - - public void setRequestedPrivilegeLevel( - PrivilegeLevel requestedPrivilegeLevel) { - this.requestedPrivilegeLevel = requestedPrivilegeLevel; - } - - public PrivilegeLevel getRequestedPrivilegeLevel() { - return requestedPrivilegeLevel; - } - - private byte getRequestedPrivilegeLevelEncoded() { - switch (requestedPrivilegeLevel) { - case MaximumAvailable: - return 0; - case Callback: - return TypeConverter.intToByte(0x1); - case User: - return TypeConverter.intToByte(0x2); - case Operator: - return TypeConverter.intToByte(0x3); - case Administrator: - return TypeConverter.intToByte(0x4); - default: - throw new IllegalArgumentException("Invalid privilege level"); - } - } - - public void setSessionID(int sessionID) { - this.sessionID = sessionID; - } - - public int getSessionID() { - return sessionID; - } - - /** - * Initiates class for decoding. Sets IPMI version to - * {@link IpmiVersion#V20} since OpenSession is a RMCP+ command. Sets - * authentication type to RMCP+. - * - * @param cipherSuite - * - {@link CipherSuite} containing authentication, - * confidentiality and integrity algorithms for this session. - * Cipher Suite might (and probably will be, because at this - * point of session creation SIK is not yet known) be not - * initialized. - * - * @see IpmiVersion - */ - public OpenSession(CipherSuite cipherSuite) { - super(IpmiVersion.V20, cipherSuite, AuthenticationType.RMCPPlus); - setCipherSuite(cipherSuite); - } - - /** - * Initiates class for encoding and decoding. Sets IPMI version to - * {@link IpmiVersion#V20} since OpenSession is a RMCP+ command. Sets - * authentication type to RMCP+. - * - * @see IpmiVersion - * - * @param sessionID - * - Session ID selected by the remote console. - * @param privilegeLevel - * - Requested privilege level for the session. Can be - * {@link PrivilegeLevel#MaximumAvailable}. - * @param cipherSuite - * - {@link CipherSuite} containing authentication, - * confidentiality and integrity algorithms for this session. - * Cipher Suite might (and probably will be, because at this - * point of session creation SIK is not yet known) be not - * initialized. - * @see CipherSuite - * @see AuthenticationAlgorithm - * @see IntegrityAlgorithm - * @see ConfidentialityAlgorithm - */ - public OpenSession(int sessionID, PrivilegeLevel privilegeLevel, - CipherSuite cipherSuite) { - super(IpmiVersion.V20, cipherSuite, AuthenticationType.RMCPPlus); - - setSessionID(sessionID); - setRequestedPrivilegeLevel(privilegeLevel); - } - - @Override - public IpmiMessage encodePayload(int messageSequenceNumber, int sessionSequenceNumber, int sessionId) { - if (sessionId != 0) { - throw new IllegalArgumentException("Session ID must be 0"); - } - Ipmiv20Message message = new Ipmiv20Message(new ConfidentialityNone()); - - message.setPayloadType(PayloadType.RmcpOpenSessionRequest); - message.setSessionID(0); - message.setSessionSequenceNumber(0); - message.setAuthenticationType(getAuthenticationType()); - message.setPayloadAuthenticated(false); - message.setPayloadEncrypted(false); - message.setPayload(preparePayload(messageSequenceNumber)); - - return message; - } - - @Override - protected IpmiPayload preparePayload(int sequenceNumber) { - byte[] payload = new byte[32]; - - payload[0] = TypeConverter.intToByte(sequenceNumber); - - payload[1] = getRequestedPrivilegeLevelEncoded(); - - payload[2] = 0; // reserved - payload[3] = 0; // reserved - - // prepare requested session ID - byte[] id = TypeConverter.intToLittleEndianByteArray(sessionID); - - System.arraycopy(id, 0, payload, 4, 4); - - // Authentication Payload - - payload[8] = 0; // payload type - payload[9] = 0; // reserved - payload[10] = 0; // reserved - payload[11] = 0x08; // payload length - payload[12] = getCipherSuite().getAuthenticationAlgorithm().getCode(); // authentication - // algorithm - // specific - // code - payload[13] = 0; // reserved - payload[14] = 0; // reserved - payload[15] = 0; // reserved - - // Integrity Payload - - payload[16] = 0x01; // payload type - payload[17] = 0; // reserved - payload[18] = 0; // reserved - payload[19] = 0x08; // payload length - payload[20] = getCipherSuite().getIntegrityAlgorithm().getCode(); // integrity - // algorithm - // specific - // code - payload[21] = 0; // reserved - payload[22] = 0; // reserved - payload[23] = 0; // reserved - - // Confidentiality Payload - - payload[24] = 0x02; // payload type - payload[25] = 0; // reserved - payload[26] = 0; // reserved - payload[27] = 0x08; // payload length - payload[28] = getCipherSuite().getConfidentialityAlgorithm().getCode(); // confidentiality - // algorithm - // specific - // code - payload[29] = 0; // reserved - payload[30] = 0; // reserved - payload[31] = 0; // reserved - - return new PlainMessage(payload); - } + private PrivilegeLevel requestedPrivilegeLevel; + + /** + * Remote console Session ID. + */ + private int sessionID; + + public void setRequestedPrivilegeLevel( + PrivilegeLevel requestedPrivilegeLevel) { + this.requestedPrivilegeLevel = requestedPrivilegeLevel; + } + + public PrivilegeLevel getRequestedPrivilegeLevel() { + return requestedPrivilegeLevel; + } + + private byte getRequestedPrivilegeLevelEncoded() { + switch (requestedPrivilegeLevel) { + case MaximumAvailable: + return 0; + case Callback: + return TypeConverter.intToByte(0x1); + case User: + return TypeConverter.intToByte(0x2); + case Operator: + return TypeConverter.intToByte(0x3); + case Administrator: + return TypeConverter.intToByte(0x4); + default: + throw new IllegalArgumentException("Invalid privilege level"); + } + } + + public void setSessionID(int sessionID) { + this.sessionID = sessionID; + } + + public int getSessionID() { + return sessionID; + } + + /** + * Initiates class for decoding. Sets IPMI version to + * {@link IpmiVersion#V20} since OpenSession is a RMCP+ command. Sets + * authentication type to RMCP+. + * + * @param cipherSuite + * - {@link CipherSuite} containing authentication, + * confidentiality and integrity algorithms for this session. + * Cipher Suite might (and probably will be, because at this + * point of session creation SIK is not yet known) be not + * initialized. + * @see IpmiVersion + */ + public OpenSession(CipherSuite cipherSuite) { + super(IpmiVersion.V20, cipherSuite, AuthenticationType.RMCPPlus); + setCipherSuite(cipherSuite); + } + + /** + * Initiates class for encoding and decoding. Sets IPMI version to + * {@link IpmiVersion#V20} since OpenSession is a RMCP+ command. Sets + * authentication type to RMCP+. + * + * @see IpmiVersion + * @param sessionID + * - Session ID selected by the remote console. + * @param privilegeLevel + * - Requested privilege level for the session. Can be + * {@link PrivilegeLevel#MaximumAvailable}. + * @param cipherSuite + * - {@link CipherSuite} containing authentication, + * confidentiality and integrity algorithms for this session. + * Cipher Suite might (and probably will be, because at this + * point of session creation SIK is not yet known) be not + * initialized. + * @see CipherSuite + * @see AuthenticationAlgorithm + * @see IntegrityAlgorithm + * @see ConfidentialityAlgorithm + */ + public OpenSession(int sessionID, PrivilegeLevel privilegeLevel, + CipherSuite cipherSuite) { + super(IpmiVersion.V20, cipherSuite, AuthenticationType.RMCPPlus); + + setSessionID(sessionID); + setRequestedPrivilegeLevel(privilegeLevel); + } + + @Override + public IpmiMessage encodePayload(int messageSequenceNumber, int sessionSequenceNumber, int sessionId) { + if (sessionId != 0) { + throw new IllegalArgumentException("Session ID must be 0"); + } + Ipmiv20Message message = new Ipmiv20Message(new ConfidentialityNone()); + + message.setPayloadType(PayloadType.RmcpOpenSessionRequest); + message.setSessionID(0); + message.setSessionSequenceNumber(0); + message.setAuthenticationType(getAuthenticationType()); + message.setPayloadAuthenticated(false); + message.setPayloadEncrypted(false); + message.setPayload(preparePayload(messageSequenceNumber)); + + return message; + } + + @Override + protected IpmiPayload preparePayload(int sequenceNumber) { + byte[] payload = new byte[32]; + + payload[0] = TypeConverter.intToByte(sequenceNumber); + + payload[1] = getRequestedPrivilegeLevelEncoded(); + + payload[2] = 0; // reserved + payload[3] = 0; // reserved + + // prepare requested session ID + byte[] id = TypeConverter.intToLittleEndianByteArray(sessionID); + + System.arraycopy(id, 0, payload, 4, 4); + + // Authentication Payload + + payload[8] = 0; // payload type + payload[9] = 0; // reserved + payload[10] = 0; // reserved + payload[11] = 0x08; // payload length + payload[12] = getCipherSuite().getAuthenticationAlgorithm().getCode(); // authentication + // algorithm + // specific + // code + payload[13] = 0; // reserved + payload[14] = 0; // reserved + payload[15] = 0; // reserved + + // Integrity Payload + + payload[16] = 0x01; // payload type + payload[17] = 0; // reserved + payload[18] = 0; // reserved + payload[19] = 0x08; // payload length + payload[20] = getCipherSuite().getIntegrityAlgorithm().getCode(); // integrity + // algorithm + // specific + // code + payload[21] = 0; // reserved + payload[22] = 0; // reserved + payload[23] = 0; // reserved + + // Confidentiality Payload + + payload[24] = 0x02; // payload type + payload[25] = 0; // reserved + payload[26] = 0; // reserved + payload[27] = 0x08; // payload length + payload[28] = getCipherSuite().getConfidentialityAlgorithm().getCode(); // confidentiality + // algorithm + // specific + // code + payload[29] = 0; // reserved + payload[30] = 0; // reserved + payload[31] = 0; // reserved + + return new PlainMessage(payload); + } + + @Override + public NetworkFunction getNetworkFunction() { + return NetworkFunction.ChassisRequest; + } - @Override - public NetworkFunction getNetworkFunction() { - return NetworkFunction.ChassisRequest; - } + @Override + public byte getCommandCode() { + return 0; + } - @Override - public byte getCommandCode() { - return 0; - } + @Override + public ResponseData getResponseData(IpmiMessage message) throws IPMIException { + if (!isCommandResponse(message)) { + throw new IllegalArgumentException( + "This is not a response for Open Session command"); + } - @Override - public ResponseData getResponseData(IpmiMessage message) throws IPMIException { - if (!isCommandResponse(message)) { - throw new IllegalArgumentException( - "This is not a response for Open Session command"); - } + byte[] payload = message.getPayload().getPayloadData(); - byte[] payload = message.getPayload().getPayloadData(); + if (payload[1] != 0) { + throw new IPMIException( + CompletionCode + .parseInt( + TypeConverter + .byteToInt(payload[1]))); + } - if (payload[1] != 0) { - throw new IPMIException(CompletionCode.parseInt(TypeConverter - .byteToInt(payload[1]))); - } + if (payload.length < 36) { + throw new IllegalArgumentException("Invalid payload length"); + } - if (payload.length < 36) { - throw new IllegalArgumentException("Invalid payload length"); - } + OpenSessionResponseData data = new OpenSessionResponseData(); - OpenSessionResponseData data = new OpenSessionResponseData(); + data.setMessageTag(payload[0]); - data.setMessageTag(payload[0]); + data.setStatusCode(payload[1]); - data.setStatusCode(payload[1]); + data.setPrivilegeLevel(payload[2]); - data.setPrivilegeLevel(payload[2]); + byte[] buffer = new byte[4]; - byte[] buffer = new byte[4]; + System.arraycopy(payload, 4, buffer, 0, 4); - System.arraycopy(payload, 4, buffer, 0, 4); + data + .setRemoteConsoleSessionId( + TypeConverter + .littleEndianByteArrayToInt(buffer)); - data.setRemoteConsoleSessionId(TypeConverter - .littleEndianByteArrayToInt(buffer)); + System.arraycopy(payload, 8, buffer, 0, 4); - System.arraycopy(payload, 8, buffer, 0, 4); + data + .setManagedSystemSessionId( + TypeConverter + .littleEndianByteArrayToInt(buffer)); - data.setManagedSystemSessionId(TypeConverter - .littleEndianByteArrayToInt(buffer)); + byte[] auth = new byte[8]; - byte[] auth = new byte[8]; + System.arraycopy(payload, 12, auth, 0, 8); - System.arraycopy(payload, 12, auth, 0, 8); + data.setAuthenticationAlgorithm(auth[4]); - data.setAuthenticationAlgorithm(auth[4]); + byte[] integr = new byte[8]; - byte[] integr = new byte[8]; + System.arraycopy(payload, 20, integr, 0, 8); - System.arraycopy(payload, 20, integr, 0, 8); + data.setIntegrityAlgorithm(integr[4]); - data.setIntegrityAlgorithm(integr[4]); + byte[] conf = new byte[8]; - byte[] conf = new byte[8]; + System.arraycopy(payload, 28, conf, 0, 8); - System.arraycopy(payload, 28, conf, 0, 8); + data.setConfidentialityAlgorithm(conf[4]); - data.setConfidentialityAlgorithm(conf[4]); - - return data; - } + return data; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/session/OpenSessionResponseData.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/session/OpenSessionResponseData.java index 54eae74..c333b6e 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/session/OpenSessionResponseData.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/session/OpenSessionResponseData.java @@ -28,129 +28,129 @@ /** * A wrapper for Open Session command response - * + * * @see OpenSession */ public class OpenSessionResponseData implements ResponseData { - /** - * The BMC returns the Message Tag value that was passed by the remote - * console in the Open Session Request message - */ - private byte messageTag; - - /** - * Identifies the status of the previous message. If the previous message - * generated an error, then only the Status Code, Reserved, and Remote - * Console Session ID fields are returned. - */ - private byte statusCode; - - /** - * Indicates the Maximum Privilege Level allowed for the session. - */ - private byte privilegeLevel; - - /** - * The Remote Console Session ID specified by RMCP+ Open Session Request - * message associated with this response. - */ - private int remoteConsoleSessionId; - - /** - * The Session ID selected by the Managed System for this new session. - */ - private int managedSystemSessionId; - - /** - * This payload defines the authentication algorithm proposal selected by - * the Managed System to be used for this session - */ - private byte authenticationAlgorithm; - - /** - * This payload defines the integrity algorithm proposal selected by the - * Managed System to be used for this session - */ - private byte integrityAlgorithm; - - /** - * This payload defines the confidentiality algorithm proposal selected by - * the Managed System to be used for this session - */ - private byte confidentialityAlgorithm; - - public void setMessageTag(byte messageTag) { - this.messageTag = messageTag; - } - - public byte getMessageTag() { - return messageTag; - } - - public void setStatusCode(byte statusCode) { - this.statusCode = statusCode; - } - - public byte getStatusCode() { - return statusCode; - } - - public void setPrivilegeLevel(byte privilegeLevel) { - this.privilegeLevel = privilegeLevel; - } - - public PrivilegeLevel getPrivilegeLevel() { - switch (privilegeLevel) { - case CommandsConstants.AL_CALLBACK: - return PrivilegeLevel.Callback; - case CommandsConstants.AL_USER: - return PrivilegeLevel.User; - case CommandsConstants.AL_OPERATOR: - return PrivilegeLevel.Operator; - case CommandsConstants.AL_ADMINISTRATOR: - return PrivilegeLevel.Administrator; - default: - throw new IllegalArgumentException("Invalid privilege level"); - } - } - - public void setRemoteConsoleSessionId(int remoteConsoleSessionId) { - this.remoteConsoleSessionId = remoteConsoleSessionId; - } - - public int getRemoteConsoleSessionId() { - return remoteConsoleSessionId; - } - - public void setManagedSystemSessionId(int managedSystemSessionId) { - this.managedSystemSessionId = managedSystemSessionId; - } - - public int getManagedSystemSessionId() { - return managedSystemSessionId; - } - - public void setAuthenticationAlgorithm(byte authenticationAlgorithm) { - this.authenticationAlgorithm = authenticationAlgorithm; - } - - public byte getAuthenticationAlgorithm() { - return authenticationAlgorithm; - } - - public void setIntegrityAlgorithm(byte integrityAlgorithm) { - this.integrityAlgorithm = integrityAlgorithm; - } - - public byte getIntegrityAlgorithm() { - return integrityAlgorithm; - } - - public void setConfidentialityAlgorithm(byte confidentialityAlgorithm) { - this.confidentialityAlgorithm = confidentialityAlgorithm; - } - - public byte getConfidentialityAlgorithm() { - return confidentialityAlgorithm; - } + /** + * The BMC returns the Message Tag value that was passed by the remote + * console in the Open Session Request message + */ + private byte messageTag; + + /** + * Identifies the status of the previous message. If the previous message + * generated an error, then only the Status Code, Reserved, and Remote + * Console Session ID fields are returned. + */ + private byte statusCode; + + /** + * Indicates the Maximum Privilege Level allowed for the session. + */ + private byte privilegeLevel; + + /** + * The Remote Console Session ID specified by RMCP+ Open Session Request + * message associated with this response. + */ + private int remoteConsoleSessionId; + + /** + * The Session ID selected by the Managed System for this new session. + */ + private int managedSystemSessionId; + + /** + * This payload defines the authentication algorithm proposal selected by + * the Managed System to be used for this session + */ + private byte authenticationAlgorithm; + + /** + * This payload defines the integrity algorithm proposal selected by the + * Managed System to be used for this session + */ + private byte integrityAlgorithm; + + /** + * This payload defines the confidentiality algorithm proposal selected by + * the Managed System to be used for this session + */ + private byte confidentialityAlgorithm; + + public void setMessageTag(byte messageTag) { + this.messageTag = messageTag; + } + + public byte getMessageTag() { + return messageTag; + } + + public void setStatusCode(byte statusCode) { + this.statusCode = statusCode; + } + + public byte getStatusCode() { + return statusCode; + } + + public void setPrivilegeLevel(byte privilegeLevel) { + this.privilegeLevel = privilegeLevel; + } + + public PrivilegeLevel getPrivilegeLevel() { + switch (privilegeLevel) { + case CommandsConstants.AL_CALLBACK: + return PrivilegeLevel.Callback; + case CommandsConstants.AL_USER: + return PrivilegeLevel.User; + case CommandsConstants.AL_OPERATOR: + return PrivilegeLevel.Operator; + case CommandsConstants.AL_ADMINISTRATOR: + return PrivilegeLevel.Administrator; + default: + throw new IllegalArgumentException("Invalid privilege level"); + } + } + + public void setRemoteConsoleSessionId(int remoteConsoleSessionId) { + this.remoteConsoleSessionId = remoteConsoleSessionId; + } + + public int getRemoteConsoleSessionId() { + return remoteConsoleSessionId; + } + + public void setManagedSystemSessionId(int managedSystemSessionId) { + this.managedSystemSessionId = managedSystemSessionId; + } + + public int getManagedSystemSessionId() { + return managedSystemSessionId; + } + + public void setAuthenticationAlgorithm(byte authenticationAlgorithm) { + this.authenticationAlgorithm = authenticationAlgorithm; + } + + public byte getAuthenticationAlgorithm() { + return authenticationAlgorithm; + } + + public void setIntegrityAlgorithm(byte integrityAlgorithm) { + this.integrityAlgorithm = integrityAlgorithm; + } + + public byte getIntegrityAlgorithm() { + return integrityAlgorithm; + } + + public void setConfidentialityAlgorithm(byte confidentialityAlgorithm) { + this.confidentialityAlgorithm = confidentialityAlgorithm; + } + + public byte getConfidentialityAlgorithm() { + return confidentialityAlgorithm; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/session/Rakp1.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/session/Rakp1.java index 67a142d..7726c1d 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/session/Rakp1.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/session/Rakp1.java @@ -57,393 +57,436 @@ */ public class Rakp1 extends IpmiCommandCoder { - /** - * The Managed System's Session ID for this session. Must be as returned by - * the Managed System in the Open Session Response message. - */ - private int managedSystemSessionId; - - /** - * The random number generated by console. - */ - private byte[] consoleRandomNumber; - - private PrivilegeLevel requestedMaximumPrivilegeLevel; - - /** - * ASCII character Name that the user at the Remote Console wishes to assume - * for this session. It's length cannot exceed 16. - */ - private String username; - - /** - * Password matching username. - */ - private String password; - - /** - * Kg key associated with the target BMC. Should be null if Get Channel - * Authentication Capabilities Response indicated that Kg is disabled which - * means that 'one-key' logins are being used ( - * {@link GetChannelAuthenticationCapabilitiesResponseData#isKgEnabled()} == - * false) - */ - private byte[] bmcKey; - - public void setManagedSystemSessionId(int managedSystemSessionId) { - this.managedSystemSessionId = managedSystemSessionId; - } - - public int getManagedSystemSessionId() { - return managedSystemSessionId; - } - - public void setRequestedMaximumPrivilegeLevel( - PrivilegeLevel requestedMaximumPrivilegeLevel) { - this.requestedMaximumPrivilegeLevel = requestedMaximumPrivilegeLevel; - } - - public PrivilegeLevel getRequestedMaximumPrivilegeLevel() { - return requestedMaximumPrivilegeLevel; - } - - public void setUsername(String username) { - if (username.length() > 16) { - throw new IllegalArgumentException( - "Username is too long. It's length cannot exceed 16"); - } - this.username = username; - } - - public String getUsername() { - return username; - } - - private void setPassword(String password) { - this.password = password; - } - - public String getPassword() { - return password; - } - - private void setConsoleRandomNumber(byte[] randomNumber) { - this.consoleRandomNumber = randomNumber; - } - - public byte[] getConsoleRandomNumber() { - return consoleRandomNumber; - } - - private void setBmcKey(byte[] bmcKey) { - this.bmcKey = bmcKey; - } - - public byte[] getBmcKey() { - return bmcKey; - } - - /** - * Initiates class for encoding and decoding. Sets IPMI version to - * {@link IpmiVersion#V20} since RAKP1 is a RMCP+ command. Sets - * Authentication Type to RMCP+. - * - * @param managedSystemSessionId - * - The Managed System's Session ID for this session. Must be as - * returned by the Managed System in the Open Session Response - * message. - * @param privilegeLevel - * - Requested Maximum {@link PrivilegeLevel} - * @param username - * - ASCII character Name that the user at the Remote Console - * wishes to assume for this session. It's length cannot exceed - * 16. - * @param password - * - password matching username - * @param bmcKey - * - BMC specific key. Should be null if Get Channel - * Authentication Capabilities Response indicated that Kg is - * disabled which means that 'one-key' logins are being used ( - * {@link GetChannelAuthenticationCapabilitiesResponseData#isKgEnabled()} - * == false) - * @param cipherSuite - * - {@link CipherSuite} containing authentication, - * confidentiality and integrity algorithms for this session. - */ - public Rakp1(int managedSystemSessionId, PrivilegeLevel privilegeLevel, - String username, String password, byte[] bmcKey, - CipherSuite cipherSuite) { - super(IpmiVersion.V20, cipherSuite, AuthenticationType.RMCPPlus); - setManagedSystemSessionId(managedSystemSessionId); - setRequestedMaximumPrivilegeLevel(privilegeLevel); - setUsername(username); - setPassword(password); - this.setBmcKey(bmcKey); - - // prepare random number - byte[] random = new byte[16]; - - for (int i = 0; i < 4; ++i) { - byte[] rand = TypeConverter.intToLittleEndianByteArray(Randomizer - .getInt()); - - System.arraycopy(rand, 0, random, 4 * i, 4); - } - - setConsoleRandomNumber(random); - } - - @Override - public IpmiMessage encodePayload(int messageSequenceNumber, int sessionSequenceNumber, int sessionId) { - if (sessionId != 0) { - throw new IllegalArgumentException("Session ID must be 0"); - } - Ipmiv20Message message = new Ipmiv20Message(new ConfidentialityNone()); - - message.setPayloadType(PayloadType.Rakp1); - message.setSessionID(0); - message.setSessionSequenceNumber(0); - message.setAuthenticationType(getAuthenticationType()); - message.setPayloadAuthenticated(false); - message.setPayloadEncrypted(false); - - message.setPayload(preparePayload(messageSequenceNumber)); - - return message; - } - - @Override - protected IpmiPayload preparePayload(int sequenceNumber) { - byte[] payload = null; - - if (getUsername() == null) { - setUsername(""); - } - - payload = new byte[28 + getUsername().length()]; - - // message tag - payload[0] = TypeConverter.intToByte(sequenceNumber); - - payload[1] = 0; // reserved - payload[2] = 0; // reserved - payload[3] = 0; // reserved - - byte[] sId = TypeConverter - .intToLittleEndianByteArray(getManagedSystemSessionId()); - - System.arraycopy(sId, 0, payload, 4, 4); // managed system session ID - - System.arraycopy(consoleRandomNumber, 0, payload, 8, 16); // generated - // random - // number - - // requested privilege level; set name-only lookup - payload[24] = TypeConverter - .intToByte(encodePrivilegeLevel(requestedMaximumPrivilegeLevel) | 0x10); - - payload[25] = 0; // reserved - payload[26] = 0; // reserved - - payload[27] = TypeConverter.intToByte(getUsername().length()); // username - // length - - if (getUsername().length() > 0) { - System.arraycopy(getUsername().getBytes(), 0, payload, 28, - getUsername().length()); // username - } - - return new PlainMessage(payload); - } - - @Override - public byte getCommandCode() { - return 0; - } + /** + * The Managed System's Session ID for this session. Must be as returned by + * the Managed System in the Open Session Response message. + */ + private int managedSystemSessionId; + + /** + * The random number generated by console. + */ + private byte[] consoleRandomNumber; + + private PrivilegeLevel requestedMaximumPrivilegeLevel; + + /** + * ASCII character Name that the user at the Remote Console wishes to assume + * for this session. It's length cannot exceed 16. + */ + private String username; + + /** + * Password matching username. + */ + private String password; + + /** + * Kg key associated with the target BMC. Should be null if Get Channel + * Authentication Capabilities Response indicated that Kg is disabled which + * means that 'one-key' logins are being used ( + * {@link GetChannelAuthenticationCapabilitiesResponseData#isKgEnabled()} == + * false) + */ + private byte[] bmcKey; + + public void setManagedSystemSessionId(int managedSystemSessionId) { + this.managedSystemSessionId = managedSystemSessionId; + } + + public int getManagedSystemSessionId() { + return managedSystemSessionId; + } + + public void setRequestedMaximumPrivilegeLevel( + PrivilegeLevel requestedMaximumPrivilegeLevel) { + this.requestedMaximumPrivilegeLevel = requestedMaximumPrivilegeLevel; + } + + public PrivilegeLevel getRequestedMaximumPrivilegeLevel() { + return requestedMaximumPrivilegeLevel; + } + + public void setUsername(String username) { + if (username.length() > 16) { + throw new IllegalArgumentException( + "Username is too long. It's length cannot exceed 16"); + } + this.username = username; + } + + public String getUsername() { + return username; + } + + private void setPassword(String password) { + this.password = password; + } + + public String getPassword() { + return password; + } + + private void setConsoleRandomNumber(byte[] randomNumber) { + this.consoleRandomNumber = randomNumber; + } + + public byte[] getConsoleRandomNumber() { + return consoleRandomNumber; + } + + private void setBmcKey(byte[] bmcKey) { + this.bmcKey = bmcKey; + } + + public byte[] getBmcKey() { + return bmcKey; + } + + /** + * Initiates class for encoding and decoding. Sets IPMI version to + * {@link IpmiVersion#V20} since RAKP1 is a RMCP+ command. Sets + * Authentication Type to RMCP+. + * + * @param managedSystemSessionId + * - The Managed System's Session ID for this session. Must be as + * returned by the Managed System in the Open Session Response + * message. + * @param privilegeLevel + * - Requested Maximum {@link PrivilegeLevel} + * @param username + * - ASCII character Name that the user at the Remote Console + * wishes to assume for this session. It's length cannot exceed + * 16. + * @param password + * - password matching username + * @param bmcKey + * - BMC specific key. Should be null if Get Channel + * Authentication Capabilities Response indicated that Kg is + * disabled which means that 'one-key' logins are being used ( + * {@link GetChannelAuthenticationCapabilitiesResponseData#isKgEnabled()} + * == false) + * @param cipherSuite + * - {@link CipherSuite} containing authentication, + * confidentiality and integrity algorithms for this session. + */ + public Rakp1(int managedSystemSessionId, PrivilegeLevel privilegeLevel, + String username, String password, byte[] bmcKey, + CipherSuite cipherSuite) { + super(IpmiVersion.V20, cipherSuite, AuthenticationType.RMCPPlus); + setManagedSystemSessionId(managedSystemSessionId); + setRequestedMaximumPrivilegeLevel(privilegeLevel); + setUsername(username); + setPassword(password); + this.setBmcKey(bmcKey); + + // prepare random number + byte[] random = new byte[16]; + + for (int i = 0; i < 4; ++i) { + byte[] rand = TypeConverter + .intToLittleEndianByteArray( + Randomizer + .getInt()); + + System.arraycopy(rand, 0, random, 4 * i, 4); + } + + setConsoleRandomNumber(random); + } + + @Override + public IpmiMessage encodePayload(int messageSequenceNumber, int sessionSequenceNumber, int sessionId) { + if (sessionId != 0) { + throw new IllegalArgumentException("Session ID must be 0"); + } + Ipmiv20Message message = new Ipmiv20Message(new ConfidentialityNone()); + + message.setPayloadType(PayloadType.Rakp1); + message.setSessionID(0); + message.setSessionSequenceNumber(0); + message.setAuthenticationType(getAuthenticationType()); + message.setPayloadAuthenticated(false); + message.setPayloadEncrypted(false); + + message.setPayload(preparePayload(messageSequenceNumber)); + + return message; + } + + @Override + protected IpmiPayload preparePayload(int sequenceNumber) { + byte[] payload = null; + + if (getUsername() == null) { + setUsername(""); + } + + payload = new byte[28 + getUsername().length()]; + + // message tag + payload[0] = TypeConverter.intToByte(sequenceNumber); + + payload[1] = 0; // reserved + payload[2] = 0; // reserved + payload[3] = 0; // reserved + + byte[] sId = TypeConverter + .intToLittleEndianByteArray(getManagedSystemSessionId()); + + System.arraycopy(sId, 0, payload, 4, 4); // managed system session ID + + System.arraycopy(consoleRandomNumber, 0, payload, 8, 16); // generated + // random + // number + + // requested privilege level; set name-only lookup + payload[24] = TypeConverter + .intToByte(encodePrivilegeLevel(requestedMaximumPrivilegeLevel) | 0x10); + + payload[25] = 0; // reserved + payload[26] = 0; // reserved + + payload[27] = TypeConverter.intToByte(getUsername().length()); // username + // length + + if (getUsername().length() > 0) { + System + .arraycopy( + getUsername().getBytes(), + 0, + payload, + 28, + getUsername().length()); // username + } + + return new PlainMessage(payload); + } + + @Override + public byte getCommandCode() { + return 0; + } + + @Override + public NetworkFunction getNetworkFunction() { + return null; + } + + /** + * @throws IllegalArgumentException + * when message is not a response for class-specific command, + * response has invalid length or authentication check fails. + * @throws NoSuchAlgorithmException + * - when authentication, confidentiality or integrity algorithm + * fails. + * @throws InvalidKeyException + * - when creating of the algorithm key fails + */ + @Override + public ResponseData getResponseData(IpmiMessage message) + throws IPMIException, + NoSuchAlgorithmException, + InvalidKeyException { + if (!isCommandResponse(message)) { + throw new IllegalArgumentException("This is not RAKP 2 message!"); + } - @Override - public NetworkFunction getNetworkFunction() { - return null; - } - - /** - * @throws IllegalArgumentException - * when message is not a response for class-specific command, - * response has invalid length or authentication check fails. - * @throws NoSuchAlgorithmException - * - when authentication, confidentiality or integrity algorithm - * fails. - * @throws InvalidKeyException - * - when creating of the algorithm key fails - */ - @Override - public ResponseData getResponseData(IpmiMessage message) throws IPMIException, NoSuchAlgorithmException, InvalidKeyException { - if (!isCommandResponse(message)) { - throw new IllegalArgumentException("This is not RAKP 2 message!"); - } - - byte[] payload = message.getPayload().getPayloadData(); - - Rakp1ResponseData data = new Rakp1ResponseData(); - - data.setMessageTag(payload[0]); - - data.setStatusCode(payload[1]); - - if (payload[1] != 0) { - throw new IPMIException(CompletionCode.parseInt(TypeConverter - .byteToInt(payload[1]))); - } - - if (payload.length < 40) { - throw new IllegalArgumentException("Invalid payload length"); - } - - byte[] buffer = new byte[4]; - - System.arraycopy(payload, 4, buffer, 0, 4); - - data.setRemoteConsoleSessionId(TypeConverter - .littleEndianByteArrayToInt(buffer)); - - byte[] managedSystemGuid = new byte[16]; - - System.arraycopy(payload, 24, managedSystemGuid, 0, 16); - - data.setManagedSystemGuid(managedSystemGuid); - - byte[] managedSystemRandomNumber = new byte[16]; - - System.arraycopy(payload, 8, managedSystemRandomNumber, 0, 16); - - data.setManagedSystemRandomNumber(managedSystemRandomNumber); - - byte[] key = null; - - int length = getCipherSuite().getAuthenticationAlgorithm() - .getKeyLength(); - - if (length > 0) { - key = new byte[length]; - System.arraycopy(payload, 40, key, 0, length); - } - - if (!getCipherSuite().getAuthenticationAlgorithm() - .checkKeyExchangeAuthenticationCode( - prepareKeyExchangeAuthenticationCodeBase(data), key, - getPassword())) { - throw new IllegalArgumentException("Authentication check failed"); - } - - return data; - } - - /** - * @return byte array holding prepared base for calculating - * KeyExchangeAuthenticationCode for RAKP Message 2 - */ - private byte[] prepareKeyExchangeAuthenticationCodeBase( - Rakp1ResponseData responseData) { - int length = 58; - if (getUsername() != null) { - length += getUsername().length(); - } - byte[] keac = new byte[length]; - - byte[] rSID = TypeConverter.intToLittleEndianByteArray(responseData - .getRemoteConsoleSessionId()); - - System.arraycopy(rSID, 0, keac, 0, 4); - - byte[] mSID = TypeConverter - .intToLittleEndianByteArray(getManagedSystemSessionId()); - - System.arraycopy(mSID, 0, keac, 4, 4); - - System.arraycopy(getConsoleRandomNumber(), 0, keac, 8, 16); - - System.arraycopy(responseData.getManagedSystemRandomNumber(), 0, keac, - 24, 16); - - System.arraycopy(responseData.getManagedSystemGuid(), 0, keac, 40, 16); - - keac[56] = TypeConverter - .intToByte(encodePrivilegeLevel(requestedMaximumPrivilegeLevel) | 0x10); - - if (getUsername() != null) { - keac[57] = TypeConverter.intToByte(getUsername().length()); - if (getUsername().length() > 0) { - System.arraycopy(getUsername().getBytes(), 0, keac, 58, - getUsername().length()); - } - } else { - keac[57] = 0; - } - - return keac; - } - - /** - * Calculates SIK (Session Integrity Key) based on RAKP Messages 1 and 2 - * - * @param responseData - * RAKP Message 2 data - * @return Session Integrity Key - * @throws NoSuchAlgorithmException - * - when authentication, confidentiality or integrity algorithm - * fails. - * @throws InvalidKeyException - * - when creating of the algorithm key fails - */ - public byte[] calculateSik(Rakp1ResponseData responseData) - throws InvalidKeyException, NoSuchAlgorithmException { - byte[] key = null; - if (getBmcKey() == null || getBmcKey().length <= 0) { - key = getPassword().getBytes(); - } else { - key = getBmcKey(); - } - - return getCipherSuite().getAuthenticationAlgorithm() - .getKeyExchangeAuthenticationCode(prepareSikBase(responseData), - new String(key)); - } - - /** - * @return byte array holding prepared base for calculating Session - * Integrity Key - */ - private byte[] prepareSikBase(Rakp1ResponseData responseData) { - int length = 34; - if (getUsername() != null) { - length += getUsername().length(); - } - - byte[] sikBase = new byte[length]; - - System.arraycopy(getConsoleRandomNumber(), 0, sikBase, 0, 16); - - System.arraycopy(responseData.getManagedSystemRandomNumber(), 0, - sikBase, 16, 16); - - sikBase[32] = TypeConverter - .intToByte(encodePrivilegeLevel(requestedMaximumPrivilegeLevel) | 0x10); - - if (getUsername() != null) { - sikBase[33] = TypeConverter.intToByte(getUsername().length()); - if (getUsername().length() > 0) { - System.arraycopy(getUsername().getBytes(), 0, sikBase, 34, - getUsername().length()); - } - } else { - sikBase[33] = 0; - } - - return sikBase; - } - - @Override - public boolean isCommandResponse(IpmiMessage message) { - return message instanceof Ipmiv20Message && ((Ipmiv20Message) message).getPayloadType() == PayloadType.Rakp2; - } + byte[] payload = message.getPayload().getPayloadData(); + + Rakp1ResponseData data = new Rakp1ResponseData(); + + data.setMessageTag(payload[0]); + + data.setStatusCode(payload[1]); + + if (payload[1] != 0) { + throw new IPMIException( + CompletionCode + .parseInt( + TypeConverter + .byteToInt(payload[1]))); + } + + if (payload.length < 40) { + throw new IllegalArgumentException("Invalid payload length"); + } + + byte[] buffer = new byte[4]; + + System.arraycopy(payload, 4, buffer, 0, 4); + + data + .setRemoteConsoleSessionId( + TypeConverter + .littleEndianByteArrayToInt(buffer)); + + byte[] managedSystemGuid = new byte[16]; + + System.arraycopy(payload, 24, managedSystemGuid, 0, 16); + + data.setManagedSystemGuid(managedSystemGuid); + + byte[] managedSystemRandomNumber = new byte[16]; + + System.arraycopy(payload, 8, managedSystemRandomNumber, 0, 16); + + data.setManagedSystemRandomNumber(managedSystemRandomNumber); + + byte[] key = null; + + int length = getCipherSuite() + .getAuthenticationAlgorithm() + .getKeyLength(); + + if (length > 0) { + key = new byte[length]; + System.arraycopy(payload, 40, key, 0, length); + } + + if (!getCipherSuite() + .getAuthenticationAlgorithm() + .checkKeyExchangeAuthenticationCode( + prepareKeyExchangeAuthenticationCodeBase(data), + key, + getPassword())) { + throw new IllegalArgumentException("Authentication check failed"); + } + + return data; + } + + /** + * @return byte array holding prepared base for calculating + * KeyExchangeAuthenticationCode for RAKP Message 2 + */ + private byte[] prepareKeyExchangeAuthenticationCodeBase( + Rakp1ResponseData responseData) { + int length = 58; + if (getUsername() != null) { + length += getUsername().length(); + } + byte[] keac = new byte[length]; + + byte[] rSID = TypeConverter + .intToLittleEndianByteArray( + responseData + .getRemoteConsoleSessionId()); + + System.arraycopy(rSID, 0, keac, 0, 4); + + byte[] mSID = TypeConverter + .intToLittleEndianByteArray(getManagedSystemSessionId()); + + System.arraycopy(mSID, 0, keac, 4, 4); + + System.arraycopy(getConsoleRandomNumber(), 0, keac, 8, 16); + + System + .arraycopy( + responseData.getManagedSystemRandomNumber(), + 0, + keac, + 24, + 16); + + System.arraycopy(responseData.getManagedSystemGuid(), 0, keac, 40, 16); + + keac[56] = TypeConverter + .intToByte(encodePrivilegeLevel(requestedMaximumPrivilegeLevel) | 0x10); + + if (getUsername() != null) { + keac[57] = TypeConverter.intToByte(getUsername().length()); + if (getUsername().length() > 0) { + System + .arraycopy( + getUsername().getBytes(), + 0, + keac, + 58, + getUsername().length()); + } + } else { + keac[57] = 0; + } + + return keac; + } + + /** + * Calculates SIK (Session Integrity Key) based on RAKP Messages 1 and 2 + * + * @param responseData + * RAKP Message 2 data + * @return Session Integrity Key + * @throws NoSuchAlgorithmException + * - when authentication, confidentiality or integrity algorithm + * fails. + * @throws InvalidKeyException + * - when creating of the algorithm key fails + */ + public byte[] calculateSik(Rakp1ResponseData responseData) + throws InvalidKeyException, + NoSuchAlgorithmException { + byte[] key = null; + if (getBmcKey() == null || getBmcKey().length <= 0) { + key = getPassword().getBytes(); + } else { + key = getBmcKey(); + } + + return getCipherSuite() + .getAuthenticationAlgorithm() + .getKeyExchangeAuthenticationCode( + prepareSikBase(responseData), + new String(key)); + } + + /** + * @return byte array holding prepared base for calculating Session + * Integrity Key + */ + private byte[] prepareSikBase(Rakp1ResponseData responseData) { + int length = 34; + if (getUsername() != null) { + length += getUsername().length(); + } + + byte[] sikBase = new byte[length]; + + System.arraycopy(getConsoleRandomNumber(), 0, sikBase, 0, 16); + + System + .arraycopy( + responseData.getManagedSystemRandomNumber(), + 0, + sikBase, + 16, + 16); + + sikBase[32] = TypeConverter + .intToByte(encodePrivilegeLevel(requestedMaximumPrivilegeLevel) | 0x10); + + if (getUsername() != null) { + sikBase[33] = TypeConverter.intToByte(getUsername().length()); + if (getUsername().length() > 0) { + System + .arraycopy( + getUsername().getBytes(), + 0, + sikBase, + 34, + getUsername().length()); + } + } else { + sikBase[33] = 0; + } + + return sikBase; + } + + @Override + public boolean isCommandResponse(IpmiMessage message) { + return message instanceof Ipmiv20Message && ((Ipmiv20Message) message).getPayloadType() == PayloadType.Rakp2; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/session/Rakp1ResponseData.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/session/Rakp1ResponseData.java index d30eff8..c32fb6c 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/session/Rakp1ResponseData.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/session/Rakp1ResponseData.java @@ -26,57 +26,58 @@ /** * A wrapper for RAKP 2 message. + * * @see Rakp1 */ public class Rakp1ResponseData implements ResponseData { - private byte messageTag; + private byte messageTag; - private byte statusCode; + private byte statusCode; - private int remoteConsoleSessionId; + private int remoteConsoleSessionId; - private byte[] managedSystemRandomNumber; + private byte[] managedSystemRandomNumber; - private byte[] managedSystemGuid; + private byte[] managedSystemGuid; - public void setMessageTag(byte messageTag) { - this.messageTag = messageTag; - } + public void setMessageTag(byte messageTag) { + this.messageTag = messageTag; + } - public byte getMessageTag() { - return messageTag; - } + public byte getMessageTag() { + return messageTag; + } - public void setStatusCode(byte statusCode) { - this.statusCode = statusCode; - } + public void setStatusCode(byte statusCode) { + this.statusCode = statusCode; + } - public byte getStatusCode() { - return statusCode; - } + public byte getStatusCode() { + return statusCode; + } - public void setRemoteConsoleSessionId(int remoteConsoleSessionId) { - this.remoteConsoleSessionId = remoteConsoleSessionId; - } + public void setRemoteConsoleSessionId(int remoteConsoleSessionId) { + this.remoteConsoleSessionId = remoteConsoleSessionId; + } - public int getRemoteConsoleSessionId() { - return remoteConsoleSessionId; - } + public int getRemoteConsoleSessionId() { + return remoteConsoleSessionId; + } - public void setManagedSystemGuid(byte[] managedSystemGuid) { - this.managedSystemGuid = managedSystemGuid; - } + public void setManagedSystemGuid(byte[] managedSystemGuid) { + this.managedSystemGuid = managedSystemGuid; + } - public byte[] getManagedSystemGuid() { - return managedSystemGuid; - } + public byte[] getManagedSystemGuid() { + return managedSystemGuid; + } - public void setManagedSystemRandomNumber(byte[] randomNumber) { - this.managedSystemRandomNumber = randomNumber; - } + public void setManagedSystemRandomNumber(byte[] randomNumber) { + this.managedSystemRandomNumber = randomNumber; + } - public byte[] getManagedSystemRandomNumber() { - return managedSystemRandomNumber; - } + public byte[] getManagedSystemRandomNumber() { + return managedSystemRandomNumber; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/session/Rakp3.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/session/Rakp3.java index 7726fd6..36a6c75 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/session/Rakp3.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/session/Rakp3.java @@ -48,277 +48,354 @@ */ public class Rakp3 extends IpmiCommandCoder { - /** - * Status of the previous message. - */ - private byte statusCode; - - /** - * The Managed System's Session ID for this session. Must be as returned by - * the Managed System in the Open Session Response message. - */ - private int managedSystemSessionId; - - private Rakp1 rakp1; - - private Rakp1ResponseData rakp1ResponseData; - - public void setStatusCode(byte statusCode) { - this.statusCode = statusCode; - } - - public byte getStatusCode() { - return statusCode; - } - - public void setManagedSystemSessionId(int managedSystemSessionId) { - this.managedSystemSessionId = managedSystemSessionId; - } - - public int getManagedSystemSessionId() { - return managedSystemSessionId; - } - - /** - * Initiates class for decoding. Sets IPMI version to - * {@link IpmiVersion#V20} since RAKP1 is a RMCP+ command. Sets - * Authentication Type to RMCP+. - * - * @param cipherSuite - * - {@link CipherSuite} containing authentication, - * confidentiality and integrity algorithms for this session. - * Only authentication algorithm is used at this point of - * creating a session. - * @param rakp1 - * - RAKP Message 1 sent earlier in the authentification process - * @param rakp1ResponseData - * - RAKP Message 2 received earlier in the authentification - * process - * - */ - public Rakp3(CipherSuite cipherSuite, Rakp1 rakp1, - Rakp1ResponseData rakp1ResponseData) { - super(IpmiVersion.V20, cipherSuite, AuthenticationType.RMCPPlus); - this.rakp1 = rakp1; - this.rakp1ResponseData = rakp1ResponseData; - setCipherSuite(new CipherSuite((byte) 0, cipherSuite - .getAuthenticationAlgorithm().getCode(), (byte) 0, (byte) 0)); - } - - /** - * Initiates class for encoding and decoding. Sets IPMI version to - * {@link IpmiVersion#V20} since RAKP1 is a RMCP+ command. Sets - * Authentication Type to RMCP+. - * - * @param statusCode - * - Status of the previous message. - * @param managedSystemSessionId - * - The Managed Systemļæ½s Session ID for this session. Must be as - * returned by the Managed System in the Open Session Response - * message. - * @param cipherSuite - * - {@link CipherSuite} containing authentication, - * confidentiality and integrity algorithms for this session. - * Only authentication algorithm is used at this point of - * creating a session. - * @param rakp1 - * - RAKP Message 1 sent earlier in the authentification process - * @param rakp1ResponseData - * - RAKP Message 2 received earlier in the authentification - * process - */ - public Rakp3(byte statusCode, int managedSystemSessionId, - CipherSuite cipherSuite, Rakp1 rakp1, - Rakp1ResponseData rakp1ResponseData) { - super(IpmiVersion.V20, cipherSuite, AuthenticationType.RMCPPlus); - setStatusCode(statusCode); - setManagedSystemSessionId(managedSystemSessionId); - this.rakp1 = rakp1; - this.rakp1ResponseData = rakp1ResponseData; - setCipherSuite(new CipherSuite((byte) 0, cipherSuite - .getAuthenticationAlgorithm().getCode(), (byte) 0, (byte) 0)); - } - - @Override - public IpmiMessage encodePayload(int messageSequenceNumber, int sessionSequenceNumber, int sessionId) - throws NoSuchAlgorithmException, InvalidKeyException { - - if (sessionId != 0) { - throw new IllegalArgumentException("Session ID must be 0"); - } - - Ipmiv20Message message = new Ipmiv20Message(new ConfidentialityNone()); - - message.setPayloadType(PayloadType.Rakp3); - message.setSessionID(0); - message.setSessionSequenceNumber(0); - message.setAuthenticationType(getAuthenticationType()); - message.setPayloadAuthenticated(getCipherSuite() - .getIntegrityAlgorithm().getCode() != SecurityConstants.IA_NONE); - message.setPayloadEncrypted(false); - - message.setPayload(preparePayload(messageSequenceNumber)); - - message.setAuthCode(getCipherSuite() - .getIntegrityAlgorithm() - .generateAuthCode( - message.getIntegrityAlgorithmBase(new Protocolv20Encoder()))); - - return message; - } - - @Override - protected IpmiPayload preparePayload(int sequenceNumber) - throws NoSuchAlgorithmException, InvalidKeyException { - byte[] payload = new byte[8]; - - payload[0] = TypeConverter.intToByte(sequenceNumber); // message - // tag - - payload[1] = getStatusCode(); // last message status code - - payload[2] = 0; // reserved - payload[3] = 0; // reserved - - byte[] manSesId = TypeConverter - .intToLittleEndianByteArray(getManagedSystemSessionId()); - - System.arraycopy(manSesId, 0, payload, 4, 4); // managed system session - // id - - byte[] exchangeAuthCode = getCipherSuite().getAuthenticationAlgorithm() - .getKeyExchangeAuthenticationCode( - prepareKeyExchangeAuthenticationCodeBase(rakp1, - rakp1ResponseData), rakp1.getPassword()); - - byte[] result = null; - - if (exchangeAuthCode != null) { - result = new byte[8 + exchangeAuthCode.length]; - System.arraycopy(exchangeAuthCode, 0, result, 8, - exchangeAuthCode.length); - } else { - result = new byte[8]; - } - - System.arraycopy(payload, 0, result, 0, 8); - - return new PlainMessage(result); - } - - /** - * @return byte array holding prepared base for calculating - * KeyExchangeAuthenticationCode for RAKP Message 3 - */ - private byte[] prepareKeyExchangeAuthenticationCodeBase(Rakp1 rakp1, - Rakp1ResponseData responseData) { - int length = 22; - if (rakp1.getUsername() != null) { - length += rakp1.getUsername().length(); - } - byte[] keac = new byte[length]; - - System.arraycopy(responseData.getManagedSystemRandomNumber(), 0, keac, - 0, 16); - - System.arraycopy(TypeConverter.intToLittleEndianByteArray(responseData - .getRemoteConsoleSessionId()), 0, keac, 16, 4); - - keac[20] = TypeConverter.intToByte(encodePrivilegeLevel(rakp1 - .getRequestedMaximumPrivilegeLevel()) | 0x10); - - if (rakp1.getUsername() != null) { - keac[21] = TypeConverter.intToByte(rakp1.getUsername().length()); - if (rakp1.getUsername().length() > 0) { - System.arraycopy(rakp1.getUsername().getBytes(), 0, keac, 22, - rakp1.getUsername().length()); - } - } else { - keac[21] = 0; - } - - return keac; - } - - @Override - public byte getCommandCode() { - return 0; - } - - @Override - public NetworkFunction getNetworkFunction() { - return null; - } - - @Override - public ResponseData getResponseData(IpmiMessage message) throws IPMIException, InvalidKeyException, NoSuchAlgorithmException { - - if (!isCommandResponse(message)) { - throw new IllegalArgumentException("This is not RAKP 4 message!"); - } - - byte[] payload = message.getPayload().getPayloadData(); - - Rakp3ResponseData data = new Rakp3ResponseData(); - - data.setMessageTag(payload[0]); - - data.setStatusCode(payload[1]); - - if (payload[1] != 0) { - throw new IPMIException(CompletionCode.parseInt(TypeConverter - .byteToInt(payload[1]))); - } - - if (payload.length < 8) { - throw new IllegalArgumentException("Invalid payload length"); - } - - byte[] buffer = new byte[4]; - - System.arraycopy(payload, 4, buffer, 0, 4); - - data.setConsoleSessionId(TypeConverter - .littleEndianByteArrayToInt(buffer)); - - byte[] integrityCheck = null; - - if (payload.length > 8) { - integrityCheck = new byte[getCipherSuite() - .getAuthenticationAlgorithm().getIntegrityCheckBaseLength()]; - System.arraycopy(payload, 8, integrityCheck, 0, getCipherSuite() - .getAuthenticationAlgorithm().getIntegrityCheckBaseLength()); - } - - if (!getCipherSuite().getAuthenticationAlgorithm().doIntegrityCheck( - prepareIntegrityCheckBase(rakp1, rakp1ResponseData), - integrityCheck, rakp1.calculateSik(rakp1ResponseData))) { - throw new IllegalArgumentException("Integrity check failed"); - } - - return data; - } - - /** - * @return byte array holding prepared base for calculating Integrity Check - */ - private byte[] prepareIntegrityCheckBase(Rakp1 rakp1, - Rakp1ResponseData responseData) { - byte[] icb = new byte[36]; - - System.arraycopy(rakp1.getConsoleRandomNumber(), 0, icb, 0, 16); - - System.arraycopy(TypeConverter.intToLittleEndianByteArray(rakp1 - .getManagedSystemSessionId()), 0, icb, 16, 4); - - System.arraycopy(responseData.getManagedSystemGuid(), 0, icb, 20, 16); - - return icb; - } - - @Override - public boolean isCommandResponse(IpmiMessage message) { - return message instanceof Ipmiv20Message && ((Ipmiv20Message) message).getPayloadType() == PayloadType.Rakp4; - } + /** + * Status of the previous message. + */ + private byte statusCode; + + /** + * The Managed System's Session ID for this session. Must be as returned by + * the Managed System in the Open Session Response message. + */ + private int managedSystemSessionId; + + private Rakp1 rakp1; + + private Rakp1ResponseData rakp1ResponseData; + + public void setStatusCode(byte statusCode) { + this.statusCode = statusCode; + } + + public byte getStatusCode() { + return statusCode; + } + + public void setManagedSystemSessionId(int managedSystemSessionId) { + this.managedSystemSessionId = managedSystemSessionId; + } + + public int getManagedSystemSessionId() { + return managedSystemSessionId; + } + + /** + * Initiates class for decoding. Sets IPMI version to + * {@link IpmiVersion#V20} since RAKP1 is a RMCP+ command. Sets + * Authentication Type to RMCP+. + * + * @param cipherSuite + * - {@link CipherSuite} containing authentication, + * confidentiality and integrity algorithms for this session. + * Only authentication algorithm is used at this point of + * creating a session. + * @param rakp1 + * - RAKP Message 1 sent earlier in the authentification process + * @param rakp1ResponseData + * - RAKP Message 2 received earlier in the authentification + * process + */ + public Rakp3(CipherSuite cipherSuite, Rakp1 rakp1, + Rakp1ResponseData rakp1ResponseData) { + super(IpmiVersion.V20, cipherSuite, AuthenticationType.RMCPPlus); + this.rakp1 = rakp1; + this.rakp1ResponseData = rakp1ResponseData; + setCipherSuite( + new CipherSuite( + (byte) 0, + cipherSuite + .getAuthenticationAlgorithm() + .getCode(), + (byte) 0, + (byte) 0)); + } + + /** + * Initiates class for encoding and decoding. Sets IPMI version to + * {@link IpmiVersion#V20} since RAKP1 is a RMCP+ command. Sets + * Authentication Type to RMCP+. + * + * @param statusCode + * - Status of the previous message. + * @param managedSystemSessionId + * - The Managed Systemļæ½s Session ID for this session. Must be as + * returned by the Managed System in the Open Session Response + * message. + * @param cipherSuite + * - {@link CipherSuite} containing authentication, + * confidentiality and integrity algorithms for this session. + * Only authentication algorithm is used at this point of + * creating a session. + * @param rakp1 + * - RAKP Message 1 sent earlier in the authentification process + * @param rakp1ResponseData + * - RAKP Message 2 received earlier in the authentification + * process + */ + public Rakp3(byte statusCode, int managedSystemSessionId, + CipherSuite cipherSuite, Rakp1 rakp1, + Rakp1ResponseData rakp1ResponseData) { + super(IpmiVersion.V20, cipherSuite, AuthenticationType.RMCPPlus); + setStatusCode(statusCode); + setManagedSystemSessionId(managedSystemSessionId); + this.rakp1 = rakp1; + this.rakp1ResponseData = rakp1ResponseData; + setCipherSuite( + new CipherSuite( + (byte) 0, + cipherSuite + .getAuthenticationAlgorithm() + .getCode(), + (byte) 0, + (byte) 0)); + } + + @Override + public IpmiMessage encodePayload(int messageSequenceNumber, int sessionSequenceNumber, int sessionId) + throws NoSuchAlgorithmException, + InvalidKeyException { + + if (sessionId != 0) { + throw new IllegalArgumentException("Session ID must be 0"); + } + + Ipmiv20Message message = new Ipmiv20Message(new ConfidentialityNone()); + + message.setPayloadType(PayloadType.Rakp3); + message.setSessionID(0); + message.setSessionSequenceNumber(0); + message.setAuthenticationType(getAuthenticationType()); + message + .setPayloadAuthenticated( + getCipherSuite() + .getIntegrityAlgorithm() + .getCode() != SecurityConstants.IA_NONE); + message.setPayloadEncrypted(false); + + message.setPayload(preparePayload(messageSequenceNumber)); + + message + .setAuthCode( + getCipherSuite() + .getIntegrityAlgorithm() + .generateAuthCode( + message.getIntegrityAlgorithmBase(new Protocolv20Encoder()))); + + return message; + } + + @Override + protected IpmiPayload preparePayload(int sequenceNumber) + throws NoSuchAlgorithmException, + InvalidKeyException { + byte[] payload = new byte[8]; + + payload[0] = TypeConverter.intToByte(sequenceNumber); // message + // tag + + payload[1] = getStatusCode(); // last message status code + + payload[2] = 0; // reserved + payload[3] = 0; // reserved + + byte[] manSesId = TypeConverter + .intToLittleEndianByteArray(getManagedSystemSessionId()); + + System.arraycopy(manSesId, 0, payload, 4, 4); // managed system session + // id + + byte[] exchangeAuthCode = getCipherSuite() + .getAuthenticationAlgorithm() + .getKeyExchangeAuthenticationCode( + prepareKeyExchangeAuthenticationCodeBase( + rakp1, + rakp1ResponseData), + rakp1.getPassword()); + + byte[] result = null; + + if (exchangeAuthCode != null) { + result = new byte[8 + exchangeAuthCode.length]; + System + .arraycopy( + exchangeAuthCode, + 0, + result, + 8, + exchangeAuthCode.length); + } else { + result = new byte[8]; + } + + System.arraycopy(payload, 0, result, 0, 8); + + return new PlainMessage(result); + } + + /** + * @return byte array holding prepared base for calculating + * KeyExchangeAuthenticationCode for RAKP Message 3 + */ + private byte[] prepareKeyExchangeAuthenticationCodeBase( + Rakp1 rakp1Message, + Rakp1ResponseData responseData) { + int length = 22; + if (rakp1Message.getUsername() != null) { + length += rakp1Message.getUsername().length(); + } + byte[] keac = new byte[length]; + + System + .arraycopy( + responseData.getManagedSystemRandomNumber(), + 0, + keac, + 0, + 16); + + System + .arraycopy( + TypeConverter + .intToLittleEndianByteArray( + responseData + .getRemoteConsoleSessionId()), + 0, + keac, + 16, + 4); + + keac[20] = TypeConverter + .intToByte( + encodePrivilegeLevel( + rakp1Message + .getRequestedMaximumPrivilegeLevel()) + | 0x10); + + if (rakp1Message.getUsername() != null) { + keac[21] = TypeConverter.intToByte(rakp1Message.getUsername().length()); + if (rakp1Message.getUsername().length() > 0) { + System + .arraycopy( + rakp1Message.getUsername().getBytes(), + 0, + keac, + 22, + rakp1Message.getUsername().length()); + } + } else { + keac[21] = 0; + } + + return keac; + } + + @Override + public byte getCommandCode() { + return 0; + } + + @Override + public NetworkFunction getNetworkFunction() { + return null; + } + + @Override + public ResponseData getResponseData(IpmiMessage message) + throws IPMIException, + InvalidKeyException, + NoSuchAlgorithmException { + + if (!isCommandResponse(message)) { + throw new IllegalArgumentException("This is not RAKP 4 message!"); + } + + byte[] payload = message.getPayload().getPayloadData(); + + Rakp3ResponseData data = new Rakp3ResponseData(); + + data.setMessageTag(payload[0]); + + data.setStatusCode(payload[1]); + + if (payload[1] != 0) { + throw new IPMIException( + CompletionCode + .parseInt( + TypeConverter + .byteToInt(payload[1]))); + } + + if (payload.length < 8) { + throw new IllegalArgumentException("Invalid payload length"); + } + + byte[] buffer = new byte[4]; + + System.arraycopy(payload, 4, buffer, 0, 4); + + data + .setConsoleSessionId( + TypeConverter + .littleEndianByteArrayToInt(buffer)); + + byte[] integrityCheck = null; + + if (payload.length > 8) { + integrityCheck = new byte[getCipherSuite() + .getAuthenticationAlgorithm() + .getIntegrityCheckBaseLength()]; + System + .arraycopy( + payload, + 8, + integrityCheck, + 0, + getCipherSuite() + .getAuthenticationAlgorithm() + .getIntegrityCheckBaseLength()); + } + + if (!getCipherSuite() + .getAuthenticationAlgorithm() + .doIntegrityCheck( + prepareIntegrityCheckBase(rakp1, rakp1ResponseData), + integrityCheck, + rakp1.calculateSik(rakp1ResponseData))) { + throw new IllegalArgumentException("Integrity check failed"); + } + + return data; + } + + /** + * @return byte array holding prepared base for calculating Integrity Check + */ + private byte[] prepareIntegrityCheckBase( + Rakp1 rakp1Message, + Rakp1ResponseData responseData) { + byte[] icb = new byte[36]; + + System.arraycopy(rakp1Message.getConsoleRandomNumber(), 0, icb, 0, 16); + + System + .arraycopy( + TypeConverter + .intToLittleEndianByteArray( + rakp1Message + .getManagedSystemSessionId()), + 0, + icb, + 16, + 4); + + System.arraycopy(responseData.getManagedSystemGuid(), 0, icb, 20, 16); + + return icb; + } + + @Override + public boolean isCommandResponse(IpmiMessage message) { + return message instanceof Ipmiv20Message && ((Ipmiv20Message) message).getPayloadType() == PayloadType.Rakp4; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/session/Rakp3ResponseData.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/session/Rakp3ResponseData.java index 67bf3fe..ef273c5 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/session/Rakp3ResponseData.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/session/Rakp3ResponseData.java @@ -26,41 +26,42 @@ /** * A wrapper for RAKP 3 message. + * * @see Rakp3 */ public class Rakp3ResponseData implements ResponseData { - private byte messageTag; + private byte messageTag; - private byte statusCode; + private byte statusCode; - /** - * The Console Session ID specified by the RMCP+ Open Session Request - * message associated with this response. - */ - private int consoleSessionId; + /** + * The Console Session ID specified by the RMCP+ Open Session Request + * message associated with this response. + */ + private int consoleSessionId; - public void setMessageTag(byte messageTag) { - this.messageTag = messageTag; - } + public void setMessageTag(byte messageTag) { + this.messageTag = messageTag; + } - public byte getMessageTag() { - return messageTag; - } + public byte getMessageTag() { + return messageTag; + } - public void setStatusCode(byte statusCode) { - this.statusCode = statusCode; - } + public void setStatusCode(byte statusCode) { + this.statusCode = statusCode; + } - public byte getStatusCode() { - return statusCode; - } + public byte getStatusCode() { + return statusCode; + } - public void setConsoleSessionId(int consoleSessionId) { - this.consoleSessionId = consoleSessionId; - } + public void setConsoleSessionId(int consoleSessionId) { + this.consoleSessionId = consoleSessionId; + } - public int getConsoleSessionId() { - return consoleSessionId; - } + public int getConsoleSessionId() { + return consoleSessionId; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/session/SetSessionPrivilegeLevel.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/session/SetSessionPrivilegeLevel.java index 7cec0f0..b5503c2 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/session/SetSessionPrivilegeLevel.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/session/SetSessionPrivilegeLevel.java @@ -46,75 +46,82 @@ */ public class SetSessionPrivilegeLevel extends IpmiCommandCoder { - private PrivilegeLevel privilegeLevel; + private PrivilegeLevel privilegeLevel; - /** - * Initiates {@link SetSessionPrivilegeLevel} for encoding and decoding - * @param version - * - IPMI version of the command. - * @param cipherSuite - * - {@link CipherSuite} containing authentication, confidentiality and integrity algorithms for this session. - * @param authenticationType - * - Type of authentication used. Must be RMCPPlus for IPMI v2.0. - * @param privilegeLevel - * - Requested {@link PrivilegeLevel} to acquire. Can not be higher than level declared during starting session. - */ - public SetSessionPrivilegeLevel(IpmiVersion version, CipherSuite cipherSuite, - AuthenticationType authenticationType, PrivilegeLevel privilegeLevel) { - super(version, cipherSuite, authenticationType); - this.privilegeLevel = privilegeLevel; - } + /** + * Initiates {@link SetSessionPrivilegeLevel} for encoding and decoding + * + * @param version + * - IPMI version of the command. + * @param cipherSuite + * - {@link CipherSuite} containing authentication, confidentiality and integrity algorithms for this session. + * @param authenticationType + * - Type of authentication used. Must be RMCPPlus for IPMI v2.0. + * @param privilegeLevel + * - Requested {@link PrivilegeLevel} to acquire. Can not be higher than level declared during starting + * session. + */ + public SetSessionPrivilegeLevel(IpmiVersion version, CipherSuite cipherSuite, + AuthenticationType authenticationType, PrivilegeLevel privilegeLevel) { + super(version, cipherSuite, authenticationType); + this.privilegeLevel = privilegeLevel; + } - @Override - public byte getCommandCode() { - return CommandCodes.SET_SESSION_PRIVILEGE_LEVEL; - } + @Override + public byte getCommandCode() { + return CommandCodes.SET_SESSION_PRIVILEGE_LEVEL; + } - @Override - public NetworkFunction getNetworkFunction() { - return NetworkFunction.ApplicationRequest; - } + @Override + public NetworkFunction getNetworkFunction() { + return NetworkFunction.ApplicationRequest; + } - @Override - protected IpmiPayload preparePayload(int sequenceNumber) throws NoSuchAlgorithmException, InvalidKeyException { - byte[] requestData = new byte[1]; + @Override + protected IpmiPayload preparePayload(int sequenceNumber) throws NoSuchAlgorithmException, InvalidKeyException { + byte[] requestData = new byte[1]; - requestData[0] = TypeConverter.intToByte(getRequestedPrivilegeLevelEncoded()); + requestData[0] = TypeConverter.intToByte(getRequestedPrivilegeLevelEncoded()); - return new IpmiLanRequest(getNetworkFunction(), getCommandCode(), requestData, - TypeConverter.intToByte(sequenceNumber)); - } + return new IpmiLanRequest( + getNetworkFunction(), + getCommandCode(), + requestData, + TypeConverter.intToByte(sequenceNumber)); + } - @Override - public ResponseData getResponseData(IpmiMessage message) throws IPMIException, - NoSuchAlgorithmException, InvalidKeyException { - if (!isCommandResponse(message)) { - throw new IllegalArgumentException("This is not a response for Get SEL Entry command"); - } - if (!(message.getPayload() instanceof IpmiLanResponse)) { - throw new IllegalArgumentException("Invalid response payload"); - } - if (((IpmiLanResponse) message.getPayload()).getCompletionCode() != CompletionCode.Ok) { - throw new IPMIException(((IpmiLanResponse) message.getPayload()).getCompletionCode()); - } + @Override + public ResponseData getResponseData(IpmiMessage message) + throws IPMIException, + NoSuchAlgorithmException, + InvalidKeyException { + if (!isCommandResponse(message)) { + throw new IllegalArgumentException("This is not a response for Get SEL Entry command"); + } + if (!(message.getPayload() instanceof IpmiLanResponse)) { + throw new IllegalArgumentException("Invalid response payload"); + } + if (((IpmiLanResponse) message.getPayload()).getCompletionCode() != CompletionCode.Ok) { + throw new IPMIException(((IpmiLanResponse) message.getPayload()).getCompletionCode()); + } - return new SetSessionPrivilegeLevelResponseData(); - } + return new SetSessionPrivilegeLevelResponseData(); + } - private byte getRequestedPrivilegeLevelEncoded() { - switch (privilegeLevel) { - case MaximumAvailable: - return 0; - case Callback: - return TypeConverter.intToByte(0x1); - case User: - return TypeConverter.intToByte(0x2); - case Operator: - return TypeConverter.intToByte(0x3); - case Administrator: - return TypeConverter.intToByte(0x4); - default: - throw new IllegalArgumentException("Invalid privilege level"); - } - } + private byte getRequestedPrivilegeLevelEncoded() { + switch (privilegeLevel) { + case MaximumAvailable: + return 0; + case Callback: + return TypeConverter.intToByte(0x1); + case User: + return TypeConverter.intToByte(0x2); + case Operator: + return TypeConverter.intToByte(0x3); + case Administrator: + return TypeConverter.intToByte(0x4); + default: + throw new IllegalArgumentException("Invalid privilege level"); + } + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/commands/session/SetSessionPrivilegeLevelResponseData.java b/src/main/java/org/metricshub/ipmi/core/coding/commands/session/SetSessionPrivilegeLevelResponseData.java index 8bec244..d4f5c78 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/commands/session/SetSessionPrivilegeLevelResponseData.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/commands/session/SetSessionPrivilegeLevelResponseData.java @@ -25,5 +25,5 @@ import org.metricshub.ipmi.core.coding.commands.ResponseData; public class SetSessionPrivilegeLevelResponseData implements ResponseData { - + } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/payload/CompletionCode.java b/src/main/java/org/metricshub/ipmi/core/coding/payload/CompletionCode.java index eeae642..bec12d4 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/payload/CompletionCode.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/payload/CompletionCode.java @@ -22,440 +22,455 @@ * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ */ public enum CompletionCode { - /** - * Command completed normally. - */ - Ok(CompletionCode.OK), - /** - * Insufficient resources to create a session. - */ - InsufficientResources(CompletionCode.INSUFFICIENTRESOURCES), - /** - * Unauthorized role or privilege level requested. - */ - UnauthorizedRole(CompletionCode.UNAUTHORIZEDROLE), - /** - * Insufficient resources to create a session at the requested role. - */ - InsufficientResourcesForRole(CompletionCode.INSUFFICIENTRESOURCESFORROLE), - /** - * Invalid name length. - */ - InvalidNameLength(CompletionCode.INVALIDNAMELENGTH), - /** - * FRU device busy. The requested cannot be completed because the implementation of the logical FRU device is in a state where the FRU information is temporarily unavailable. This could be due to a condition such as a los s of arbitration if the FRU is implemented as a device on a shared bus. - */ - Frudevicebusy(CompletionCode.FRUDEVICEBUSY), - /** - * Unauthorized name. - */ - UnauthorizedName(CompletionCode.UNAUTHORIZEDNAME), - /** - * Invalid Session ID in request. - */ - InvalidSessionId(CompletionCode.INVALIDSESSIONID), - /** - * Invalid Session Handle in request. - */ - InvalidSessionHandle(CompletionCode.INVALIDSESSIONHANDLE), - /** - * GUID that BMC submitted in RAKP Message 2 was not accepted by remote console. - */ - UnauthorizedGuid(CompletionCode.UNAUTHORIZEDGUID), - /** - * Invalid integrity check value. - */ - InvalidIntegrityCheckValue(CompletionCode.INVALIDINTEGRITYCHECKVALUE), - /** - * Invalid confidentiality algorithm. - */ - InvalidConfidentialityAlgorithm(CompletionCode.INVALIDCONFIDENTIALITYALGORITHM), - /** - * No Cipher Suite match with proposed security algorithms. - */ - NoMatchingCipherSuite(CompletionCode.NOMATCHINGCIPHERSUITE), - /** - * Illegal or unrecognized parameter. - */ - IllegalOrUnrecognizedParameter(CompletionCode.ILLEGALORUNRECOGNIZEDPARAMETER), - /** - * Command could not be processed because command processing resources are temporarily unavailable. - */ - NodeBusy(CompletionCode.NODEBUSY), - /** - * Used to indicate an unrecognized or unsupported command. - */ - InvalidCommand(CompletionCode.INVALIDCOMMAND), - /** - * Command invalid for given LUN. - */ - InvalidLun(CompletionCode.INVALIDLUN), - /** - * Timeout while processing command. Response unavailable. - */ - Timeout(CompletionCode.TIMEOUT), - /** - * Out of space. Command could not be completed because of a lack of storage space required to execute the given command operation. - */ - OutOfSpace(CompletionCode.OUTOFSPACE), - /** - * Reservation Canceled or Invalid Reservation ID. - */ - ReservationCanceled(CompletionCode.RESERVATIONCANCELED), - /** - * Request data truncated. - */ - RequestTruncated(CompletionCode.REQUESTTRUNCATED), - /** - * Request data length invalid. - */ - InvalidRequestLength(CompletionCode.INVALIDREQUESTLENGTH), - /** - * Invalid session ID. - */ - InvalidId(CompletionCode.INVALIDID), - /** - * Request data field length limit exceeded. - */ - LengthLimitExceeded(CompletionCode.LENGTHLIMITEXCEEDED), - /** - * Parameter out of range. One or more parameters in the data field of the Request are out of range. This is different from {@link #InvalidData} (CCh) code in that it indicates that the erroneous field(s) has a contiguous range of possible values. - */ - ParameterOutOfRange(CompletionCode.PARAMETEROUTOFRANGE), - /** - * Cannot return number of requested data bytes. - */ - CannotRespond(CompletionCode.CANNOTRESPOND), - /** - * Requested Sensor, data, or record not present. - */ - DataNotPresent(CompletionCode.DATANOTPRESENT), - /** - * Invalid data field in Request. - */ - InvalidData(CompletionCode.INVALIDDATA), - /** - * Command illegal for specified sensor or record type. - */ - IllegalCommand(CompletionCode.ILLEGALCOMMAND), - /** - * Command response could not be provided. - */ - ResponseUnavailable(CompletionCode.RESPONSEUNAVAILABLE), - /** - * Cannot execute duplicated request. This completion code is for devices which cannot return the response that was returned for the original instance of the request. Such devices should provide separate commands that allow the completion status of the original request to be determined. An Event Receiver does not use this completion code, but returns the 00h completion code in the response to (valid) duplicated requests. - */ - DuplicatedRequest(CompletionCode.DUPLICATEDREQUEST), - /** - * Command response could not be provided. SDR Repository in update mode. - */ - SdrUpdating(CompletionCode.SDRUPDATING), - /** - * Command response could not be provided. Device in firmware update mode. - */ - FirmwareUpdating(CompletionCode.FIRMWAREUPDATING), - /** - * Command response could not be provided. BMC initialization or initialization agent in progress. - */ - InitializationInProgress(CompletionCode.INITIALIZATIONINPROGRESS), - /** - * Destination unavailable. Cannot deliver request to selected destination. E.g. this code can be returned if a request message is targeted to SMS, but receive message queue reception is disabled for the particular channel. - */ - DestinationUnavailable(CompletionCode.DESTINATIONUNAVAILABLE), - /** - * Cannot execute command due to insufficient privilege level or other security - based restriction (e.g. disabled for 'firmware firewall'). - */ - InsufficentPrivilege(CompletionCode.INSUFFICENTPRIVILEGE), - /** - * Cannot execute command. Command, or request parameter(s), not supported in present state. - */ - CommandNotSupported(CompletionCode.COMMANDNOTSUPPORTED), - /** - * Cannot execute command. Parameter is illegal because command sub-function has been disabled or is unavailable (e.g. disabled for 'firmware firewall'). - */ - IllegalParameter(CompletionCode.ILLEGALPARAMETER), - /** - * Unspecified error. - */ - UnspecifiedError(CompletionCode.UNSPECIFIEDERROR), - /** - * Invalid payload type. - */ - InvalidPayloadType(CompletionCode.INVALIDPAYLOADTYPE), - /** - * Invalid authentication algorithm. - */ - InvalidAuthenticationAlgorithm(CompletionCode.INVALIDAUTHENTICATIONALGORITHM), - /** - * Invalid integrity algorithm. - */ - InvalidIntegrityAlgorithm(CompletionCode.INVALIDINTEGRITYALGORITHM), - /** - * No matching authentication payload. - */ - NoMatchingAuthenticationPayload(CompletionCode.NOMATCHINGAUTHENTICATIONPAYLOAD), - /** - * No matching integrity payload. - */ - NoMatchingIntegrityPayload(CompletionCode.NOMATCHINGINTEGRITYPAYLOAD), - /** - * Inactive session ID. - */ - InactiveSessionID(CompletionCode.INACTIVESESSIONID), - /** - * Invalid role. - */ - InvalidRole(CompletionCode.INVALIDROLE), - ; - private static final int OK = 0; - private static final int INSUFFICIENTRESOURCES = 1; - private static final int UNAUTHORIZEDROLE = 10; - private static final int INSUFFICIENTRESOURCESFORROLE = 11; - private static final int INVALIDNAMELENGTH = 12; - private static final int FRUDEVICEBUSY = 129; - private static final int UNAUTHORIZEDNAME = 13; - private static final int INVALIDSESSIONID = 135; - private static final int INVALIDSESSIONHANDLE = 136; - private static final int UNAUTHORIZEDGUID = 14; - private static final int INVALIDINTEGRITYCHECKVALUE = 15; - private static final int INVALIDCONFIDENTIALITYALGORITHM = 16; - private static final int NOMATCHINGCIPHERSUITE = 17; - private static final int ILLEGALORUNRECOGNIZEDPARAMETER = 18; - private static final int NODEBUSY = 192; - private static final int INVALIDCOMMAND = 193; - private static final int INVALIDLUN = 194; - private static final int TIMEOUT = 195; - private static final int OUTOFSPACE = 196; - private static final int RESERVATIONCANCELED = 197; - private static final int REQUESTTRUNCATED = 198; - private static final int INVALIDREQUESTLENGTH = 199; - private static final int INVALIDID = 2; - private static final int LENGTHLIMITEXCEEDED = 200; - private static final int PARAMETEROUTOFRANGE = 201; - private static final int CANNOTRESPOND = 202; - private static final int DATANOTPRESENT = 203; - private static final int INVALIDDATA = 204; - private static final int ILLEGALCOMMAND = 205; - private static final int RESPONSEUNAVAILABLE = 206; - private static final int DUPLICATEDREQUEST = 207; - private static final int SDRUPDATING = 208; - private static final int FIRMWAREUPDATING = 209; - private static final int INITIALIZATIONINPROGRESS = 210; - private static final int DESTINATIONUNAVAILABLE = 211; - private static final int INSUFFICENTPRIVILEGE = 212; - private static final int COMMANDNOTSUPPORTED = 213; - private static final int ILLEGALPARAMETER = 214; - private static final int UNSPECIFIEDERROR = 255; - private static final int INVALIDPAYLOADTYPE = 3; - private static final int INVALIDAUTHENTICATIONALGORITHM = 4; - private static final int INVALIDINTEGRITYALGORITHM = 5; - private static final int NOMATCHINGAUTHENTICATIONPAYLOAD = 6; - private static final int NOMATCHINGINTEGRITYPAYLOAD = 7; - private static final int INACTIVESESSIONID = 8; - private static final int INVALIDROLE = 9; + /** + * Command completed normally. + */ + Ok(CompletionCode.OK), + /** + * Insufficient resources to create a session. + */ + InsufficientResources(CompletionCode.INSUFFICIENTRESOURCES), + /** + * Unauthorized role or privilege level requested. + */ + UnauthorizedRole(CompletionCode.UNAUTHORIZEDROLE), + /** + * Insufficient resources to create a session at the requested role. + */ + InsufficientResourcesForRole(CompletionCode.INSUFFICIENTRESOURCESFORROLE), + /** + * Invalid name length. + */ + InvalidNameLength(CompletionCode.INVALIDNAMELENGTH), + /** + * FRU device busy. The requested cannot be completed because the implementation of the logical FRU device is in a + * state where the FRU information is temporarily unavailable. This could be due to a condition such as a los s of + * arbitration if the FRU is implemented as a device on a shared bus. + */ + Frudevicebusy(CompletionCode.FRUDEVICEBUSY), + /** + * Unauthorized name. + */ + UnauthorizedName(CompletionCode.UNAUTHORIZEDNAME), + /** + * Invalid Session ID in request. + */ + InvalidSessionId(CompletionCode.INVALIDSESSIONID), + /** + * Invalid Session Handle in request. + */ + InvalidSessionHandle(CompletionCode.INVALIDSESSIONHANDLE), + /** + * GUID that BMC submitted in RAKP Message 2 was not accepted by remote console. + */ + UnauthorizedGuid(CompletionCode.UNAUTHORIZEDGUID), + /** + * Invalid integrity check value. + */ + InvalidIntegrityCheckValue(CompletionCode.INVALIDINTEGRITYCHECKVALUE), + /** + * Invalid confidentiality algorithm. + */ + InvalidConfidentialityAlgorithm(CompletionCode.INVALIDCONFIDENTIALITYALGORITHM), + /** + * No Cipher Suite match with proposed security algorithms. + */ + NoMatchingCipherSuite(CompletionCode.NOMATCHINGCIPHERSUITE), + /** + * Illegal or unrecognized parameter. + */ + IllegalOrUnrecognizedParameter(CompletionCode.ILLEGALORUNRECOGNIZEDPARAMETER), + /** + * Command could not be processed because command processing resources are temporarily unavailable. + */ + NodeBusy(CompletionCode.NODEBUSY), + /** + * Used to indicate an unrecognized or unsupported command. + */ + InvalidCommand(CompletionCode.INVALIDCOMMAND), + /** + * Command invalid for given LUN. + */ + InvalidLun(CompletionCode.INVALIDLUN), + /** + * Timeout while processing command. Response unavailable. + */ + Timeout(CompletionCode.TIMEOUT), + /** + * Out of space. Command could not be completed because of a lack of storage space required to execute the given + * command operation. + */ + OutOfSpace(CompletionCode.OUTOFSPACE), + /** + * Reservation Canceled or Invalid Reservation ID. + */ + ReservationCanceled(CompletionCode.RESERVATIONCANCELED), + /** + * Request data truncated. + */ + RequestTruncated(CompletionCode.REQUESTTRUNCATED), + /** + * Request data length invalid. + */ + InvalidRequestLength(CompletionCode.INVALIDREQUESTLENGTH), + /** + * Invalid session ID. + */ + InvalidId(CompletionCode.INVALIDID), + /** + * Request data field length limit exceeded. + */ + LengthLimitExceeded(CompletionCode.LENGTHLIMITEXCEEDED), + /** + * Parameter out of range. One or more parameters in the data field of the Request are out of range. This is different + * from {@link #InvalidData} (CCh) code in that it indicates that the erroneous field(s) has a contiguous range of + * possible values. + */ + ParameterOutOfRange(CompletionCode.PARAMETEROUTOFRANGE), + /** + * Cannot return number of requested data bytes. + */ + CannotRespond(CompletionCode.CANNOTRESPOND), + /** + * Requested Sensor, data, or record not present. + */ + DataNotPresent(CompletionCode.DATANOTPRESENT), + /** + * Invalid data field in Request. + */ + InvalidData(CompletionCode.INVALIDDATA), + /** + * Command illegal for specified sensor or record type. + */ + IllegalCommand(CompletionCode.ILLEGALCOMMAND), + /** + * Command response could not be provided. + */ + ResponseUnavailable(CompletionCode.RESPONSEUNAVAILABLE), + /** + * Cannot execute duplicated request. This completion code is for devices which cannot return the response that was + * returned for the original instance of the request. Such devices should provide separate commands that allow the + * completion status of the original request to be determined. An Event Receiver does not use this completion code, + * but returns the 00h completion code in the response to (valid) duplicated requests. + */ + DuplicatedRequest(CompletionCode.DUPLICATEDREQUEST), + /** + * Command response could not be provided. SDR Repository in update mode. + */ + SdrUpdating(CompletionCode.SDRUPDATING), + /** + * Command response could not be provided. Device in firmware update mode. + */ + FirmwareUpdating(CompletionCode.FIRMWAREUPDATING), + /** + * Command response could not be provided. BMC initialization or initialization agent in progress. + */ + InitializationInProgress(CompletionCode.INITIALIZATIONINPROGRESS), + /** + * Destination unavailable. Cannot deliver request to selected destination. E.g. this code can be returned if a + * request message is targeted to SMS, but receive message queue reception is disabled for the particular channel. + */ + DestinationUnavailable(CompletionCode.DESTINATIONUNAVAILABLE), + /** + * Cannot execute command due to insufficient privilege level or other security - based restriction (e.g. disabled for + * 'firmware firewall'). + */ + InsufficentPrivilege(CompletionCode.INSUFFICENTPRIVILEGE), + /** + * Cannot execute command. Command, or request parameter(s), not supported in present state. + */ + CommandNotSupported(CompletionCode.COMMANDNOTSUPPORTED), + /** + * Cannot execute command. Parameter is illegal because command sub-function has been disabled or is unavailable (e.g. + * disabled for 'firmware firewall'). + */ + IllegalParameter(CompletionCode.ILLEGALPARAMETER), + /** + * Unspecified error. + */ + UnspecifiedError(CompletionCode.UNSPECIFIEDERROR), + /** + * Invalid payload type. + */ + InvalidPayloadType(CompletionCode.INVALIDPAYLOADTYPE), + /** + * Invalid authentication algorithm. + */ + InvalidAuthenticationAlgorithm(CompletionCode.INVALIDAUTHENTICATIONALGORITHM), + /** + * Invalid integrity algorithm. + */ + InvalidIntegrityAlgorithm(CompletionCode.INVALIDINTEGRITYALGORITHM), + /** + * No matching authentication payload. + */ + NoMatchingAuthenticationPayload(CompletionCode.NOMATCHINGAUTHENTICATIONPAYLOAD), + /** + * No matching integrity payload. + */ + NoMatchingIntegrityPayload(CompletionCode.NOMATCHINGINTEGRITYPAYLOAD), + /** + * Inactive session ID. + */ + InactiveSessionID(CompletionCode.INACTIVESESSIONID), + /** + * Invalid role. + */ + InvalidRole(CompletionCode.INVALIDROLE), + ; - private int code; + private static final int OK = 0; + private static final int INSUFFICIENTRESOURCES = 1; + private static final int UNAUTHORIZEDROLE = 10; + private static final int INSUFFICIENTRESOURCESFORROLE = 11; + private static final int INVALIDNAMELENGTH = 12; + private static final int FRUDEVICEBUSY = 129; + private static final int UNAUTHORIZEDNAME = 13; + private static final int INVALIDSESSIONID = 135; + private static final int INVALIDSESSIONHANDLE = 136; + private static final int UNAUTHORIZEDGUID = 14; + private static final int INVALIDINTEGRITYCHECKVALUE = 15; + private static final int INVALIDCONFIDENTIALITYALGORITHM = 16; + private static final int NOMATCHINGCIPHERSUITE = 17; + private static final int ILLEGALORUNRECOGNIZEDPARAMETER = 18; + private static final int NODEBUSY = 192; + private static final int INVALIDCOMMAND = 193; + private static final int INVALIDLUN = 194; + private static final int TIMEOUT = 195; + private static final int OUTOFSPACE = 196; + private static final int RESERVATIONCANCELED = 197; + private static final int REQUESTTRUNCATED = 198; + private static final int INVALIDREQUESTLENGTH = 199; + private static final int INVALIDID = 2; + private static final int LENGTHLIMITEXCEEDED = 200; + private static final int PARAMETEROUTOFRANGE = 201; + private static final int CANNOTRESPOND = 202; + private static final int DATANOTPRESENT = 203; + private static final int INVALIDDATA = 204; + private static final int ILLEGALCOMMAND = 205; + private static final int RESPONSEUNAVAILABLE = 206; + private static final int DUPLICATEDREQUEST = 207; + private static final int SDRUPDATING = 208; + private static final int FIRMWAREUPDATING = 209; + private static final int INITIALIZATIONINPROGRESS = 210; + private static final int DESTINATIONUNAVAILABLE = 211; + private static final int INSUFFICENTPRIVILEGE = 212; + private static final int COMMANDNOTSUPPORTED = 213; + private static final int ILLEGALPARAMETER = 214; + private static final int UNSPECIFIEDERROR = 255; + private static final int INVALIDPAYLOADTYPE = 3; + private static final int INVALIDAUTHENTICATIONALGORITHM = 4; + private static final int INVALIDINTEGRITYALGORITHM = 5; + private static final int NOMATCHINGAUTHENTICATIONPAYLOAD = 6; + private static final int NOMATCHINGINTEGRITYPAYLOAD = 7; + private static final int INACTIVESESSIONID = 8; + private static final int INVALIDROLE = 9; - CompletionCode(int code) { - this.code = code; - } - public int getCode() { - return code; - } - public static CompletionCode parseInt(int value) { - switch(value) { - case OK: - return Ok; - case INSUFFICIENTRESOURCES: - return InsufficientResources; - case UNAUTHORIZEDROLE: - return UnauthorizedRole; - case INSUFFICIENTRESOURCESFORROLE: - return InsufficientResourcesForRole; - case INVALIDNAMELENGTH: - return InvalidNameLength; - case FRUDEVICEBUSY: - return Frudevicebusy; - case UNAUTHORIZEDNAME: - return UnauthorizedName; - case INVALIDSESSIONID: - return InvalidSessionId; - case INVALIDSESSIONHANDLE: - return InvalidSessionHandle; - case UNAUTHORIZEDGUID: - return UnauthorizedGuid; - case INVALIDINTEGRITYCHECKVALUE: - return InvalidIntegrityCheckValue; - case INVALIDCONFIDENTIALITYALGORITHM: - return InvalidConfidentialityAlgorithm; - case NOMATCHINGCIPHERSUITE: - return NoMatchingCipherSuite; - case ILLEGALORUNRECOGNIZEDPARAMETER: - return IllegalOrUnrecognizedParameter; - case NODEBUSY: - return NodeBusy; - case INVALIDCOMMAND: - return InvalidCommand; - case INVALIDLUN: - return InvalidLun; - case TIMEOUT: - return Timeout; - case OUTOFSPACE: - return OutOfSpace; - case RESERVATIONCANCELED: - return ReservationCanceled; - case REQUESTTRUNCATED: - return RequestTruncated; - case INVALIDREQUESTLENGTH: - return InvalidRequestLength; - case INVALIDID: - return InvalidId; - case LENGTHLIMITEXCEEDED: - return LengthLimitExceeded; - case PARAMETEROUTOFRANGE: - return ParameterOutOfRange; - case CANNOTRESPOND: - return CannotRespond; - case DATANOTPRESENT: - return DataNotPresent; - case INVALIDDATA: - return InvalidData; - case ILLEGALCOMMAND: - return IllegalCommand; - case RESPONSEUNAVAILABLE: - return ResponseUnavailable; - case DUPLICATEDREQUEST: - return DuplicatedRequest; - case SDRUPDATING: - return SdrUpdating; - case FIRMWAREUPDATING: - return FirmwareUpdating; - case INITIALIZATIONINPROGRESS: - return InitializationInProgress; - case DESTINATIONUNAVAILABLE: - return DestinationUnavailable; - case INSUFFICENTPRIVILEGE: - return InsufficentPrivilege; - case COMMANDNOTSUPPORTED: - return CommandNotSupported; - case ILLEGALPARAMETER: - return IllegalParameter; - case UNSPECIFIEDERROR: - return UnspecifiedError; - case INVALIDPAYLOADTYPE: - return InvalidPayloadType; - case INVALIDAUTHENTICATIONALGORITHM: - return InvalidAuthenticationAlgorithm; - case INVALIDINTEGRITYALGORITHM: - return InvalidIntegrityAlgorithm; - case NOMATCHINGAUTHENTICATIONPAYLOAD: - return NoMatchingAuthenticationPayload; - case NOMATCHINGINTEGRITYPAYLOAD: - return NoMatchingIntegrityPayload; - case INACTIVESESSIONID: - return InactiveSessionID; - case INVALIDROLE: - return InvalidRole; - default: - throw new IllegalArgumentException("Invalid value: " + value); - } -} - public String getMessage() { - switch(code) { - case OK: - return "Command completed normally."; - case INSUFFICIENTRESOURCES: - return "Insufficient resources to create a session."; - case UNAUTHORIZEDROLE: - return "Unauthorized role or privilege level requested."; - case INSUFFICIENTRESOURCESFORROLE: - return "Insufficient resources to create a session at the requested role."; - case INVALIDNAMELENGTH: - return "Invalid name length."; - case FRUDEVICEBUSY: - return "FRU device busy. The requested cannot be completed because the implementation of the logical FRU device is in a state where the FRU information is temporarily unavailable. This could be due to a condition such as a los s of arbitration if the FRU is implemented as a device on a shared bus."; - case UNAUTHORIZEDNAME: - return "Unauthorized name."; - case INVALIDSESSIONID: - return "Invalid Session ID in request."; - case INVALIDSESSIONHANDLE: - return "Invalid Session Handle in request."; - case UNAUTHORIZEDGUID: - return "GUID that BMC submitted in RAKP Message 2 was not accepted by remote console."; - case INVALIDINTEGRITYCHECKVALUE: - return "Invalid integrity check value."; - case INVALIDCONFIDENTIALITYALGORITHM: - return "Invalid confidentiality algorithm."; - case NOMATCHINGCIPHERSUITE: - return "No Cipher Suite match with proposed security algorithms."; - case ILLEGALORUNRECOGNIZEDPARAMETER: - return "Illegal or unrecognized parameter."; - case NODEBUSY: - return "Command could not be processed because command processing resources are temporarily unavailable."; - case INVALIDCOMMAND: - return "Used to indicate an unrecognized or unsupported command."; - case INVALIDLUN: - return "Command invalid for given LUN."; - case TIMEOUT: - return "Timeout while processing command. Response unavailable."; - case OUTOFSPACE: - return "Out of space. Command could not be completed because of a lack of storage space required to execute the given command operation."; - case RESERVATIONCANCELED: - return "Reservation Canceled or Invalid Reservation ID."; - case REQUESTTRUNCATED: - return "Request data truncated."; - case INVALIDREQUESTLENGTH: - return "Request data length invalid."; - case INVALIDID: - return "Invalid session ID."; - case LENGTHLIMITEXCEEDED: - return "Request data field length limit exceeded."; - case PARAMETEROUTOFRANGE: - return "Parameter out of range. One or more parameters in the data field of the Request are out of range. This is different from {@link #InvalidData} (CCh) code in that it indicates that the erroneous field(s) has a contiguous range of possible values."; - case CANNOTRESPOND: - return "Cannot return number of requested data bytes."; - case DATANOTPRESENT: - return "Requested Sensor, data, or record not present."; - case INVALIDDATA: - return "Invalid data field in Request."; - case ILLEGALCOMMAND: - return "Command illegal for specified sensor or record type."; - case RESPONSEUNAVAILABLE: - return "Command response could not be provided."; - case DUPLICATEDREQUEST: - return "Cannot execute duplicated request. This completion code is for devices which cannot return the response that was returned for the original instance of the request. Such devices should provide separate commands that allow the completion status of the original request to be determined. An Event Receiver does not use this completion code, but returns the 00h completion code in the response to (valid) duplicated requests."; - case SDRUPDATING: - return "Command response could not be provided. SDR Repository in update mode."; - case FIRMWAREUPDATING: - return "Command response could not be provided. Device in firmware update mode."; - case INITIALIZATIONINPROGRESS: - return "Command response could not be provided. BMC initialization or initialization agent in progress."; - case DESTINATIONUNAVAILABLE: - return "Destination unavailable. Cannot deliver request to selected destination. E.g. this code can be returned if a request message is targeted to SMS, but receive message queue reception is disabled for the particular channel."; - case INSUFFICENTPRIVILEGE: - return "Cannot execute command due to insufficient privilege level or other security - based restriction (e.g. disabled for 'firmware firewall')."; - case COMMANDNOTSUPPORTED: - return "Cannot execute command. Command, or request parameter(s), not supported in present state."; - case ILLEGALPARAMETER: - return "Cannot execute command. Parameter is illegal because command sub-function has been disabled or is unavailable (e.g. disabled for 'firmware firewall')."; - case UNSPECIFIEDERROR: - return "Unspecified error."; - case INVALIDPAYLOADTYPE: - return "Invalid payload type."; - case INVALIDAUTHENTICATIONALGORITHM: - return "Invalid authentication algorithm."; - case INVALIDINTEGRITYALGORITHM: - return "Invalid integrity algorithm."; - case NOMATCHINGAUTHENTICATIONPAYLOAD: - return "No matching authentication payload."; - case NOMATCHINGINTEGRITYPAYLOAD: - return "No matching integrity payload."; - case INACTIVESESSIONID: - return "Inactive session ID."; - case INVALIDROLE: - return "Invalid role."; - default: - throw new IllegalArgumentException("Invalid value: " + code); - } - } + private int code; + + CompletionCode(int code) { + this.code = code; + } + + public int getCode() { + return code; + } + + public static CompletionCode parseInt(int value) { + switch (value) { + case OK: + return Ok; + case INSUFFICIENTRESOURCES: + return InsufficientResources; + case UNAUTHORIZEDROLE: + return UnauthorizedRole; + case INSUFFICIENTRESOURCESFORROLE: + return InsufficientResourcesForRole; + case INVALIDNAMELENGTH: + return InvalidNameLength; + case FRUDEVICEBUSY: + return Frudevicebusy; + case UNAUTHORIZEDNAME: + return UnauthorizedName; + case INVALIDSESSIONID: + return InvalidSessionId; + case INVALIDSESSIONHANDLE: + return InvalidSessionHandle; + case UNAUTHORIZEDGUID: + return UnauthorizedGuid; + case INVALIDINTEGRITYCHECKVALUE: + return InvalidIntegrityCheckValue; + case INVALIDCONFIDENTIALITYALGORITHM: + return InvalidConfidentialityAlgorithm; + case NOMATCHINGCIPHERSUITE: + return NoMatchingCipherSuite; + case ILLEGALORUNRECOGNIZEDPARAMETER: + return IllegalOrUnrecognizedParameter; + case NODEBUSY: + return NodeBusy; + case INVALIDCOMMAND: + return InvalidCommand; + case INVALIDLUN: + return InvalidLun; + case TIMEOUT: + return Timeout; + case OUTOFSPACE: + return OutOfSpace; + case RESERVATIONCANCELED: + return ReservationCanceled; + case REQUESTTRUNCATED: + return RequestTruncated; + case INVALIDREQUESTLENGTH: + return InvalidRequestLength; + case INVALIDID: + return InvalidId; + case LENGTHLIMITEXCEEDED: + return LengthLimitExceeded; + case PARAMETEROUTOFRANGE: + return ParameterOutOfRange; + case CANNOTRESPOND: + return CannotRespond; + case DATANOTPRESENT: + return DataNotPresent; + case INVALIDDATA: + return InvalidData; + case ILLEGALCOMMAND: + return IllegalCommand; + case RESPONSEUNAVAILABLE: + return ResponseUnavailable; + case DUPLICATEDREQUEST: + return DuplicatedRequest; + case SDRUPDATING: + return SdrUpdating; + case FIRMWAREUPDATING: + return FirmwareUpdating; + case INITIALIZATIONINPROGRESS: + return InitializationInProgress; + case DESTINATIONUNAVAILABLE: + return DestinationUnavailable; + case INSUFFICENTPRIVILEGE: + return InsufficentPrivilege; + case COMMANDNOTSUPPORTED: + return CommandNotSupported; + case ILLEGALPARAMETER: + return IllegalParameter; + case UNSPECIFIEDERROR: + return UnspecifiedError; + case INVALIDPAYLOADTYPE: + return InvalidPayloadType; + case INVALIDAUTHENTICATIONALGORITHM: + return InvalidAuthenticationAlgorithm; + case INVALIDINTEGRITYALGORITHM: + return InvalidIntegrityAlgorithm; + case NOMATCHINGAUTHENTICATIONPAYLOAD: + return NoMatchingAuthenticationPayload; + case NOMATCHINGINTEGRITYPAYLOAD: + return NoMatchingIntegrityPayload; + case INACTIVESESSIONID: + return InactiveSessionID; + case INVALIDROLE: + return InvalidRole; + default: + throw new IllegalArgumentException("Invalid value: " + value); + } + } + + public String getMessage() { + switch (code) { + case OK: + return "Command completed normally."; + case INSUFFICIENTRESOURCES: + return "Insufficient resources to create a session."; + case UNAUTHORIZEDROLE: + return "Unauthorized role or privilege level requested."; + case INSUFFICIENTRESOURCESFORROLE: + return "Insufficient resources to create a session at the requested role."; + case INVALIDNAMELENGTH: + return "Invalid name length."; + case FRUDEVICEBUSY: + return "FRU device busy. The requested cannot be completed because the implementation of the logical FRU device is in a state where the FRU information is temporarily unavailable. This could be due to a condition such as a los s of arbitration if the FRU is implemented as a device on a shared bus."; + case UNAUTHORIZEDNAME: + return "Unauthorized name."; + case INVALIDSESSIONID: + return "Invalid Session ID in request."; + case INVALIDSESSIONHANDLE: + return "Invalid Session Handle in request."; + case UNAUTHORIZEDGUID: + return "GUID that BMC submitted in RAKP Message 2 was not accepted by remote console."; + case INVALIDINTEGRITYCHECKVALUE: + return "Invalid integrity check value."; + case INVALIDCONFIDENTIALITYALGORITHM: + return "Invalid confidentiality algorithm."; + case NOMATCHINGCIPHERSUITE: + return "No Cipher Suite match with proposed security algorithms."; + case ILLEGALORUNRECOGNIZEDPARAMETER: + return "Illegal or unrecognized parameter."; + case NODEBUSY: + return "Command could not be processed because command processing resources are temporarily unavailable."; + case INVALIDCOMMAND: + return "Used to indicate an unrecognized or unsupported command."; + case INVALIDLUN: + return "Command invalid for given LUN."; + case TIMEOUT: + return "Timeout while processing command. Response unavailable."; + case OUTOFSPACE: + return "Out of space. Command could not be completed because of a lack of storage space required to execute the given command operation."; + case RESERVATIONCANCELED: + return "Reservation Canceled or Invalid Reservation ID."; + case REQUESTTRUNCATED: + return "Request data truncated."; + case INVALIDREQUESTLENGTH: + return "Request data length invalid."; + case INVALIDID: + return "Invalid session ID."; + case LENGTHLIMITEXCEEDED: + return "Request data field length limit exceeded."; + case PARAMETEROUTOFRANGE: + return "Parameter out of range. One or more parameters in the data field of the Request are out of range. This is different from {@link #InvalidData} (CCh) code in that it indicates that the erroneous field(s) has a contiguous range of possible values."; + case CANNOTRESPOND: + return "Cannot return number of requested data bytes."; + case DATANOTPRESENT: + return "Requested Sensor, data, or record not present."; + case INVALIDDATA: + return "Invalid data field in Request."; + case ILLEGALCOMMAND: + return "Command illegal for specified sensor or record type."; + case RESPONSEUNAVAILABLE: + return "Command response could not be provided."; + case DUPLICATEDREQUEST: + return "Cannot execute duplicated request. This completion code is for devices which cannot return the response that was returned for the original instance of the request. Such devices should provide separate commands that allow the completion status of the original request to be determined. An Event Receiver does not use this completion code, but returns the 00h completion code in the response to (valid) duplicated requests."; + case SDRUPDATING: + return "Command response could not be provided. SDR Repository in update mode."; + case FIRMWAREUPDATING: + return "Command response could not be provided. Device in firmware update mode."; + case INITIALIZATIONINPROGRESS: + return "Command response could not be provided. BMC initialization or initialization agent in progress."; + case DESTINATIONUNAVAILABLE: + return "Destination unavailable. Cannot deliver request to selected destination. E.g. this code can be returned if a request message is targeted to SMS, but receive message queue reception is disabled for the particular channel."; + case INSUFFICENTPRIVILEGE: + return "Cannot execute command due to insufficient privilege level or other security - based restriction (e.g. disabled for 'firmware firewall')."; + case COMMANDNOTSUPPORTED: + return "Cannot execute command. Command, or request parameter(s), not supported in present state."; + case ILLEGALPARAMETER: + return "Cannot execute command. Parameter is illegal because command sub-function has been disabled or is unavailable (e.g. disabled for 'firmware firewall')."; + case UNSPECIFIEDERROR: + return "Unspecified error."; + case INVALIDPAYLOADTYPE: + return "Invalid payload type."; + case INVALIDAUTHENTICATIONALGORITHM: + return "Invalid authentication algorithm."; + case INVALIDINTEGRITYALGORITHM: + return "Invalid integrity algorithm."; + case NOMATCHINGAUTHENTICATIONPAYLOAD: + return "No matching authentication payload."; + case NOMATCHINGINTEGRITYPAYLOAD: + return "No matching integrity payload."; + case INACTIVESESSIONID: + return "Inactive session ID."; + case INVALIDROLE: + return "Invalid role."; + default: + throw new IllegalArgumentException("Invalid value: " + code); + } + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/payload/IpmiPayload.java b/src/main/java/org/metricshub/ipmi/core/coding/payload/IpmiPayload.java index b9c1fce..387a74f 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/payload/IpmiPayload.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/payload/IpmiPayload.java @@ -31,59 +31,58 @@ */ public abstract class IpmiPayload { - private byte[] data; + private byte[] data; - private byte[] encryptedPayload; + private byte[] encryptedPayload; - public void setData(byte[] data) { - this.data = data; - } + public void setData(byte[] data) { + this.data = data; + } - public byte[] getData() { - return data; - } + public byte[] getData() { + return data; + } - /** - * Returns encrypted payload encoded in byte array. - * - * Migth be null if payload was not yet encrypted. - * - * @see #encryptPayload(ConfidentialityAlgorithm) - */ - public byte[] getEncryptedPayload() { - return encryptedPayload; - } + /** + * Returns encrypted payload encoded in byte array. + * Migth be null if payload was not yet encrypted. + * + * @see #encryptPayload(ConfidentialityAlgorithm) + */ + public byte[] getEncryptedPayload() { + return encryptedPayload; + } - /** - * Returns unencrypted payload encoded in byte array (owner is responsible - * for encryption). - * - * @return payload - */ - public abstract byte[] getPayloadData(); + /** + * Returns unencrypted payload encoded in byte array (owner is responsible + * for encryption). + * + * @return payload + */ + public abstract byte[] getPayloadData(); - /** - * Returns encoded but UNENCRYPTED payload length. - */ - public abstract int getPayloadLength(); + /** + * Returns encoded but UNENCRYPTED payload length. + */ + public abstract int getPayloadLength(); - /** - * Returns IPMI command encapsulated in IPMI Payload. - */ - public abstract byte[] getIpmiCommandData(); + /** + * Returns IPMI command encapsulated in IPMI Payload. + */ + public abstract byte[] getIpmiCommandData(); - /** - * Encrypts {@link #getPayloadData()}. - * - * @param confidentialityAlgorithm - * {@link ConfidentialityAlgorithm} to be used to encrypt payload - * data. - * @throws InvalidKeyException - * - when confidentiality algorithm fails. - * @see IpmiPayload#getEncryptedPayload() - */ - public void encryptPayload(ConfidentialityAlgorithm confidentialityAlgorithm) - throws InvalidKeyException { - encryptedPayload = confidentialityAlgorithm.encrypt(getPayloadData()); - } + /** + * Encrypts {@link #getPayloadData()}. + * + * @param confidentialityAlgorithm + * {@link ConfidentialityAlgorithm} to be used to encrypt payload + * data. + * @throws InvalidKeyException + * - when confidentiality algorithm fails. + * @see IpmiPayload#getEncryptedPayload() + */ + public void encryptPayload(ConfidentialityAlgorithm confidentialityAlgorithm) + throws InvalidKeyException { + encryptedPayload = confidentialityAlgorithm.encrypt(getPayloadData()); + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/payload/PlainMessage.java b/src/main/java/org/metricshub/ipmi/core/coding/payload/PlainMessage.java index 3e3292b..10cf933 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/payload/PlainMessage.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/payload/PlainMessage.java @@ -29,28 +29,29 @@ */ public class PlainMessage extends IpmiPayload { - @Override - public byte[] getPayloadData() { - return getData(); - } + @Override + public byte[] getPayloadData() { + return getData(); + } - @Override - public int getPayloadLength() { - return getData().length; - } + @Override + public int getPayloadLength() { + return getData().length; + } - /** - * Creates IPMI payload. - * @param data - * - byte array containing payload for IPMI message. - */ - public PlainMessage(byte[] data) { - setData(data); - } + /** + * Creates IPMI payload. + * + * @param data + * - byte array containing payload for IPMI message. + */ + public PlainMessage(byte[] data) { + setData(data); + } - @Override - public byte[] getIpmiCommandData() { - return getData(); - } + @Override + public byte[] getIpmiCommandData() { + return getData(); + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/payload/lan/IPMIException.java b/src/main/java/org/metricshub/ipmi/core/coding/payload/lan/IPMIException.java index b4758bf..fcbb95b 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/payload/lan/IPMIException.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/payload/lan/IPMIException.java @@ -26,20 +26,20 @@ public class IPMIException extends Exception { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; - private final CompletionCode completionCode; + private final CompletionCode completionCode; - public IPMIException(CompletionCode completionCode) { - this.completionCode = completionCode; - } + public IPMIException(CompletionCode completionCode) { + this.completionCode = completionCode; + } - public CompletionCode getCompletionCode() { - return completionCode; - } + public CompletionCode getCompletionCode() { + return completionCode; + } - @Override - public String getMessage() { - return completionCode.getMessage(); - } + @Override + public String getMessage() { + return completionCode.getMessage(); + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/payload/lan/IpmiLanConstants.java b/src/main/java/org/metricshub/ipmi/core/coding/payload/lan/IpmiLanConstants.java index 583068c..c0947b7 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/payload/lan/IpmiLanConstants.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/payload/lan/IpmiLanConstants.java @@ -27,22 +27,22 @@ /** * Set of constants. * Byte constants are encoded as pseudo unsigned bytes. - * IpmiLanConstants doesn't use {@link TypeConverter} because + * IpmiLanConstants doesn't use {@link TypeConverter} because * fields need to be runtime constants. + * * @see TypeConverter#byteToInt(byte) * @see TypeConverter#intToByte(int) */ public final class IpmiLanConstants { - /** - * The address of the BMC. - */ - public static final byte BMC_ADDRESS = 0x20; - - /** - * The address of the remote console. - */ - public static final byte REMOTE_CONSOLE_ADDRESS = (byte) (0x81 - 256); - - private IpmiLanConstants() { - } + /** + * The address of the BMC. + */ + public static final byte BMC_ADDRESS = 0x20; + + /** + * The address of the remote console. + */ + public static final byte REMOTE_CONSOLE_ADDRESS = (byte) (0x81 - 256); + + private IpmiLanConstants() {} } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/payload/lan/IpmiLanMessage.java b/src/main/java/org/metricshub/ipmi/core/coding/payload/lan/IpmiLanMessage.java index 0b39062..cc5fa14 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/payload/lan/IpmiLanMessage.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/payload/lan/IpmiLanMessage.java @@ -29,109 +29,127 @@ * A wrapper class for IPMI LAN message */ public abstract class IpmiLanMessage extends IpmiPayload { - public static final int MIN_SEQUENCE_NUMBER = 1; - public static final int MAX_SEQUENCE_NUMBER = 63; - - private byte responderAddress; - - protected byte networkFunction; - - private byte responderLogicalUnitNumber; - - private byte requesterAddress; - - private byte requesterLogicalUnitNumber; - - private byte sequenceNumber; - - private byte command; - - public void setResponderAddress(byte responderAddress) { - this.responderAddress = responderAddress; - } - - public byte getResponderAddress() { - return responderAddress; - } - - public void setNetworkFunction(NetworkFunction networkFunction) { - this.networkFunction = TypeConverter.intToByte(networkFunction.getCode()); - } - - public NetworkFunction getNetworkFunction() { - return NetworkFunction.parseInt(TypeConverter.byteToInt(networkFunction)); - } - - public void setResponderLogicalUnitNumber(byte responderLogicalUnitNumber) { - this.responderLogicalUnitNumber = responderLogicalUnitNumber; - } - - public byte getResponderLogicalUnitNumber() { - return responderLogicalUnitNumber; - } - - public void setSequenceNumber(byte sequenceAddress) { - this.sequenceNumber = sequenceAddress; - } - - public byte getSequenceNumber() { - return sequenceNumber; - } - - public void setRequesterAddress(byte requesterAddress) { - this.requesterAddress = requesterAddress; - } - - public byte getRequesterAddress() { - return requesterAddress; - } - - public void setRequesterLogicalUnitNumber(byte requesterLogicalUnitNumber) { - this.requesterLogicalUnitNumber = requesterLogicalUnitNumber; - } - - public byte getRequesterLogicalUnitNumber() { - return requesterLogicalUnitNumber; - } - - public void setCommand(byte command) { - this.command = command; - } - - public byte getCommand() { - return command; - } - - /** - * Gets expected size of LAN message in bytes. - */ - @Override - public abstract int getPayloadLength(); - - /** - * Converts IpmiLanMessage to byte array. - */ - @Override - public abstract byte[] getPayloadData(); - - protected byte getChecksum1(byte[] message) { - int checksum = 0; - for(int i = 0; i < 2; ++i) { - checksum = (checksum + TypeConverter.byteToInt(message[i])) % 256; - } - return (byte) -TypeConverter.intToByte(checksum); - } - - protected byte getChecksum2(byte[] message) { - int checksum = 0; - for(int i = 3; i < message.length-1; ++i) { - checksum = ((checksum + TypeConverter.byteToInt(message[i])) % 256); - } - return (byte)-TypeConverter.intToByte(checksum); - } - - @Override - public byte[] getIpmiCommandData() { - return getData(); - } + public static final int MIN_SEQUENCE_NUMBER = 1; + public static final int MAX_SEQUENCE_NUMBER = 63; + + private byte responderAddress; + + private byte networkFunction; + + private byte responderLogicalUnitNumber; + + private byte requesterAddress; + + private byte requesterLogicalUnitNumber; + + private byte sequenceNumber; + + private byte command; + + public void setResponderAddress(byte responderAddress) { + this.responderAddress = responderAddress; + } + + public byte getResponderAddress() { + return responderAddress; + } + + public void setNetworkFunction(NetworkFunction networkFunction) { + this.networkFunction = TypeConverter.intToByte(networkFunction.getCode()); + } + + public NetworkFunction getNetworkFunction() { + return NetworkFunction.parseInt(TypeConverter.byteToInt(networkFunction)); + } + + /** + * Sets the raw network function code (6 bits), which may not map to a known {@link NetworkFunction}. + * + * @param networkFunctionCode the network function code + */ + protected void setNetworkFunctionCode(byte networkFunctionCode) { + this.networkFunction = networkFunctionCode; + } + + /** + * Returns the raw network function code (6 bits). + * + * @return the network function code + */ + protected byte getNetworkFunctionCode() { + return networkFunction; + } + + public void setResponderLogicalUnitNumber(byte responderLogicalUnitNumber) { + this.responderLogicalUnitNumber = responderLogicalUnitNumber; + } + + public byte getResponderLogicalUnitNumber() { + return responderLogicalUnitNumber; + } + + public void setSequenceNumber(byte sequenceAddress) { + this.sequenceNumber = sequenceAddress; + } + + public byte getSequenceNumber() { + return sequenceNumber; + } + + public void setRequesterAddress(byte requesterAddress) { + this.requesterAddress = requesterAddress; + } + + public byte getRequesterAddress() { + return requesterAddress; + } + + public void setRequesterLogicalUnitNumber(byte requesterLogicalUnitNumber) { + this.requesterLogicalUnitNumber = requesterLogicalUnitNumber; + } + + public byte getRequesterLogicalUnitNumber() { + return requesterLogicalUnitNumber; + } + + public void setCommand(byte command) { + this.command = command; + } + + public byte getCommand() { + return command; + } + + /** + * Gets expected size of LAN message in bytes. + */ + @Override + public abstract int getPayloadLength(); + + /** + * Converts IpmiLanMessage to byte array. + */ + @Override + public abstract byte[] getPayloadData(); + + protected byte getChecksum1(byte[] message) { + int checksum = 0; + for (int i = 0; i < 2; ++i) { + checksum = (checksum + TypeConverter.byteToInt(message[i])) % 256; + } + return (byte) -TypeConverter.intToByte(checksum); + } + + protected byte getChecksum2(byte[] message) { + int checksum = 0; + for (int i = 3; i < message.length - 1; ++i) { + checksum = ((checksum + TypeConverter.byteToInt(message[i])) % 256); + } + return (byte) -TypeConverter.intToByte(checksum); + } + + @Override + public byte[] getIpmiCommandData() { + return getData(); + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/payload/lan/IpmiLanRequest.java b/src/main/java/org/metricshub/ipmi/core/coding/payload/lan/IpmiLanRequest.java index 582e23d..d8f9592 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/payload/lan/IpmiLanRequest.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/payload/lan/IpmiLanRequest.java @@ -29,84 +29,91 @@ * A wrapper class for IPMB LAN message */ public class IpmiLanRequest extends IpmiLanMessage { - /** - * Builds IpmiLanRequest addressed at LUN 0. - * - * @param networkFunction - * - command specific {@link NetworkFunction} - * @param commandCode - * - command specific {@link CommandCodes} - * @param requestData - * - command specific payload - * @param sequenceNumber - * - used to match request and response - must be in range [0-63] - */ - public IpmiLanRequest(NetworkFunction networkFunction, byte commandCode, - byte[] requestData, byte sequenceNumber) { - this(networkFunction, commandCode, requestData, sequenceNumber, - TypeConverter.intToByte(0)); - } + /** + * Builds IpmiLanRequest addressed at LUN 0. + * + * @param networkFunction + * - command specific {@link NetworkFunction} + * @param commandCode + * - command specific {@link CommandCodes} + * @param requestData + * - command specific payload + * @param sequenceNumber + * - used to match request and response - must be in range [0-63] + */ + public IpmiLanRequest(NetworkFunction networkFunction, byte commandCode, + byte[] requestData, byte sequenceNumber) { + this( + networkFunction, + commandCode, + requestData, + sequenceNumber, + TypeConverter.intToByte(0)); + } - /** - * Builds IpmiLanRequest. - * - * @param networkFunction - * - command specific {@link NetworkFunction} - * @param commandCode - * - command specific {@link CommandCodes} - * @param requestData - * - command specific payload - * @param sequenceNumber - * - used to match request and response - must be in range [0-63] - * @param lun - * - target Logical Unit Number. Must be in range [0-3]. - */ - public IpmiLanRequest(NetworkFunction networkFunction, byte commandCode, - byte[] requestData, byte sequenceNumber, byte lun) { - if (lun < 0 || lun > 3) { - throw new IllegalArgumentException("Invalid LUN"); - } - setResponderAddress(IpmiLanConstants.BMC_ADDRESS); - setNetworkFunction(networkFunction); - setResponderLogicalUnitNumber(TypeConverter.intToByte(lun)); - setRequesterAddress(IpmiLanConstants.REMOTE_CONSOLE_ADDRESS); - setRequesterLogicalUnitNumber(TypeConverter.intToByte(0)); - setSequenceNumber(sequenceNumber); - setData(requestData); - setCommand(commandCode); - } + /** + * Builds IpmiLanRequest. + * + * @param networkFunction + * - command specific {@link NetworkFunction} + * @param commandCode + * - command specific {@link CommandCodes} + * @param requestData + * - command specific payload + * @param sequenceNumber + * - used to match request and response - must be in range [0-63] + * @param lun + * - target Logical Unit Number. Must be in range [0-3]. + */ + public IpmiLanRequest(NetworkFunction networkFunction, byte commandCode, + byte[] requestData, byte sequenceNumber, byte lun) { + if (lun < 0 || lun > 3) { + throw new IllegalArgumentException("Invalid LUN"); + } + setResponderAddress(IpmiLanConstants.BMC_ADDRESS); + setNetworkFunction(networkFunction); + setResponderLogicalUnitNumber(TypeConverter.intToByte(lun)); + setRequesterAddress(IpmiLanConstants.REMOTE_CONSOLE_ADDRESS); + setRequesterLogicalUnitNumber(TypeConverter.intToByte(0)); + setSequenceNumber(sequenceNumber); + setData(requestData); + setCommand(commandCode); + } - @Override - public int getPayloadLength() { - int length = 7; + @Override + public int getPayloadLength() { + int length = 7; - if (getData() != null) { - length += getData().length; - } - return length; - } + if (getData() != null) { + length += getData().length; + } + return length; + } - @Override - public byte[] getPayloadData() { - byte[] message = new byte[getPayloadLength()]; + @Override + public byte[] getPayloadData() { + byte[] message = new byte[getPayloadLength()]; - message[0] = getResponderAddress(); - message[1] = TypeConverter.intToByte((networkFunction << 2) - | getResponderLogicalUnitNumber()); - message[2] = getChecksum1(message); - message[3] = getRequesterAddress(); - message[4] = TypeConverter - .intToByte(((getSequenceNumber() & 0x3f) << 2) - | getResponderLogicalUnitNumber()); - message[5] = getCommand(); + message[0] = getResponderAddress(); + message[1] = TypeConverter + .intToByte( + (getNetworkFunctionCode() << 2) + | getResponderLogicalUnitNumber()); + message[2] = getChecksum1(message); + message[3] = getRequesterAddress(); + message[4] = TypeConverter + .intToByte( + ((getSequenceNumber() & 0x3f) << 2) + | getResponderLogicalUnitNumber()); + message[5] = getCommand(); - if (getData() != null) { - System.arraycopy(getData(), 0, message, 6, getData().length); - } + if (getData() != null) { + System.arraycopy(getData(), 0, message, 6, getData().length); + } - message[message.length - 1] = getChecksum2(message); + message[message.length - 1] = getChecksum2(message); - return message; - } + return message; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/payload/lan/IpmiLanResponse.java b/src/main/java/org/metricshub/ipmi/core/coding/payload/lan/IpmiLanResponse.java index 1ba47b6..a222e09 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/payload/lan/IpmiLanResponse.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/payload/lan/IpmiLanResponse.java @@ -30,70 +30,88 @@ */ public class IpmiLanResponse extends IpmiLanMessage { - private CompletionCode completionCode; + private CompletionCode completionCode; - public void setCompletionCode(byte completionCode) { - this.completionCode = CompletionCode.parseInt(TypeConverter - .byteToInt(completionCode)); - } + public void setCompletionCode(byte completionCode) { + this.completionCode = CompletionCode + .parseInt( + TypeConverter + .byteToInt(completionCode)); + } - public CompletionCode getCompletionCode() { - return completionCode; - } + public CompletionCode getCompletionCode() { + return completionCode; + } - /** - * Builds IPMI LAN response message from byte array. - * - * @param rawData - * @throws IllegalArgumentException - * when checksum is corrupted - */ - public IpmiLanResponse(byte[] rawData) { - setRequesterAddress(rawData[0]); - networkFunction = TypeConverter.intToByte((TypeConverter - .byteToInt(rawData[1]) & 0xfC) >> 2); - setRequesterLogicalUnitNumber(TypeConverter.intToByte(TypeConverter - .byteToInt(rawData[1]) & 0x03)); - if (rawData[2] != getChecksum1(rawData)) { - throw new IllegalArgumentException("Checksum 1 failed"); - } - setResponderAddress(rawData[3]); - setSequenceNumber(TypeConverter.intToByte((TypeConverter - .byteToInt(rawData[4]) & 0xfC) >> 2)); - setResponderLogicalUnitNumber(TypeConverter.intToByte(TypeConverter - .byteToInt(rawData[4]) & 0x03)); - setCommand(rawData[5]); - setCompletionCode(rawData[6]); + /** + * Builds IPMI LAN response message from byte array. + * + * @param rawData + * @throws IllegalArgumentException + * when checksum is corrupted + */ + public IpmiLanResponse(byte[] rawData) { + setRequesterAddress(rawData[0]); + setNetworkFunctionCode( + TypeConverter + .intToByte( + (TypeConverter + .byteToInt(rawData[1]) + & 0xfC) >> 2)); + setRequesterLogicalUnitNumber( + TypeConverter + .intToByte( + TypeConverter + .byteToInt(rawData[1]) + & 0x03)); + if (rawData[2] != getChecksum1(rawData)) { + throw new IllegalArgumentException("Checksum 1 failed"); + } + setResponderAddress(rawData[3]); + setSequenceNumber( + TypeConverter + .intToByte( + (TypeConverter + .byteToInt(rawData[4]) + & 0xfC) >> 2)); + setResponderLogicalUnitNumber( + TypeConverter + .intToByte( + TypeConverter + .byteToInt(rawData[4]) + & 0x03)); + setCommand(rawData[5]); + setCompletionCode(rawData[6]); - if (rawData.length > 8) { - byte[] data = new byte[rawData.length - 8]; + if (rawData.length > 8) { + byte[] data = new byte[rawData.length - 8]; - System.arraycopy(rawData, 7, data, 0, rawData.length - 8); + System.arraycopy(rawData, 7, data, 0, rawData.length - 8); - setData(data); - } + setData(data); + } - if (rawData[rawData.length - 1] != getChecksum2(rawData)) { - throw new IllegalArgumentException("Checksum 2 failed"); - } - } + if (rawData[rawData.length - 1] != getChecksum2(rawData)) { + throw new IllegalArgumentException("Checksum 2 failed"); + } + } - @Override - public int getPayloadLength() { - int length = 8; - if (getData() != null) { - length += getData().length; - } - return length; - } + @Override + public int getPayloadLength() { + int length = 8; + if (getData() != null) { + length += getData().length; + } + return length; + } - /** - * @deprecated LAN response does not hve payload data - */ - @Override - @Deprecated - public byte[] getPayloadData() { - return null; - } + /** + * @deprecated LAN response does not hve payload data + */ + @Override + @Deprecated + public byte[] getPayloadData() { + return null; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/payload/lan/NetworkFunction.java b/src/main/java/org/metricshub/ipmi/core/coding/payload/lan/NetworkFunction.java index eeafccd..996645b 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/payload/lan/NetworkFunction.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/payload/lan/NetworkFunction.java @@ -26,75 +26,85 @@ * IPMB network functions */ public enum NetworkFunction { - ChassisRequest(NetworkFunction.CHASSISREQUEST), ChassisResponse( - NetworkFunction.CHASSISRESPONSE), StorageRequest( - NetworkFunction.STORAGEREQUEST), StorageResponse( - NetworkFunction.STORAGERESPONSE), BridgeRequest( - NetworkFunction.BRIDGEREQUEST), BridgeResponse( - NetworkFunction.BRIDGERESPONSE), - /** - * Sensor/Event Request - */ - SensorRequest(NetworkFunction.SENSORREQUEST), - /** - * Sensor/Event Response - */ - SensorResponse(NetworkFunction.SENSORRESPONSE), ApplicationRequest( - NetworkFunction.APPLICATIONREQUEST), ApplicationResponse( - NetworkFunction.APPLICATIONRESPONSE), FirmwareRequest( - NetworkFunction.FIRMWAREREQUEST), FirmwareResponse( - NetworkFunction.FIRMWARERESPONSE), ; - private static final int CHASSISREQUEST = 0; - private static final int CHASSISRESPONSE = 1; - private static final int STORAGEREQUEST = 10; - private static final int STORAGERESPONSE = 11; - private static final int BRIDGEREQUEST = 2; - private static final int BRIDGERESPONSE = 3; - private static final int SENSORREQUEST = 4; - private static final int SENSORRESPONSE = 5; - private static final int APPLICATIONREQUEST = 6; - private static final int APPLICATIONRESPONSE = 7; - private static final int FIRMWAREREQUEST = 8; - private static final int FIRMWARERESPONSE = 9; + ChassisRequest(NetworkFunction.CHASSISREQUEST), + ChassisResponse( + NetworkFunction.CHASSISRESPONSE), + StorageRequest( + NetworkFunction.STORAGEREQUEST), + StorageResponse( + NetworkFunction.STORAGERESPONSE), + BridgeRequest( + NetworkFunction.BRIDGEREQUEST), + BridgeResponse( + NetworkFunction.BRIDGERESPONSE), + /** + * Sensor/Event Request + */ + SensorRequest(NetworkFunction.SENSORREQUEST), + /** + * Sensor/Event Response + */ + SensorResponse(NetworkFunction.SENSORRESPONSE), + ApplicationRequest( + NetworkFunction.APPLICATIONREQUEST), + ApplicationResponse( + NetworkFunction.APPLICATIONRESPONSE), + FirmwareRequest( + NetworkFunction.FIRMWAREREQUEST), + FirmwareResponse( + NetworkFunction.FIRMWARERESPONSE),; - private int code; + private static final int CHASSISREQUEST = 0; + private static final int CHASSISRESPONSE = 1; + private static final int STORAGEREQUEST = 10; + private static final int STORAGERESPONSE = 11; + private static final int BRIDGEREQUEST = 2; + private static final int BRIDGERESPONSE = 3; + private static final int SENSORREQUEST = 4; + private static final int SENSORRESPONSE = 5; + private static final int APPLICATIONREQUEST = 6; + private static final int APPLICATIONRESPONSE = 7; + private static final int FIRMWAREREQUEST = 8; + private static final int FIRMWARERESPONSE = 9; - NetworkFunction(int code) { - this.code = code; - } + private int code; - public int getCode() { - return code; - } + NetworkFunction(int code) { + this.code = code; + } - public static NetworkFunction parseInt(int value) { - switch (value) { - case CHASSISREQUEST: - return ChassisRequest; - case CHASSISRESPONSE: - return ChassisResponse; - case STORAGEREQUEST: - return StorageRequest; - case STORAGERESPONSE: - return StorageResponse; - case BRIDGEREQUEST: - return BridgeRequest; - case BRIDGERESPONSE: - return BridgeResponse; - case SENSORREQUEST: - return SensorRequest; - case SENSORRESPONSE: - return SensorResponse; - case APPLICATIONREQUEST: - return ApplicationRequest; - case APPLICATIONRESPONSE: - return ApplicationResponse; - case FIRMWAREREQUEST: - return FirmwareRequest; - case FIRMWARERESPONSE: - return FirmwareResponse; - default: - throw new IllegalArgumentException("Invalid value: " + value); - } - } + public int getCode() { + return code; + } + + public static NetworkFunction parseInt(int value) { + switch (value) { + case CHASSISREQUEST: + return ChassisRequest; + case CHASSISRESPONSE: + return ChassisResponse; + case STORAGEREQUEST: + return StorageRequest; + case STORAGERESPONSE: + return StorageResponse; + case BRIDGEREQUEST: + return BridgeRequest; + case BRIDGERESPONSE: + return BridgeResponse; + case SENSORREQUEST: + return SensorRequest; + case SENSORRESPONSE: + return SensorResponse; + case APPLICATIONREQUEST: + return ApplicationRequest; + case APPLICATIONRESPONSE: + return ApplicationResponse; + case FIRMWAREREQUEST: + return FirmwareRequest; + case FIRMWARERESPONSE: + return FirmwareResponse; + default: + throw new IllegalArgumentException("Invalid value: " + value); + } + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/payload/package-info.java b/src/main/java/org/metricshub/ipmi/core/coding/payload/package-info.java index d592242..f6e33f4 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/payload/package-info.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/payload/package-info.java @@ -1,6 +1,7 @@ /** - * The IPMI payload encoders and decoders. - * To implement custom payload encoder/decoder, extend {@link org.metricshub.ipmi.core.coding.payload.IpmiPayload} class. + * The IPMI payload encoders and decoders. + * To implement custom payload encoder/decoder, extend {@link org.metricshub.ipmi.core.coding.payload.IpmiPayload} + * class. */ package org.metricshub.ipmi.core.coding.payload; /*- diff --git a/src/main/java/org/metricshub/ipmi/core/coding/payload/sol/SolAckState.java b/src/main/java/org/metricshub/ipmi/core/coding/payload/sol/SolAckState.java index 8aa7f94..c2571df 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/payload/sol/SolAckState.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/payload/sol/SolAckState.java @@ -29,43 +29,43 @@ */ public enum SolAckState { - /** - * Message was acknowledged. - */ - ACK, + /** + * Message was acknowledged. + */ + ACK, - /** - * Message was not acknowledged. - */ - NACK; + /** + * Message was not acknowledged. + */ + NACK; - private static final int ACK_BIT_NUMBER = 6; + private static final int ACK_BIT_NUMBER = 6; - /** - * Extracts {@link SolAckState} from given byte. - * - * @param value - * byte with encoded {@link SolAckState} - * @return {@link SolAckState} extracted from byte - */ - public static SolAckState extractFromByte(byte value) { - return TypeConverter.isBitSetOnPosition(ACK_BIT_NUMBER, value) ? SolAckState.NACK : SolAckState.ACK; - } + /** + * Extracts {@link SolAckState} from given byte. + * + * @param value + * byte with encoded {@link SolAckState} + * @return {@link SolAckState} extracted from byte + */ + public static SolAckState extractFromByte(byte value) { + return TypeConverter.isBitSetOnPosition(ACK_BIT_NUMBER, value) ? SolAckState.NACK : SolAckState.ACK; + } - /** - * Encode information about this {@link SolAckState} in given byte, returning updated byte. - * - * @param value - * current byte value - * @return updated byte value - */ - public byte encodeInByte(final byte value) { - byte updatedValue = value; + /** + * Encode information about this {@link SolAckState} in given byte, returning updated byte. + * + * @param value + * current byte value + * @return updated byte value + */ + public byte encodeInByte(final byte value) { + byte updatedValue = value; - if (this == SolAckState.NACK) { - updatedValue = TypeConverter.setBitOnPosition(ACK_BIT_NUMBER, value); - } + if (this == SolAckState.NACK) { + updatedValue = TypeConverter.setBitOnPosition(ACK_BIT_NUMBER, value); + } - return updatedValue; - } + return updatedValue; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/payload/sol/SolInboundMessage.java b/src/main/java/org/metricshub/ipmi/core/coding/payload/sol/SolInboundMessage.java index b88dbd4..d7421fe 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/payload/sol/SolInboundMessage.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/payload/sol/SolInboundMessage.java @@ -27,29 +27,30 @@ */ public class SolInboundMessage extends SolMessage { - /** - * Status field in {@link SolMessage} BMC -> Remote Console payload. - */ - private final SolInboundStatusField statusField; - - public SolInboundMessage(byte sequenceNumber, byte ackNackSequenceNumber, byte acceptedCharacterCount, SolInboundStatusField statusField) { - super(sequenceNumber, ackNackSequenceNumber, acceptedCharacterCount, statusField.convertToByte()); - this.statusField = statusField; - } - - public SolInboundMessage(byte[] rawData) { - super(rawData[0], rawData[1], rawData[2], rawData[3]); - - if (rawData.length > PAYLOAD_HEADER_LENGTH) { - byte[] characterData = new byte[rawData.length - PAYLOAD_HEADER_LENGTH]; - System.arraycopy(rawData, PAYLOAD_HEADER_LENGTH, characterData, 0, characterData.length); - setData(characterData); - } - - this.statusField = new SolInboundStatusField(rawData[3]); - } - - public SolInboundStatusField getStatusField() { - return statusField; - } + /** + * Status field in {@link SolMessage} BMC -> Remote Console payload. + */ + private final SolInboundStatusField statusField; + + public SolInboundMessage(byte sequenceNumber, byte ackNackSequenceNumber, byte acceptedCharacterCount, + SolInboundStatusField statusField) { + super(sequenceNumber, ackNackSequenceNumber, acceptedCharacterCount, statusField.convertToByte()); + this.statusField = statusField; + } + + public SolInboundMessage(byte[] rawData) { + super(rawData[0], rawData[1], rawData[2], rawData[3]); + + if (rawData.length > PAYLOAD_HEADER_LENGTH) { + byte[] characterData = new byte[rawData.length - PAYLOAD_HEADER_LENGTH]; + System.arraycopy(rawData, PAYLOAD_HEADER_LENGTH, characterData, 0, characterData.length); + setData(characterData); + } + + this.statusField = new SolInboundStatusField(rawData[3]); + } + + public SolInboundStatusField getStatusField() { + return statusField; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/payload/sol/SolInboundStatusField.java b/src/main/java/org/metricshub/ipmi/core/coding/payload/sol/SolInboundStatusField.java index a547dbf..321bc32 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/payload/sol/SolInboundStatusField.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/payload/sol/SolInboundStatusField.java @@ -28,87 +28,88 @@ import java.util.Set; /** - * {@link SolInboundStatusField} is a transfer object for status sent by remote system to this application in {@link SolInboundMessage}. + * {@link SolInboundStatusField} is a transfer object for status sent by remote system to this application in + * {@link SolInboundMessage}. */ public class SolInboundStatusField { - /** - * Acknowledge state of {@link SolMessage} that this message is response for. - */ - private final SolAckState ackState; - - /** - * Set of statuses indicated by BMC in this message. - */ - private final Set statuses; - - /** - * Creates new instance if {@link SolInboundStatusField} without Acknowledge data. - * - * @param statuses - * Set of SOL specific statuses for inbound message - */ - public SolInboundStatusField(Set statuses) { - this.ackState = SolAckState.ACK; - this.statuses = statuses; - } - - /** - * Creates new instance of {@link SolInboundStatusField} filled with given data. - * - * @param ackState - * Acknowledge state carried by this object - * @param statuses - * Set of SOL specific statuses for inbound message - */ - public SolInboundStatusField(SolAckState ackState, Set statuses) { - this.ackState = ackState; - this.statuses = statuses; - } - - /** - * Creates new instance of {@link SolInboundStatusField} from raw byte. - * - * @param raw - * byte carrying information about SOL status - */ - public SolInboundStatusField(byte raw) { - this.ackState = SolAckState.extractFromByte(raw); - this.statuses = extractStatusesFromByte(raw); - } - - private Set extractStatusesFromByte(byte raw) { - Set result = new HashSet(); - - for (SolStatus status : SolStatus.values()) { - if (TypeConverter.isBitSetOnPosition(status.getStatusNumber(), raw)) { - result.add(status); - } - } - - return result; - } - - public Set getStatuses() { - return statuses; - } - - public SolAckState getAckState() { - return ackState; - } - - /** - * Convert this object to it's raw, byte representation. - */ - public byte convertToByte() { - byte value = (byte) 0; - - value = ackState.encodeInByte(value); - - for (SolStatus status : statuses) { - value = TypeConverter.setBitOnPosition(status.getStatusNumber(), value); - } - - return value; - } + /** + * Acknowledge state of {@link SolMessage} that this message is response for. + */ + private final SolAckState ackState; + + /** + * Set of statuses indicated by BMC in this message. + */ + private final Set statuses; + + /** + * Creates new instance if {@link SolInboundStatusField} without Acknowledge data. + * + * @param statuses + * Set of SOL specific statuses for inbound message + */ + public SolInboundStatusField(Set statuses) { + this.ackState = SolAckState.ACK; + this.statuses = statuses; + } + + /** + * Creates new instance of {@link SolInboundStatusField} filled with given data. + * + * @param ackState + * Acknowledge state carried by this object + * @param statuses + * Set of SOL specific statuses for inbound message + */ + public SolInboundStatusField(SolAckState ackState, Set statuses) { + this.ackState = ackState; + this.statuses = statuses; + } + + /** + * Creates new instance of {@link SolInboundStatusField} from raw byte. + * + * @param raw + * byte carrying information about SOL status + */ + public SolInboundStatusField(byte raw) { + this.ackState = SolAckState.extractFromByte(raw); + this.statuses = extractStatusesFromByte(raw); + } + + private Set extractStatusesFromByte(byte raw) { + Set result = new HashSet(); + + for (SolStatus status : SolStatus.values()) { + if (TypeConverter.isBitSetOnPosition(status.getStatusNumber(), raw)) { + result.add(status); + } + } + + return result; + } + + public Set getStatuses() { + return statuses; + } + + public SolAckState getAckState() { + return ackState; + } + + /** + * Convert this object to it's raw, byte representation. + */ + public byte convertToByte() { + byte value = (byte) 0; + + value = ackState.encodeInByte(value); + + for (SolStatus status : statuses) { + value = TypeConverter.setBitOnPosition(status.getStatusNumber(), value); + } + + return value; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/payload/sol/SolMessage.java b/src/main/java/org/metricshub/ipmi/core/coding/payload/sol/SolMessage.java index b7f64c2..5539f9d 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/payload/sol/SolMessage.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/payload/sol/SolMessage.java @@ -31,113 +31,114 @@ */ public abstract class SolMessage extends IpmiPayload { - public static final byte MIN_SEQUENCE_NUMBER = 1; - public static final byte MAX_SEQUENCE_NUMBER = 15; - - private static final int PACKET_SEQUENCE_NUMBER_LENGTH = 1; - private static final int PACKET_ACK_SEQUENCE_NUMBER_LENGTH = 1; - private static final int ACCEPTED_CHARACTERS_LENGTH = 1; - private static final int OPERATION_STATUS_LENGTH = 1; - - public static final int PAYLOAD_HEADER_LENGTH = - PACKET_SEQUENCE_NUMBER_LENGTH + - PACKET_ACK_SEQUENCE_NUMBER_LENGTH + - ACCEPTED_CHARACTERS_LENGTH + - OPERATION_STATUS_LENGTH; - - /** - * Sequence number of this packet. - */ - private final byte sequenceNumber; - - /** - * Sequence number of packet being ACKd/NACKd by this packet. - */ - private final byte ackNackSequenceNumber; - - /** - * Number of characters being accepted from ACKd/NACKd packet. - */ - private final byte acceptedCharacterCount; - - /** - * Operation to invoke or status of previously send packet. - */ - private final byte operationStatus; - - protected SolMessage(byte sequenceNumber, byte ackNackSequenceNumber, byte acceptedCharacterCount, byte operationStatus) { - this.sequenceNumber = trimSequenceNumber(sequenceNumber); - this.ackNackSequenceNumber = trimSequenceNumber(ackNackSequenceNumber); - this.acceptedCharacterCount = acceptedCharacterCount; - this.operationStatus = operationStatus; - } - - /** - * Trims given sequence number to max allowed value for sequence numbers, applying MAX_SEQUENCE_NUMBER mask on it. - * - * @param sequenceNumber - * Sequence number before trim - * @return trimmed sequence number - */ - private byte trimSequenceNumber(byte sequenceNumber) { - return TypeConverter.intToByte(sequenceNumber & MAX_SEQUENCE_NUMBER); - } - - @Override - public byte[] getPayloadData() { - return MessageComposer.get(getPayloadLength()) - .appendField(sequenceNumber) - .appendField(ackNackSequenceNumber) - .appendField(acceptedCharacterCount) - .appendField(operationStatus) - .appendField(getData()) - .getMessage(); - } - - @Override - public int getPayloadLength() { - return PAYLOAD_HEADER_LENGTH + getData().length; - } - - @Override - public byte[] getIpmiCommandData() { - return getData(); - } - - @Override - public byte[] getData() { - byte[] data = super.getData(); - - if (data == null) { - return new byte[0]; - } - - return data; - } - - public byte getSequenceNumber() { - return sequenceNumber; - } - - public byte getAckNackSequenceNumber() { - return ackNackSequenceNumber; - } - - public byte getAcceptedCharacterCount() { - return acceptedCharacterCount; - } - - /** - * Checks if given message carries some data (or operation/status). - */ - public boolean isDataCarrier() { - return sequenceNumber != 0 || getData().length > 0; - } - - /** - * Checks if given {@link SolMessage} is an ACK/NACK for some other message. - */ - public boolean isAcknowledgeMessage() { - return ackNackSequenceNumber != 0; - } + public static final byte MIN_SEQUENCE_NUMBER = 1; + public static final byte MAX_SEQUENCE_NUMBER = 15; + + private static final int PACKET_SEQUENCE_NUMBER_LENGTH = 1; + private static final int PACKET_ACK_SEQUENCE_NUMBER_LENGTH = 1; + private static final int ACCEPTED_CHARACTERS_LENGTH = 1; + private static final int OPERATION_STATUS_LENGTH = 1; + + public static final int PAYLOAD_HEADER_LENGTH = PACKET_SEQUENCE_NUMBER_LENGTH + + PACKET_ACK_SEQUENCE_NUMBER_LENGTH + + ACCEPTED_CHARACTERS_LENGTH + + OPERATION_STATUS_LENGTH; + + /** + * Sequence number of this packet. + */ + private final byte sequenceNumber; + + /** + * Sequence number of packet being ACKd/NACKd by this packet. + */ + private final byte ackNackSequenceNumber; + + /** + * Number of characters being accepted from ACKd/NACKd packet. + */ + private final byte acceptedCharacterCount; + + /** + * Operation to invoke or status of previously send packet. + */ + private final byte operationStatus; + + protected SolMessage(byte sequenceNumber, byte ackNackSequenceNumber, byte acceptedCharacterCount, + byte operationStatus) { + this.sequenceNumber = trimSequenceNumber(sequenceNumber); + this.ackNackSequenceNumber = trimSequenceNumber(ackNackSequenceNumber); + this.acceptedCharacterCount = acceptedCharacterCount; + this.operationStatus = operationStatus; + } + + /** + * Trims given sequence number to max allowed value for sequence numbers, applying MAX_SEQUENCE_NUMBER mask on it. + * + * @param number + * Sequence number before trim + * @return trimmed sequence number + */ + private byte trimSequenceNumber(byte number) { + return TypeConverter.intToByte(number & MAX_SEQUENCE_NUMBER); + } + + @Override + public byte[] getPayloadData() { + return MessageComposer + .get(getPayloadLength()) + .appendField(sequenceNumber) + .appendField(ackNackSequenceNumber) + .appendField(acceptedCharacterCount) + .appendField(operationStatus) + .appendField(getData()) + .getMessage(); + } + + @Override + public int getPayloadLength() { + return PAYLOAD_HEADER_LENGTH + getData().length; + } + + @Override + public byte[] getIpmiCommandData() { + return getData(); + } + + @Override + public byte[] getData() { + byte[] data = super.getData(); + + if (data == null) { + return new byte[0]; + } + + return data; + } + + public byte getSequenceNumber() { + return sequenceNumber; + } + + public byte getAckNackSequenceNumber() { + return ackNackSequenceNumber; + } + + public byte getAcceptedCharacterCount() { + return acceptedCharacterCount; + } + + /** + * Checks if given message carries some data (or operation/status). + */ + public boolean isDataCarrier() { + return sequenceNumber != 0 || getData().length > 0; + } + + /** + * Checks if given {@link SolMessage} is an ACK/NACK for some other message. + */ + public boolean isAcknowledgeMessage() { + return ackNackSequenceNumber != 0; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/payload/sol/SolOperation.java b/src/main/java/org/metricshub/ipmi/core/coding/payload/sol/SolOperation.java index daa7ef1..9ec8e1c 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/payload/sol/SolOperation.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/payload/sol/SolOperation.java @@ -26,50 +26,51 @@ * Enumeration of all possible operations, that Remote Console can invoke on BMC during SOL communication. */ public enum SolOperation { - /** - * Assert RI (may not be supported on all implementations) - Goal is to allow this to be used for generating a WOR. - */ - RingWOR(5), + /** + * Assert RI (may not be supported on all implementations) - Goal is to allow this to be used for generating a WOR. + */ + RingWOR(5), - /** - * Generate BREAK (300 ms, nominal) - */ - Break(4), + /** + * Generate BREAK (300 ms, nominal) + */ + Break(4), - /** - * Deassert CTS (clear to send) to the baseboard serial controller. - * (This is the default state when SOL is deactivated.) - */ - CTS(3), + /** + * Deassert CTS (clear to send) to the baseboard serial controller. + * (This is the default state when SOL is deactivated.) + */ + CTS(3), - /** - * When test mode inactive, deassert DCD/DSR to baseboard serial controller. - * For test mode active, deassert just DCD to baseboard serial controller. - */ - DCD_DSR(2), + /** + * When test mode inactive, deassert DCD/DSR to baseboard serial controller. + * For test mode active, deassert just DCD to baseboard serial controller. + */ + DCD_DSR(2), - /** - * When test mode inactive, drop (flush) data from remote console to BMC [not including data carried in this packet, if any]. - * For test mode active, deassert DSR to baseboard serial controller. - */ - FlushInbound(1), + /** + * When test mode inactive, drop (flush) data from remote console to BMC [not including data carried in this packet, + * if any]. + * For test mode active, deassert DSR to baseboard serial controller. + */ + FlushInbound(1), - /** - * When test mode inactive, flush Outbound Character Data (flush data from BMC to remote console). - * When test mode active, won't have any effect. - */ - FlushOutbound(0); + /** + * When test mode inactive, flush Outbound Character Data (flush data from BMC to remote console). + * When test mode active, won't have any effect. + */ + FlushOutbound(0); - /** - * ID of the operation (number of bit in operation field byte). - */ - private final int operationNumber; + /** + * ID of the operation (number of bit in operation field byte). + */ + private final int operationNumber; - SolOperation(int operationNumber) { - this.operationNumber = operationNumber; - } + SolOperation(int operationNumber) { + this.operationNumber = operationNumber; + } - public int getOperationNumber() { - return operationNumber; - } + public int getOperationNumber() { + return operationNumber; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/payload/sol/SolOutboundMessage.java b/src/main/java/org/metricshub/ipmi/core/coding/payload/sol/SolOutboundMessage.java index 56da885..e3d1e11 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/payload/sol/SolOutboundMessage.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/payload/sol/SolOutboundMessage.java @@ -27,19 +27,20 @@ */ public class SolOutboundMessage extends SolMessage { - /** - * Operation field in {@link SolMessage} Remote Console -> BMC payload. - */ - private final SolOutboundOperationField operationField; + /** + * Operation field in {@link SolMessage} Remote Console -> BMC payload. + */ + private final SolOutboundOperationField operationField; - public SolOutboundMessage(byte sequenceNumber, byte ackNackSequenceNumber, byte acceptedCharacterCount, SolOutboundOperationField operationField) { - super(sequenceNumber, ackNackSequenceNumber, acceptedCharacterCount, operationField.convertToByte()); + public SolOutboundMessage(byte sequenceNumber, byte ackNackSequenceNumber, byte acceptedCharacterCount, + SolOutboundOperationField operationField) { + super(sequenceNumber, ackNackSequenceNumber, acceptedCharacterCount, operationField.convertToByte()); - this.operationField = operationField; - } + this.operationField = operationField; + } - public SolOutboundOperationField getOperationField() { - return operationField; - } + public SolOutboundOperationField getOperationField() { + return operationField; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/payload/sol/SolOutboundOperationField.java b/src/main/java/org/metricshub/ipmi/core/coding/payload/sol/SolOutboundOperationField.java index 2b4f398..b545eda 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/payload/sol/SolOutboundOperationField.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/payload/sol/SolOutboundOperationField.java @@ -28,77 +28,78 @@ import java.util.Set; /** - * {@link SolOutboundOperationField} is a transfer object for operation sent by this application to remote system in {@link SolOutboundMessage}. + * {@link SolOutboundOperationField} is a transfer object for operation sent by this application to remote system in + * {@link SolOutboundMessage}. */ public class SolOutboundOperationField { - /** - * Acknowledge state of {@link SolMessage} that this message is response for. - */ - private final SolAckState ackState; - - /** - * Set of operations to invoke on BMC. - */ - private final Set operations; - - /** - * Creates new instance of {@link SolOutboundOperationField} filled with given data. - * - * @param ackState - * Acknowledge state carried by this object - * @param operations - * Set of SOL specific operations for outbound message - */ - public SolOutboundOperationField(SolAckState ackState, Set operations) { - this.ackState = ackState; - this.operations = operations; - } - - /** - * Creates new instance of {@link SolOutboundOperationField} from raw byte. - * - * @param raw - * byte carrying information about SOL operations - */ - public SolOutboundOperationField(byte raw) { - this.ackState = SolAckState.extractFromByte(raw); - this.operations = extractOperationsFromByte(raw); - } - - protected Set extractOperationsFromByte(byte raw) { - Set result = new HashSet(); - - for (SolOperation operation : SolOperation.values()) { - if (TypeConverter.isBitSetOnPosition(operation.getOperationNumber(), raw)) { - result.add(operation); - } - } - - return result; - } - - public Set getOperations() { - return operations; - } - - public SolAckState getAckState() { - return ackState; - } - - /** - * Convert this object to it's raw, byte representation. - */ - public byte convertToByte() { - byte value = (byte) 0; - - value = ackState.encodeInByte(value); - - for (SolOperation operation : operations) { - value = TypeConverter.setBitOnPosition(operation.getOperationNumber(), value); - } - - return value; - } + /** + * Acknowledge state of {@link SolMessage} that this message is response for. + */ + private final SolAckState ackState; + + /** + * Set of operations to invoke on BMC. + */ + private final Set operations; + + /** + * Creates new instance of {@link SolOutboundOperationField} filled with given data. + * + * @param ackState + * Acknowledge state carried by this object + * @param operations + * Set of SOL specific operations for outbound message + */ + public SolOutboundOperationField(SolAckState ackState, Set operations) { + this.ackState = ackState; + this.operations = operations; + } + + /** + * Creates new instance of {@link SolOutboundOperationField} from raw byte. + * + * @param raw + * byte carrying information about SOL operations + */ + public SolOutboundOperationField(byte raw) { + this.ackState = SolAckState.extractFromByte(raw); + this.operations = extractOperationsFromByte(raw); + } + + protected Set extractOperationsFromByte(byte raw) { + Set result = new HashSet(); + + for (SolOperation operation : SolOperation.values()) { + if (TypeConverter.isBitSetOnPosition(operation.getOperationNumber(), raw)) { + result.add(operation); + } + } + + return result; + } + + public Set getOperations() { + return operations; + } + + public SolAckState getAckState() { + return ackState; + } + + /** + * Convert this object to it's raw, byte representation. + */ + public byte convertToByte() { + byte value = (byte) 0; + + value = ackState.encodeInByte(value); + + for (SolOperation operation : operations) { + value = TypeConverter.setBitOnPosition(operation.getOperationNumber(), value); + } + + return value; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/payload/sol/SolStatus.java b/src/main/java/org/metricshub/ipmi/core/coding/payload/sol/SolStatus.java index e230d1b..79a7a21 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/payload/sol/SolStatus.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/payload/sol/SolStatus.java @@ -26,56 +26,56 @@ * Enumeration of all possible states, that Remote Console can receive from BMC during SOL communication. */ public enum SolStatus { - /** - * Character transfer is unavailable because system is in a powered-down or sleep state. - */ - CharacterTransferUnavailable(5), + /** + * Character transfer is unavailable because system is in a powered-down or sleep state. + */ + CharacterTransferUnavailable(5), - /** - * SOL is deactivated/deactivating. - * (Remote console can use this to tell if SOL was deactivated by some other party, - * or by local pushbutton reset or power on/off). - */ - SolDeactivated(4), + /** + * SOL is deactivated/deactivating. + * (Remote console can use this to tell if SOL was deactivated by some other party, + * or by local pushbutton reset or power on/off). + */ + SolDeactivated(4), - /** - * Characters were dropped between transmitting this packet and the previous packet, - * because the system did not pay attention to hardware flow control. - */ - TransmitOverrun(3), + /** + * Characters were dropped between transmitting this packet and the previous packet, + * because the system did not pay attention to hardware flow control. + */ + TransmitOverrun(3), - /** - * A break condition from the system has been detected. - * The BMC will generate this only on one packet at the start of the break. - */ - Break(2), + /** + * A break condition from the system has been detected. + * The BMC will generate this only on one packet at the start of the break. + */ + Break(2), - /** - * When test mode active, signals that RTS is asserted on serial port. - * For test mode inactive, it is unused. - * A packet with this status will be automatically sent whenever RTS changes state. - * Note that this packet may not contain character data. - */ - RtsAsserted(1), + /** + * When test mode active, signals that RTS is asserted on serial port. + * For test mode inactive, it is unused. + * A packet with this status will be automatically sent whenever RTS changes state. + * Note that this packet may not contain character data. + */ + RtsAsserted(1), - /** - * When test mode active, signals that DTR is asserted on serial port. - * For test mode inactive, it is unused. - * A packet with this status will be automatically sent whenever DTR changes state. - * Note that this packet may not contain character data. - */ - DtrAsserted(0); + /** + * When test mode active, signals that DTR is asserted on serial port. + * For test mode inactive, it is unused. + * A packet with this status will be automatically sent whenever DTR changes state. + * Note that this packet may not contain character data. + */ + DtrAsserted(0); - /** - * ID of the status (number of bit in status field byte). - */ - private final int statusNumber; + /** + * ID of the status (number of bit in status field byte). + */ + private final int statusNumber; - SolStatus(int statusNumber) { - this.statusNumber = statusNumber; - } + SolStatus(int statusNumber) { + this.statusNumber = statusNumber; + } - public int getStatusNumber() { - return statusNumber; - } + public int getStatusNumber() { + return statusNumber; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/protocol/AuthenticationType.java b/src/main/java/org/metricshub/ipmi/core/coding/protocol/AuthenticationType.java index 8ae1c0c..fad1590 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/protocol/AuthenticationType.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/protocol/AuthenticationType.java @@ -27,43 +27,48 @@ * used. */ public enum AuthenticationType { - None(AuthenticationType.NONE), Md2(AuthenticationType.MD2), Md5( - AuthenticationType.MD5), Simple(AuthenticationType.SIMPLE), Oem( - AuthenticationType.OEM), RMCPPlus(AuthenticationType.RMCPPLUS), ; + None(AuthenticationType.NONE), + Md2(AuthenticationType.MD2), + Md5( + AuthenticationType.MD5), + Simple(AuthenticationType.SIMPLE), + Oem( + AuthenticationType.OEM), + RMCPPlus(AuthenticationType.RMCPPLUS),; - private static final int NONE = 0; - private static final int MD2 = 1; - private static final int MD5 = 2; - private static final int SIMPLE = 4; - private static final int OEM = 5; - private static final int RMCPPLUS = 6; + private static final int NONE = 0; + private static final int MD2 = 1; + private static final int MD5 = 2; + private static final int SIMPLE = 4; + private static final int OEM = 5; + private static final int RMCPPLUS = 6; - private int code; + private int code; - AuthenticationType(int code) { - this.code = code; - } + AuthenticationType(int code) { + this.code = code; + } - public int getCode() { - return code; - } + public int getCode() { + return code; + } - public static AuthenticationType parseInt(int value) { - switch (value) { - case NONE: - return None; - case MD2: - return Md2; - case MD5: - return Md5; - case SIMPLE: - return Simple; - case OEM: - return Oem; - case RMCPPLUS: - return RMCPPlus; - default: - throw new IllegalArgumentException("Invalid value: " + value); - } - } + public static AuthenticationType parseInt(int value) { + switch (value) { + case NONE: + return None; + case MD2: + return Md2; + case MD5: + return Md5; + case SIMPLE: + return Simple; + case OEM: + return Oem; + case RMCPPLUS: + return RMCPPlus; + default: + throw new IllegalArgumentException("Invalid value: " + value); + } + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/protocol/IpmiMessage.java b/src/main/java/org/metricshub/ipmi/core/coding/protocol/IpmiMessage.java index b45c1a4..9c22a80 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/protocol/IpmiMessage.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/protocol/IpmiMessage.java @@ -29,85 +29,86 @@ * Wrapper class for IPMI message */ public abstract class IpmiMessage { - private AuthenticationType authenticationType; - - private int sessionSequenceNumber; - - private int sessionID; - - private byte[] authCode; - - private IpmiPayload payload; - - private int payloadLength; - - /** - * Confidentiality Algorithm used for encryption and decryption. - */ - private ConfidentialityAlgorithm confidentialityAlgorithm; - - public void setAuthenticationType(AuthenticationType authenticationType) { - this.authenticationType = authenticationType; - } - - public AuthenticationType getAuthenticationType() { - return authenticationType; - } - - public void setSessionSequenceNumber(int sessionSequenceNumber) { - this.sessionSequenceNumber = sessionSequenceNumber; - } - - public int getSessionSequenceNumber() { - return sessionSequenceNumber; - } - - public void setSessionID(int sessionID) { - this.sessionID = sessionID; - } - - public int getSessionID() { - return sessionID; - } - - public void setAuthCode(byte[] authCode) { - this.authCode = authCode; - } - - public byte[] getAuthCode() { - return authCode; - } - - /** - * Sets {@link #payload} and {@link #payloadLength} - * @param payload - */ - public void setPayload(IpmiPayload payload) { - setPayloadLength(payload.getPayloadLength()); - this.payload = payload; - } - - public IpmiPayload getPayload() { - return payload; - } - - public void setPayloadLength(int payloadLength) { - this.payloadLength = payloadLength; - } - - /** - * @return Length of the UNENCRYPTED payload. - */ - public int getPayloadLength() { - return payloadLength; - } - - public void setConfidentialityAlgorithm(ConfidentialityAlgorithm confidentialityAlgorithm) { - this.confidentialityAlgorithm = confidentialityAlgorithm; - } - - public ConfidentialityAlgorithm getConfidentialityAlgorithm() { - return confidentialityAlgorithm; - } + private AuthenticationType authenticationType; + + private int sessionSequenceNumber; + + private int sessionID; + + private byte[] authCode; + + private IpmiPayload payload; + + private int payloadLength; + + /** + * Confidentiality Algorithm used for encryption and decryption. + */ + private ConfidentialityAlgorithm confidentialityAlgorithm; + + public void setAuthenticationType(AuthenticationType authenticationType) { + this.authenticationType = authenticationType; + } + + public AuthenticationType getAuthenticationType() { + return authenticationType; + } + + public void setSessionSequenceNumber(int sessionSequenceNumber) { + this.sessionSequenceNumber = sessionSequenceNumber; + } + + public int getSessionSequenceNumber() { + return sessionSequenceNumber; + } + + public void setSessionID(int sessionID) { + this.sessionID = sessionID; + } + + public int getSessionID() { + return sessionID; + } + + public void setAuthCode(byte[] authCode) { + this.authCode = authCode; + } + + public byte[] getAuthCode() { + return authCode; + } + + /** + * Sets {@link #payload} and {@link #payloadLength} + * + * @param payload + */ + public void setPayload(IpmiPayload payload) { + setPayloadLength(payload.getPayloadLength()); + this.payload = payload; + } + + public IpmiPayload getPayload() { + return payload; + } + + public void setPayloadLength(int payloadLength) { + this.payloadLength = payloadLength; + } + + /** + * @return Length of the UNENCRYPTED payload. + */ + public int getPayloadLength() { + return payloadLength; + } + + public void setConfidentialityAlgorithm(ConfidentialityAlgorithm confidentialityAlgorithm) { + this.confidentialityAlgorithm = confidentialityAlgorithm; + } + + public ConfidentialityAlgorithm getConfidentialityAlgorithm() { + return confidentialityAlgorithm; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/protocol/Ipmiv15Message.java b/src/main/java/org/metricshub/ipmi/core/coding/protocol/Ipmiv15Message.java index 0cab16f..dc1e00c 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/protocol/Ipmiv15Message.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/protocol/Ipmiv15Message.java @@ -29,16 +29,16 @@ */ public class Ipmiv15Message extends IpmiMessage { - public Ipmiv15Message() { - setConfidentialityAlgorithm(new ConfidentialityNone()); - } + public Ipmiv15Message() { + setConfidentialityAlgorithm(new ConfidentialityNone()); + } - @Override - public void setAuthenticationType(AuthenticationType authenticationType) { - if (authenticationType == AuthenticationType.RMCPPlus) { - throw new IllegalArgumentException( - "IPMIv1.5 does not support RMCP+"); - } - super.setAuthenticationType(authenticationType); - } + @Override + public void setAuthenticationType(AuthenticationType authenticationType) { + if (authenticationType == AuthenticationType.RMCPPlus) { + throw new IllegalArgumentException( + "IPMIv1.5 does not support RMCP+"); + } + super.setAuthenticationType(authenticationType); + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/protocol/Ipmiv20Message.java b/src/main/java/org/metricshub/ipmi/core/coding/protocol/Ipmiv20Message.java index cd9b6c5..026d427 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/protocol/Ipmiv20Message.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/protocol/Ipmiv20Message.java @@ -31,77 +31,77 @@ * Wrapper class for IPMI v2.0 message */ public class Ipmiv20Message extends IpmiMessage { - private boolean payloadEncrypted; - - private boolean payloadAuthenticated; - - private PayloadType payloadType; - - private int oemIANA; - - private Object oemPayloadID; - - public void setPayloadEncrypted(boolean payloadEncrypted) { - this.payloadEncrypted = payloadEncrypted; - } - - public boolean isPayloadEncrypted() { - return payloadEncrypted; - } - - public void setPayloadAuthenticated(boolean payloadAuthenticated) { - this.payloadAuthenticated = payloadAuthenticated; - } - - public boolean isPayloadAuthenticated() { - return payloadAuthenticated; - } - - public void setPayloadType(PayloadType payloadType) { - this.payloadType = payloadType; - } - - public PayloadType getPayloadType() { - return payloadType; - } - - public void setOemIANA(int oemIANA) { - this.oemIANA = oemIANA; - } - - public int getOemIANA() { - return oemIANA; - } - - public void setOemPayloadID(Object oemPayloadID) { - this.oemPayloadID = oemPayloadID; - } - - public Object getOemPayloadID() { - return oemPayloadID; - } - - public Ipmiv20Message(ConfidentialityAlgorithm confidentialityAlgorithm) { - setConfidentialityAlgorithm(confidentialityAlgorithm); - } - - /** - * Gets base for integrity algorithm calculations. If used for the message - * being created, does not contain AuthCode field so amount of Integrity Pad - * bytes cannot be calculated. Therefore integrity algorithms using this - * base must add proper amount of the Integrity Pad bytes and modify the Pad - * Length byte. - * - * @param encoder - * - {@link IpmiEncoder} to be used to convert message to byte - * array format. Must be able to handle null authCode field with - * {@link #isPayloadAuthenticated()} == true since this method is - * used in its generation. - * @return base for integrity algorithm calculations - * @throws InvalidKeyException - * - when initiation of the confidentiality algorithm fails - */ - public byte[] getIntegrityAlgorithmBase(IpmiEncoder encoder) throws InvalidKeyException { - return encoder.encode(this); - } + private boolean payloadEncrypted; + + private boolean payloadAuthenticated; + + private PayloadType payloadType; + + private int oemIANA; + + private Object oemPayloadID; + + public void setPayloadEncrypted(boolean payloadEncrypted) { + this.payloadEncrypted = payloadEncrypted; + } + + public boolean isPayloadEncrypted() { + return payloadEncrypted; + } + + public void setPayloadAuthenticated(boolean payloadAuthenticated) { + this.payloadAuthenticated = payloadAuthenticated; + } + + public boolean isPayloadAuthenticated() { + return payloadAuthenticated; + } + + public void setPayloadType(PayloadType payloadType) { + this.payloadType = payloadType; + } + + public PayloadType getPayloadType() { + return payloadType; + } + + public void setOemIANA(int oemIANA) { + this.oemIANA = oemIANA; + } + + public int getOemIANA() { + return oemIANA; + } + + public void setOemPayloadID(Object oemPayloadID) { + this.oemPayloadID = oemPayloadID; + } + + public Object getOemPayloadID() { + return oemPayloadID; + } + + public Ipmiv20Message(ConfidentialityAlgorithm confidentialityAlgorithm) { + setConfidentialityAlgorithm(confidentialityAlgorithm); + } + + /** + * Gets base for integrity algorithm calculations. If used for the message + * being created, does not contain AuthCode field so amount of Integrity Pad + * bytes cannot be calculated. Therefore integrity algorithms using this + * base must add proper amount of the Integrity Pad bytes and modify the Pad + * Length byte. + * + * @param encoder + * - {@link IpmiEncoder} to be used to convert message to byte + * array format. Must be able to handle null authCode field with + * {@link #isPayloadAuthenticated()} == true since this method is + * used in its generation. + * @return base for integrity algorithm calculations + * @throws InvalidKeyException + * - when initiation of the confidentiality algorithm fails + */ + public byte[] getIntegrityAlgorithmBase(IpmiEncoder encoder) throws InvalidKeyException { + return encoder.encode(this); + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/protocol/PayloadType.java b/src/main/java/org/metricshub/ipmi/core/coding/protocol/PayloadType.java index ccf5540..6ebdc62 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/protocol/PayloadType.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/protocol/PayloadType.java @@ -26,104 +26,115 @@ * Types of IPMI packet payload */ public enum PayloadType { - /** - * IPMI packet - */ - Ipmi(PayloadType.IPMI), - /** - * Serial over LAN packet - */ - Sol(PayloadType.SOL), - /** - * OEM Explicit - */ - Oem(PayloadType.OEM), RmcpOpenSessionRequest( - PayloadType.RMCPOPENSESSIONREQUEST), RmcpOpenSessionResponse( - PayloadType.RMCPOPENSESSIONRESPONSE), - /** - * RAKP Message 1 - */ - Rakp1(PayloadType.RAKP1), - /** - * RAKP Message 2 - */ - Rakp2(PayloadType.RAKP2), - /** - * RAKP Message 3 - */ - Rakp3(PayloadType.RAKP3), - /** - * RAKP Message 4 - */ - Rakp4(PayloadType.RAKP4), Oem0(PayloadType.OEM0), Oem1(PayloadType.OEM1), Oem2( - PayloadType.OEM2), Oem3(PayloadType.OEM3), Oem4(PayloadType.OEM4), Oem5( - PayloadType.OEM5), Oem6(PayloadType.OEM6), Oem7(PayloadType.OEM7), ; - private static final int IPMI = 0; - private static final int SOL = 1; - private static final int OEM = 2; - private static final int RMCPOPENSESSIONREQUEST = 16; - private static final int RMCPOPENSESSIONRESPONSE = 17; - private static final int RAKP1 = 18; - private static final int RAKP2 = 19; - private static final int RAKP3 = 20; - private static final int RAKP4 = 21; - private static final int OEM0 = 32; - private static final int OEM1 = 33; - private static final int OEM2 = 34; - private static final int OEM3 = 35; - private static final int OEM4 = 36; - private static final int OEM5 = 37; - private static final int OEM6 = 38; - private static final int OEM7 = 39; + /** + * IPMI packet + */ + Ipmi(PayloadType.IPMI), + /** + * Serial over LAN packet + */ + Sol(PayloadType.SOL), + /** + * OEM Explicit + */ + Oem(PayloadType.OEM), + RmcpOpenSessionRequest( + PayloadType.RMCPOPENSESSIONREQUEST), + RmcpOpenSessionResponse( + PayloadType.RMCPOPENSESSIONRESPONSE), + /** + * RAKP Message 1 + */ + Rakp1(PayloadType.RAKP1), + /** + * RAKP Message 2 + */ + Rakp2(PayloadType.RAKP2), + /** + * RAKP Message 3 + */ + Rakp3(PayloadType.RAKP3), + /** + * RAKP Message 4 + */ + Rakp4(PayloadType.RAKP4), + Oem0(PayloadType.OEM0), + Oem1(PayloadType.OEM1), + Oem2( + PayloadType.OEM2), + Oem3(PayloadType.OEM3), + Oem4(PayloadType.OEM4), + Oem5( + PayloadType.OEM5), + Oem6(PayloadType.OEM6), + Oem7(PayloadType.OEM7),; - private int code; + private static final int IPMI = 0; + private static final int SOL = 1; + private static final int OEM = 2; + private static final int RMCPOPENSESSIONREQUEST = 16; + private static final int RMCPOPENSESSIONRESPONSE = 17; + private static final int RAKP1 = 18; + private static final int RAKP2 = 19; + private static final int RAKP3 = 20; + private static final int RAKP4 = 21; + private static final int OEM0 = 32; + private static final int OEM1 = 33; + private static final int OEM2 = 34; + private static final int OEM3 = 35; + private static final int OEM4 = 36; + private static final int OEM5 = 37; + private static final int OEM6 = 38; + private static final int OEM7 = 39; - PayloadType(int code) { - this.code = code; - } + private int code; - public int getCode() { - return code; - } + PayloadType(int code) { + this.code = code; + } - public static PayloadType parseInt(int value) { - switch (value) { - case IPMI: - return Ipmi; - case SOL: - return Sol; - case OEM: - return Oem; - case RMCPOPENSESSIONREQUEST: - return RmcpOpenSessionRequest; - case RMCPOPENSESSIONRESPONSE: - return RmcpOpenSessionResponse; - case RAKP1: - return Rakp1; - case RAKP2: - return Rakp2; - case RAKP3: - return Rakp3; - case RAKP4: - return Rakp4; - case OEM0: - return Oem0; - case OEM1: - return Oem1; - case OEM2: - return Oem2; - case OEM3: - return Oem3; - case OEM4: - return Oem4; - case OEM5: - return Oem5; - case OEM6: - return Oem6; - case OEM7: - return Oem7; - default: - throw new IllegalArgumentException("Invalid value: " + value); - } - } + public int getCode() { + return code; + } + + public static PayloadType parseInt(int value) { + switch (value) { + case IPMI: + return Ipmi; + case SOL: + return Sol; + case OEM: + return Oem; + case RMCPOPENSESSIONREQUEST: + return RmcpOpenSessionRequest; + case RMCPOPENSESSIONRESPONSE: + return RmcpOpenSessionResponse; + case RAKP1: + return Rakp1; + case RAKP2: + return Rakp2; + case RAKP3: + return Rakp3; + case RAKP4: + return Rakp4; + case OEM0: + return Oem0; + case OEM1: + return Oem1; + case OEM2: + return Oem2; + case OEM3: + return Oem3; + case OEM4: + return Oem4; + case OEM5: + return Oem5; + case OEM6: + return Oem6; + case OEM7: + return Oem7; + default: + throw new IllegalArgumentException("Invalid value: " + value); + } + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/protocol/decoder/IpmiDecoder.java b/src/main/java/org/metricshub/ipmi/core/coding/protocol/decoder/IpmiDecoder.java index a5606a7..092ef32 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/protocol/decoder/IpmiDecoder.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/protocol/decoder/IpmiDecoder.java @@ -31,17 +31,18 @@ * Decodes IPMI session header and retrieves encrypted payload. */ public interface IpmiDecoder { - - /** - * Decodes IPMI message. - * @param rmcpMessage - * - RMCP message to decode. - * @see IpmiMessage - * @return Decoded IPMI message - * @throws IllegalArgumentException - * when delivered RMCP message does not contain encapsulated IPMI message. - * @throws InvalidKeyException - * - when initiation of the integrity algorithm fails - */ - IpmiMessage decode(RmcpMessage rmcpMessage) throws InvalidKeyException; + + /** + * Decodes IPMI message. + * + * @param rmcpMessage + * - RMCP message to decode. + * @see IpmiMessage + * @return Decoded IPMI message + * @throws IllegalArgumentException + * when delivered RMCP message does not contain encapsulated IPMI message. + * @throws InvalidKeyException + * - when initiation of the integrity algorithm fails + */ + IpmiMessage decode(RmcpMessage rmcpMessage) throws InvalidKeyException; } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/protocol/decoder/PlainCommandv20Decoder.java b/src/main/java/org/metricshub/ipmi/core/coding/protocol/decoder/PlainCommandv20Decoder.java index 1040513..459a48a 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/protocol/decoder/PlainCommandv20Decoder.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/protocol/decoder/PlainCommandv20Decoder.java @@ -35,21 +35,24 @@ */ public class PlainCommandv20Decoder extends Protocolv20Decoder { - public PlainCommandv20Decoder(CipherSuite cipherSuite) { - super(cipherSuite); - } + public PlainCommandv20Decoder(CipherSuite cipherSuite) { + super(cipherSuite); + } - /** - * - * @return Payload decoded into {@link PlainMessage}. - */ - @Override - protected IpmiPayload decodePayload(byte[] rawData, int offset, int length, - ConfidentialityAlgorithm confidentialityAlgorithm, PayloadType payloadType) { - byte[] payload = new byte[length]; + /** + * @return Payload decoded into {@link PlainMessage}. + */ + @Override + protected IpmiPayload decodePayload( + byte[] rawData, + int offset, + int length, + ConfidentialityAlgorithm confidentialityAlgorithm, + PayloadType payloadType) { + byte[] payload = new byte[length]; - System.arraycopy(rawData, offset, payload, 0, length); + System.arraycopy(rawData, offset, payload, 0, length); - return new PlainMessage(confidentialityAlgorithm.decrypt(payload)); - } + return new PlainMessage(confidentialityAlgorithm.decrypt(payload)); + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/protocol/decoder/ProtocolDecoder.java b/src/main/java/org/metricshub/ipmi/core/coding/protocol/decoder/ProtocolDecoder.java index 9d8b303..4aff7fe 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/protocol/decoder/ProtocolDecoder.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/protocol/decoder/ProtocolDecoder.java @@ -39,162 +39,179 @@ */ public abstract class ProtocolDecoder implements IpmiDecoder { - public ProtocolDecoder() { - - } - - /** - * Decodes IPMI message version independent fields. - * - * @param rmcpMessage - * - RMCP message to decode. - * @param message - * - A reference to message being decoded. - * @param sequenceNumberOffset - * - Protocol version specific offset to Session Sequence Number - * field in the header of the IPMI message. - * @param payloadLengthOffset - * - Protocol version specific offset to IPMI Payload Length - * field in the header of the IPMI message. - * @param payloadLengthLength - * - Length of the payload length field. - * @see IpmiMessage - * @return Offset to the session trailer. - * @throws IllegalArgumentException - * when delivered RMCP message does not contain encapsulated - * IPMI message. - * - * @deprecated this method is obolete. use {@link ProtocolDecoder#decode(RmcpMessage)} instead - */ - @Deprecated - protected int decode(RmcpMessage rmcpMessage, IpmiMessage message, - int sequenceNumberOffset, int payloadLengthOffset, - int payloadLengthLength) { - - if (rmcpMessage.getClassOfMessage() != RmcpClassOfMessage.Ipmi) { - throw new IllegalArgumentException("This is not an IPMI message"); - } - - byte[] raw = rmcpMessage.getData(); - - message.setAuthenticationType(decodeAuthenticationType(raw[0])); - - message.setSessionSequenceNumber(decodeSessionSequenceNumber(raw, - sequenceNumberOffset)); - - message.setPayloadLength(decodePayloadLength(raw, payloadLengthOffset)); - - message.setPayload(decodePayload(raw, payloadLengthOffset - + payloadLengthLength, message.getPayloadLength(), - message.getConfidentialityAlgorithm(), PayloadType.Ipmi)); - - return payloadLengthOffset + payloadLengthLength - + message.getPayloadLength(); - } - - protected static AuthenticationType decodeAuthenticationType(byte authenticationType) { - authenticationType &= TypeConverter.intToByte(0x0f); - - return AuthenticationType.parseInt(TypeConverter - .byteToInt(authenticationType)); - } - - /** - * Decodes {@link AuthenticationType} of the message so that the version of - * the IPMI protocol could be determined. - * - * @param message - * - RMCP message to decode. - * @return {@link AuthenticationType} of the message. - */ - public static AuthenticationType decodeAuthenticationType( - RmcpMessage message) { - return decodeAuthenticationType(message.getData()[0]); - } - - /** - * Decodes int in a little endian convention from raw message at given - * offset - * - * @param rawMessage - * - Raw message to be decoded - * @param offset - * @return Decoded integer - */ - protected static int decodeInt(byte[] rawMessage, int offset) { - byte[] result = new byte[4]; - - System.arraycopy(rawMessage, offset, result, 0, 4); - - return TypeConverter.littleEndianByteArrayToInt(result); - } - - /** - * Decodes session sequence number. - * - * @param rawMessage - * - Byte array holding whole message data. - * @param offset - * - Offset to session sequence number in header. - * @return Session Sequence number. - */ - protected int decodeSessionSequenceNumber(byte[] rawMessage, int offset) { - return decodeInt(rawMessage, offset); - } - - /** - * Decodes session ID. - * - * @param rawMessage - * - Byte array holding whole message data. - * @param offset - * - Offset to session ID in header. - * @return Session ID. - */ - protected static int decodeSessionID(byte[] rawMessage, int offset) { - return decodeInt(rawMessage, offset); - } - - /** - * Decodes payload length. - * - * @param rawData - * - Byte array holding whole message data. - * @param offset - * - Offset to payload length in header. - * @return payload length. - */ - protected abstract int decodePayloadLength(byte[] rawData, int offset); - - /** - * Decodes payload. - * - * @param rawData - * - Byte array holding whole message data. - * @param offset - * - Offset to payload. - * @param length - * - Length of the payload. - * @param confidentialityAlgorithm - * - {@link ConfidentialityAlgorithm} required to decrypt - * payload. - * @return Payload decoded into {@link IpmiLanResponse}. - */ - protected IpmiPayload decodePayload(byte[] rawData, int offset, int length, - ConfidentialityAlgorithm confidentialityAlgorithm, PayloadType payloadType) { - byte[] payload = null; - if (length > 0) { - payload = new byte[length]; - - System.arraycopy(rawData, offset, payload, 0, length); - - payload = confidentialityAlgorithm.decrypt(payload); - } - - if (payloadType == PayloadType.Sol) { - return new SolInboundMessage(payload); - } else { - return new IpmiLanResponse(payload); - } - } + public ProtocolDecoder() { + + } + + /** + * Decodes IPMI message version independent fields. + * + * @param rmcpMessage + * - RMCP message to decode. + * @param message + * - A reference to message being decoded. + * @param sequenceNumberOffset + * - Protocol version specific offset to Session Sequence Number + * field in the header of the IPMI message. + * @param payloadLengthOffset + * - Protocol version specific offset to IPMI Payload Length + * field in the header of the IPMI message. + * @param payloadLengthLength + * - Length of the payload length field. + * @see IpmiMessage + * @return Offset to the session trailer. + * @throws IllegalArgumentException + * when delivered RMCP message does not contain encapsulated + * IPMI message. + * @deprecated this method is obolete. use {@link ProtocolDecoder#decode(RmcpMessage)} instead + */ + @Deprecated + protected int decode( + RmcpMessage rmcpMessage, + IpmiMessage message, + int sequenceNumberOffset, + int payloadLengthOffset, + int payloadLengthLength) { + + if (rmcpMessage.getClassOfMessage() != RmcpClassOfMessage.Ipmi) { + throw new IllegalArgumentException("This is not an IPMI message"); + } + + byte[] raw = rmcpMessage.getData(); + + message.setAuthenticationType(decodeAuthenticationType(raw[0])); + + message + .setSessionSequenceNumber( + decodeSessionSequenceNumber( + raw, + sequenceNumberOffset)); + + message.setPayloadLength(decodePayloadLength(raw, payloadLengthOffset)); + + message + .setPayload( + decodePayload( + raw, + payloadLengthOffset + + payloadLengthLength, + message.getPayloadLength(), + message.getConfidentialityAlgorithm(), + PayloadType.Ipmi)); + + return payloadLengthOffset + payloadLengthLength + + message.getPayloadLength(); + } + + protected static AuthenticationType decodeAuthenticationType(byte authenticationType) { + authenticationType &= TypeConverter.intToByte(0x0f); + + return AuthenticationType + .parseInt( + TypeConverter + .byteToInt(authenticationType)); + } + + /** + * Decodes {@link AuthenticationType} of the message so that the version of + * the IPMI protocol could be determined. + * + * @param message + * - RMCP message to decode. + * @return {@link AuthenticationType} of the message. + */ + public static AuthenticationType decodeAuthenticationType( + RmcpMessage message) { + return decodeAuthenticationType(message.getData()[0]); + } + + /** + * Decodes int in a little endian convention from raw message at given + * offset + * + * @param rawMessage + * - Raw message to be decoded + * @param offset + * @return Decoded integer + */ + protected static int decodeInt(byte[] rawMessage, int offset) { + byte[] result = new byte[4]; + + System.arraycopy(rawMessage, offset, result, 0, 4); + + return TypeConverter.littleEndianByteArrayToInt(result); + } + + /** + * Decodes session sequence number. + * + * @param rawMessage + * - Byte array holding whole message data. + * @param offset + * - Offset to session sequence number in header. + * @return Session Sequence number. + */ + protected int decodeSessionSequenceNumber(byte[] rawMessage, int offset) { + return decodeInt(rawMessage, offset); + } + + /** + * Decodes session ID. + * + * @param rawMessage + * - Byte array holding whole message data. + * @param offset + * - Offset to session ID in header. + * @return Session ID. + */ + protected static int decodeSessionID(byte[] rawMessage, int offset) { + return decodeInt(rawMessage, offset); + } + + /** + * Decodes payload length. + * + * @param rawData + * - Byte array holding whole message data. + * @param offset + * - Offset to payload length in header. + * @return payload length. + */ + protected abstract int decodePayloadLength(byte[] rawData, int offset); + + /** + * Decodes payload. + * + * @param rawData + * - Byte array holding whole message data. + * @param offset + * - Offset to payload. + * @param length + * - Length of the payload. + * @param confidentialityAlgorithm + * - {@link ConfidentialityAlgorithm} required to decrypt + * payload. + * @return Payload decoded into {@link IpmiLanResponse}. + */ + protected IpmiPayload decodePayload( + byte[] rawData, + int offset, + int length, + ConfidentialityAlgorithm confidentialityAlgorithm, + PayloadType payloadType) { + byte[] payload = null; + if (length > 0) { + payload = new byte[length]; + + System.arraycopy(rawData, offset, payload, 0, length); + + payload = confidentialityAlgorithm.decrypt(payload); + } + + if (payloadType == PayloadType.Sol) { + return new SolInboundMessage(payload); + } else { + return new IpmiLanResponse(payload); + } + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/protocol/decoder/Protocolv15Decoder.java b/src/main/java/org/metricshub/ipmi/core/coding/protocol/decoder/Protocolv15Decoder.java index 2521b65..114085b 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/protocol/decoder/Protocolv15Decoder.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/protocol/decoder/Protocolv15Decoder.java @@ -34,75 +34,84 @@ */ public class Protocolv15Decoder extends ProtocolDecoder { - public Protocolv15Decoder() { - super(); - } - - /** - * Decodes IPMI v1.5 message fields. - * - * @param rmcpMessage - * - RMCP message to decode. - * @return decoded message - * @see Ipmiv15Message - * @throws IllegalArgumentException - * when delivered RMCP message does not contain encapsulated - * IPMI message. - */ - @Override - public IpmiMessage decode(RmcpMessage rmcpMessage) { - Ipmiv15Message message = new Ipmiv15Message(); - - byte[] raw = rmcpMessage.getData(); - - message.setAuthenticationType(decodeAuthenticationType(raw[0])); - - int offset = 1; - - message.setSessionSequenceNumber(decodeSessionSequenceNumber(raw, - offset)); - - offset += 4; - - message.setSessionID(decodeSessionID(raw, offset)); - - offset += 4; - - if (message.getAuthenticationType() != AuthenticationType.None) { - message.setAuthCode(decodeAuthCode(raw, offset)); - offset += 16; - } - - int payloadLength = decodePayloadLength(raw, offset); - - message.setPayloadLength(payloadLength); - ++offset; - - message.setPayload(decodePayload(raw, offset, payloadLength, - message.getConfidentialityAlgorithm(), PayloadType.Ipmi)); - - return message; - } - - /** - * Decodes authentication code. - * - * @param rawMessage - * - Byte array holding whole message data. - * @param offset - * - Offset to authentication code in header. - * @return authentication code. - */ - private byte[] decodeAuthCode(byte[] rawMessage, int offset) { - byte[] authCode = new byte[16]; - - System.arraycopy(rawMessage, offset, authCode, 0, 16); - - return authCode; - } - - @Override - protected int decodePayloadLength(byte[] rawData, int offset) { - return TypeConverter.byteToInt(rawData[offset]); - } + public Protocolv15Decoder() { + super(); + } + + /** + * Decodes IPMI v1.5 message fields. + * + * @param rmcpMessage + * - RMCP message to decode. + * @return decoded message + * @see Ipmiv15Message + * @throws IllegalArgumentException + * when delivered RMCP message does not contain encapsulated + * IPMI message. + */ + @Override + public IpmiMessage decode(RmcpMessage rmcpMessage) { + Ipmiv15Message message = new Ipmiv15Message(); + + byte[] raw = rmcpMessage.getData(); + + message.setAuthenticationType(decodeAuthenticationType(raw[0])); + + int offset = 1; + + message + .setSessionSequenceNumber( + decodeSessionSequenceNumber( + raw, + offset)); + + offset += 4; + + message.setSessionID(decodeSessionID(raw, offset)); + + offset += 4; + + if (message.getAuthenticationType() != AuthenticationType.None) { + message.setAuthCode(decodeAuthCode(raw, offset)); + offset += 16; + } + + int payloadLength = decodePayloadLength(raw, offset); + + message.setPayloadLength(payloadLength); + ++offset; + + message + .setPayload( + decodePayload( + raw, + offset, + payloadLength, + message.getConfidentialityAlgorithm(), + PayloadType.Ipmi)); + + return message; + } + + /** + * Decodes authentication code. + * + * @param rawMessage + * - Byte array holding whole message data. + * @param offset + * - Offset to authentication code in header. + * @return authentication code. + */ + private byte[] decodeAuthCode(byte[] rawMessage, int offset) { + byte[] authCode = new byte[16]; + + System.arraycopy(rawMessage, offset, authCode, 0, 16); + + return authCode; + } + + @Override + protected int decodePayloadLength(byte[] rawData, int offset) { + return TypeConverter.byteToInt(rawData[offset]); + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/protocol/decoder/Protocolv20Decoder.java b/src/main/java/org/metricshub/ipmi/core/coding/protocol/decoder/Protocolv20Decoder.java index cb8693f..8e2910c 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/protocol/decoder/Protocolv20Decoder.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/protocol/decoder/Protocolv20Decoder.java @@ -31,7 +31,6 @@ import org.metricshub.ipmi.core.coding.security.ConfidentialityNone; import org.metricshub.ipmi.core.common.TypeConverter; - import java.security.InvalidKeyException; import java.util.Arrays; @@ -43,249 +42,273 @@ */ public class Protocolv20Decoder extends ProtocolDecoder { - private static Logger logger = LoggerFactory.getLogger(Protocolv20Decoder.class); - - private CipherSuite cipherSuite; - - /** - * Initiates IPMI v2.0 packet decoder. - * - * @param cipherSuite - * - {@link CipherSuite} that will be used to decode the message - */ - public Protocolv20Decoder(CipherSuite cipherSuite) { - super(); - this.cipherSuite = cipherSuite; - } - - /** - * Decodes IPMI v2.0 message fields. - * - * @param rmcpMessage - * - RMCP message to decode. - * @return decoded message - * @see Ipmiv20Message - * @throws IllegalArgumentException - * when delivered RMCP message does not contain encapsulated - * IPMI message or when AuthCode field is incorrect (integrity - * check fails). - * @throws InvalidKeyException - * - when initiation of the integrity algorithm fails - */ - @Override - public IpmiMessage decode(RmcpMessage rmcpMessage) throws InvalidKeyException { - Ipmiv20Message message = new Ipmiv20Message( - cipherSuite.getConfidentialityAlgorithm()); - - byte[] raw = rmcpMessage.getData(); - - message.setAuthenticationType(decodeAuthenticationType(raw[0])); - - message.setPayloadEncrypted(decodeEncryption(raw[1])); - - message.setPayloadAuthenticated(decodeAuthentication(raw[1])); - - message.setPayloadType(decodePayloadType(raw[1])); - - int offset = 2; - - if (message.getPayloadType() == PayloadType.Oem) { - message.setOemIANA(decodeOEMIANA(raw)); - offset += 4; - - message.setOemPayloadID(decodeOEMPayloadId(raw, offset)); - offset += 2; - } - - message.setSessionID(decodeSessionID(raw, offset)); - offset += 4; - - message.setSessionSequenceNumber(decodeSessionSequenceNumber(raw, - offset)); - offset += 4; - - int payloadLength = decodePayloadLength(raw, offset); - offset += 2; - - if (message.isPayloadEncrypted()) { - message.setPayload(decodePayload(raw, offset, payloadLength, - message.getConfidentialityAlgorithm(), message.getPayloadType())); - } else { - message.setPayload(decodePayload(raw, offset, payloadLength, - new ConfidentialityNone(), message.getPayloadType())); - } - - offset += payloadLength; - - if (message.getAuthenticationType() != AuthenticationType.None - && !(message.getAuthenticationType() == AuthenticationType.RMCPPlus && !message - .isPayloadAuthenticated()) - && message.getSessionID() != 0) { - offset = skipIntegrityPAD(raw, offset); - message.setAuthCode(decodeAuthCode(raw, offset)); - if (!validateAuthCode(raw, offset)) { - logger.warn("Integrity check failed"); - } - } - - return message; - } - - /** - * Decodes first bit of Payload Type. - * - * @param payloadType - * @return True if payload is encrypted, false otherwise. - */ - private boolean decodeEncryption(byte payloadType) { - return (payloadType & TypeConverter.intToByte(0x80)) != 0; - } - - /** - * Decodes second bit of Payload Type. - * - * @param payloadType - * @return True if payload is authenticated, false otherwise. - */ - public boolean decodeAuthentication(byte payloadType) { - return (payloadType & TypeConverter.intToByte(0x40)) != 0; - } - - public static PayloadType decodePayloadType(byte payloadType) { - return PayloadType.parseInt(TypeConverter.intToByte(payloadType - & TypeConverter.intToByte(0x3f))); - } - - /** - * Decodes OEM IANA. - * - * @param rawMessage - * - Byte array holding whole message data. - * @return OEM IANA number. - */ - private int decodeOEMIANA(byte[] rawMessage) { - byte[] oemIANA = new byte[4]; - - System.arraycopy(rawMessage, 3, oemIANA, 0, 3); - oemIANA[3] = 0; - - return TypeConverter.littleEndianByteArrayToInt(oemIANA); - } - - /** - * Decodes OEM payload ID. To implement manufacturer-specific OEM Payload ID - * decoding, override this function. - * - * @param rawMessage - * - Byte array holding whole message data. - * @param offset - * - Offset to OEM payload ID in header. - * @return Decoded OEM payload ID. - */ - protected Object decodeOEMPayloadId(byte[] rawMessage, int offset) { - byte[] oemPayload = new byte[2]; - - System.arraycopy(rawMessage, offset, oemPayload, 0, 2); - - return oemPayload; - } - - @Override - protected int decodePayloadLength(byte[] rawData, int offset) { - byte[] payloadLength = new byte[4]; - System.arraycopy(rawData, offset, payloadLength, 0, 2); - payloadLength[2] = 0; - payloadLength[3] = 0; - - return TypeConverter.littleEndianByteArrayToInt(payloadLength); - } - - /** - * Skips the integrity pad and pad length fields. - * - * @param rawMessage - * - Byte array holding whole message data. - * @param offset - * - Offset to integrity pad. - * @return Offset to Auth Code - * @throws IndexOutOfBoundsException - * when message is corrupted and pad length does not appear - * after integrity pad or length is incorrect. - */ - private int skipIntegrityPAD(final byte[] rawMessage, final int offset) { - int skip = 0; - while (TypeConverter.byteToInt(rawMessage[offset + skip]) == 0xff) { - ++skip; - } - int length = TypeConverter.byteToInt(rawMessage[offset + skip]); - if (length != skip) { - throw new IndexOutOfBoundsException("Message is corrupted."); - } - - int currentOffset = offset + skip + 2; // skip pad length and next header fields - if (currentOffset >= rawMessage.length) { - throw new IndexOutOfBoundsException("Message is corrupted."); - } - return currentOffset; - } - - /** - * Decodes the Auth Code. - * - * @param rawMessage - * - Byte array holding whole message data. - * @param offset - * - Offset to auth code. - * @return Auth Code - * @throws IndexOutOfBoundsException - * when message is corrupted and pad length does not appear - * after integrity pad or length is incorrect. - */ - private byte[] decodeAuthCode(byte[] rawMessage, int offset) { - byte[] authCode = new byte[rawMessage.length - offset]; - System.arraycopy(rawMessage, offset, authCode, 0, authCode.length); - return authCode; - } - - /** - * Checks if Auth Code of the received message is valid - * - * @param rawMessage - * - received message - * @param offset - * - offset to the AuthCode field in the message - * @return True if AuthCode is correct, false otherwise. - * @throws InvalidKeyException - * - when initiation of the integrity algorithm fails - */ - private boolean validateAuthCode(byte[] rawMessage, int offset) { - byte[] base = new byte[offset]; - - System.arraycopy(rawMessage, 0, base, 0, offset); - - byte[] authCode = null; - - if (rawMessage.length > offset) { - authCode = new byte[rawMessage.length - offset]; - System.arraycopy(rawMessage, offset, authCode, 0, authCode.length); - } - - return Arrays.equals(authCode, cipherSuite.getIntegrityAlgorithm() - .generateAuthCode(base)); - } - - /** - * Decodes session ID. - * - * @param message - * - message to get session ID from - * @return Session ID. - */ - public static int decodeSessionID(RmcpMessage message) { - int offset = 2; - if (decodePayloadType(message.getData()[1]) == PayloadType.Oem) { - offset += 6; - } - return decodeSessionID(message.getData(), offset); - } + private static Logger logger = LoggerFactory.getLogger(Protocolv20Decoder.class); + + private CipherSuite cipherSuite; + + /** + * Initiates IPMI v2.0 packet decoder. + * + * @param cipherSuite + * - {@link CipherSuite} that will be used to decode the message + */ + public Protocolv20Decoder(CipherSuite cipherSuite) { + super(); + this.cipherSuite = cipherSuite; + } + + /** + * Decodes IPMI v2.0 message fields. + * + * @param rmcpMessage + * - RMCP message to decode. + * @return decoded message + * @see Ipmiv20Message + * @throws IllegalArgumentException + * when delivered RMCP message does not contain encapsulated + * IPMI message or when AuthCode field is incorrect (integrity + * check fails). + * @throws InvalidKeyException + * - when initiation of the integrity algorithm fails + */ + @Override + public IpmiMessage decode(RmcpMessage rmcpMessage) throws InvalidKeyException { + Ipmiv20Message message = new Ipmiv20Message( + cipherSuite.getConfidentialityAlgorithm()); + + byte[] raw = rmcpMessage.getData(); + + message.setAuthenticationType(decodeAuthenticationType(raw[0])); + + message.setPayloadEncrypted(decodeEncryption(raw[1])); + + message.setPayloadAuthenticated(decodeAuthentication(raw[1])); + + message.setPayloadType(decodePayloadType(raw[1])); + + int offset = 2; + + if (message.getPayloadType() == PayloadType.Oem) { + message.setOemIANA(decodeOEMIANA(raw)); + offset += 4; + + message.setOemPayloadID(decodeOEMPayloadId(raw, offset)); + offset += 2; + } + + message.setSessionID(decodeSessionID(raw, offset)); + offset += 4; + + message + .setSessionSequenceNumber( + decodeSessionSequenceNumber( + raw, + offset)); + offset += 4; + + int payloadLength = decodePayloadLength(raw, offset); + offset += 2; + + if (message.isPayloadEncrypted()) { + message + .setPayload( + decodePayload( + raw, + offset, + payloadLength, + message.getConfidentialityAlgorithm(), + message.getPayloadType())); + } else { + message + .setPayload( + decodePayload( + raw, + offset, + payloadLength, + new ConfidentialityNone(), + message.getPayloadType())); + } + + offset += payloadLength; + + if (message.getAuthenticationType() != AuthenticationType.None + && !(message.getAuthenticationType() == AuthenticationType.RMCPPlus + && !message + .isPayloadAuthenticated()) + && message.getSessionID() != 0) { + offset = skipIntegrityPAD(raw, offset); + message.setAuthCode(decodeAuthCode(raw, offset)); + if (!validateAuthCode(raw, offset)) { + logger.warn("Integrity check failed"); + } + } + + return message; + } + + /** + * Decodes first bit of Payload Type. + * + * @param payloadType + * @return True if payload is encrypted, false otherwise. + */ + private boolean decodeEncryption(byte payloadType) { + return (payloadType & TypeConverter.intToByte(0x80)) != 0; + } + + /** + * Decodes second bit of Payload Type. + * + * @param payloadType + * @return True if payload is authenticated, false otherwise. + */ + public boolean decodeAuthentication(byte payloadType) { + return (payloadType & TypeConverter.intToByte(0x40)) != 0; + } + + public static PayloadType decodePayloadType(byte payloadType) { + return PayloadType + .parseInt( + TypeConverter + .intToByte( + payloadType + & TypeConverter.intToByte(0x3f))); + } + + /** + * Decodes OEM IANA. + * + * @param rawMessage + * - Byte array holding whole message data. + * @return OEM IANA number. + */ + private int decodeOEMIANA(byte[] rawMessage) { + byte[] oemIANA = new byte[4]; + + System.arraycopy(rawMessage, 3, oemIANA, 0, 3); + oemIANA[3] = 0; + + return TypeConverter.littleEndianByteArrayToInt(oemIANA); + } + + /** + * Decodes OEM payload ID. To implement manufacturer-specific OEM Payload ID + * decoding, override this function. + * + * @param rawMessage + * - Byte array holding whole message data. + * @param offset + * - Offset to OEM payload ID in header. + * @return Decoded OEM payload ID. + */ + protected Object decodeOEMPayloadId(byte[] rawMessage, int offset) { + byte[] oemPayload = new byte[2]; + + System.arraycopy(rawMessage, offset, oemPayload, 0, 2); + + return oemPayload; + } + + @Override + protected int decodePayloadLength(byte[] rawData, int offset) { + byte[] payloadLength = new byte[4]; + System.arraycopy(rawData, offset, payloadLength, 0, 2); + payloadLength[2] = 0; + payloadLength[3] = 0; + + return TypeConverter.littleEndianByteArrayToInt(payloadLength); + } + + /** + * Skips the integrity pad and pad length fields. + * + * @param rawMessage + * - Byte array holding whole message data. + * @param offset + * - Offset to integrity pad. + * @return Offset to Auth Code + * @throws IndexOutOfBoundsException + * when message is corrupted and pad length does not appear + * after integrity pad or length is incorrect. + */ + private int skipIntegrityPAD(final byte[] rawMessage, final int offset) { + int skip = 0; + while (TypeConverter.byteToInt(rawMessage[offset + skip]) == 0xff) { + ++skip; + } + int length = TypeConverter.byteToInt(rawMessage[offset + skip]); + if (length != skip) { + throw new IndexOutOfBoundsException("Message is corrupted."); + } + + int currentOffset = offset + skip + 2; // skip pad length and next header fields + if (currentOffset >= rawMessage.length) { + throw new IndexOutOfBoundsException("Message is corrupted."); + } + return currentOffset; + } + + /** + * Decodes the Auth Code. + * + * @param rawMessage + * - Byte array holding whole message data. + * @param offset + * - Offset to auth code. + * @return Auth Code + * @throws IndexOutOfBoundsException + * when message is corrupted and pad length does not appear + * after integrity pad or length is incorrect. + */ + private byte[] decodeAuthCode(byte[] rawMessage, int offset) { + byte[] authCode = new byte[rawMessage.length - offset]; + System.arraycopy(rawMessage, offset, authCode, 0, authCode.length); + return authCode; + } + + /** + * Checks if Auth Code of the received message is valid + * + * @param rawMessage + * - received message + * @param offset + * - offset to the AuthCode field in the message + * @return True if AuthCode is correct, false otherwise. + * @throws InvalidKeyException + * - when initiation of the integrity algorithm fails + */ + private boolean validateAuthCode(byte[] rawMessage, int offset) { + byte[] base = new byte[offset]; + + System.arraycopy(rawMessage, 0, base, 0, offset); + + byte[] authCode = null; + + if (rawMessage.length > offset) { + authCode = new byte[rawMessage.length - offset]; + System.arraycopy(rawMessage, offset, authCode, 0, authCode.length); + } + + return Arrays + .equals( + authCode, + cipherSuite + .getIntegrityAlgorithm() + .generateAuthCode(base)); + } + + /** + * Decodes session ID. + * + * @param message + * - message to get session ID from + * @return Session ID. + */ + public static int decodeSessionID(RmcpMessage message) { + int offset = 2; + if (decodePayloadType(message.getData()[1]) == PayloadType.Oem) { + offset += 6; + } + return decodeSessionID(message.getData(), offset); + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/protocol/decoder/package-info.java b/src/main/java/org/metricshub/ipmi/core/coding/protocol/decoder/package-info.java index 32d97a7..de93501 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/protocol/decoder/package-info.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/protocol/decoder/package-info.java @@ -1,6 +1,7 @@ /** - * IPMI protocol decoder classes. - * To implement custom IPMI protocol decoder implement {@link org.metricshub.ipmi.core.coding.protocol.decoder.IpmiDecoder} interface. + * IPMI protocol decoder classes. + * To implement custom IPMI protocol decoder implement + * {@link org.metricshub.ipmi.core.coding.protocol.decoder.IpmiDecoder} interface. */ package org.metricshub.ipmi.core.coding.protocol.decoder; /*- diff --git a/src/main/java/org/metricshub/ipmi/core/coding/protocol/encoder/IpmiEncoder.java b/src/main/java/org/metricshub/ipmi/core/coding/protocol/encoder/IpmiEncoder.java index bf0602a..435e0a8 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/protocol/encoder/IpmiEncoder.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/protocol/encoder/IpmiEncoder.java @@ -30,14 +30,15 @@ * Encodes IPMI message. */ public interface IpmiEncoder { - /** - * Encodes IPMI message. - * @param ipmiMessage - * - IPMI message to encode. - * @return IPMI message encoded into byte array. - * @throws InvalidKeyException - * - when initiation of the confidentiality algorithm fails - * @see IpmiMessage - */ - byte[] encode(IpmiMessage ipmiMessage) throws InvalidKeyException; + /** + * Encodes IPMI message. + * + * @param ipmiMessage + * - IPMI message to encode. + * @return IPMI message encoded into byte array. + * @throws InvalidKeyException + * - when initiation of the confidentiality algorithm fails + * @see IpmiMessage + */ + byte[] encode(IpmiMessage ipmiMessage) throws InvalidKeyException; } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/protocol/encoder/ProtocolEncoder.java b/src/main/java/org/metricshub/ipmi/core/coding/protocol/encoder/ProtocolEncoder.java index 90b70bb..4980e02 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/protocol/encoder/ProtocolEncoder.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/protocol/encoder/ProtocolEncoder.java @@ -31,94 +31,94 @@ */ public abstract class ProtocolEncoder implements IpmiEncoder { - protected byte encodeAuthenticationType( - AuthenticationType authenticationType) { - return TypeConverter.intToByte(authenticationType.getCode()); - } + protected byte encodeAuthenticationType( + AuthenticationType authenticationType) { + return TypeConverter.intToByte(authenticationType.getCode()); + } - /** - * Converts integer value into byte array using little endian convention and - * inserts it into message at given offset. - * - * @param value - * @param message - * - IPMI message being created - * @param offset - * @throws IndexOutOfBoundsException - * when message is too short to hold value at given offset - */ - protected void encodeInt(int value, byte[] message, int offset) { - byte[] array = TypeConverter.intToLittleEndianByteArray(value); + /** + * Converts integer value into byte array using little endian convention and + * inserts it into message at given offset. + * + * @param value + * @param message + * - IPMI message being created + * @param offset + * @throws IndexOutOfBoundsException + * when message is too short to hold value at given offset + */ + protected void encodeInt(int value, byte[] message, int offset) { + byte[] array = TypeConverter.intToLittleEndianByteArray(value); - if (array.length + offset > message.length) { - throw new IndexOutOfBoundsException("Message is too short"); - } + if (array.length + offset > message.length) { + throw new IndexOutOfBoundsException("Message is too short"); + } - System.arraycopy(array, 0, message, offset, array.length); - } + System.arraycopy(array, 0, message, offset, array.length); + } - /** - * Encodes session sequence number and inserts it into message at given - * offset. - * - * @param value - * @param message - * - IPMI message being created - * @param offset - * @throws IndexOutOfBoundsException - * when message is too short to hold value at given offset - */ - protected void encodeSessionSequenceNumber(int value, byte[] message, int offset) { - encodeInt(value, message, offset); - } + /** + * Encodes session sequence number and inserts it into message at given + * offset. + * + * @param value + * @param message + * - IPMI message being created + * @param offset + * @throws IndexOutOfBoundsException + * when message is too short to hold value at given offset + */ + protected void encodeSessionSequenceNumber(int value, byte[] message, int offset) { + encodeInt(value, message, offset); + } - /** - * Encodes session id and inserts it into message at given offset. - * - * @param value - * @param message - * - IPMI message being created - * @param offset - * @throws IndexOutOfBoundsException - * when message is too short to hold value at given offset - */ - protected void encodeSessionId(int value, byte[] message, int offset) { - encodeInt(value, message, offset); - } + /** + * Encodes session id and inserts it into message at given offset. + * + * @param value + * @param message + * - IPMI message being created + * @param offset + * @throws IndexOutOfBoundsException + * when message is too short to hold value at given offset + */ + protected void encodeSessionId(int value, byte[] message, int offset) { + encodeInt(value, message, offset); + } - /** - * Encodes payload length and inserts it into message at given offset. - * - * @param value - * @param message - * - IPMI message being created - * @param offset - * @throws IndexOutOfBoundsException - * when message is too short to hold value at given offset - */ - protected abstract void encodePayloadLength(int value, byte[] message, int offset); + /** + * Encodes payload length and inserts it into message at given offset. + * + * @param value + * @param message + * - IPMI message being created + * @param offset + * @throws IndexOutOfBoundsException + * when message is too short to hold value at given offset + */ + protected abstract void encodePayloadLength(int value, byte[] message, int offset); - /** - * Encodes payload and inserts it into message at given offset.
- * When payload == null it will not be inserted. - * - * @param payload - * - IPMI payload to encode. - * @param message - * - IPMI message being created. - * @param offset - * @throws IndexOutOfBoundsException - * when message is too short to hold value at given offset - * @return offset + encoded message length - */ - protected int encodePayload(byte[] payload, byte[] message, int offset) { - if (payload == null) { - return offset; - } - if (payload.length + offset > message.length) { - throw new IndexOutOfBoundsException("Message is too short"); - } - System.arraycopy(payload, 0, message, offset, payload.length); - return offset + payload.length; - } + /** + * Encodes payload and inserts it into message at given offset.
+ * When payload == null it will not be inserted. + * + * @param payload + * - IPMI payload to encode. + * @param message + * - IPMI message being created. + * @param offset + * @throws IndexOutOfBoundsException + * when message is too short to hold value at given offset + * @return offset + encoded message length + */ + protected int encodePayload(byte[] payload, byte[] message, int offset) { + if (payload == null) { + return offset; + } + if (payload.length + offset > message.length) { + throw new IndexOutOfBoundsException("Message is too short"); + } + System.arraycopy(payload, 0, message, offset, payload.length); + return offset + payload.length; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/protocol/encoder/Protocolv15Encoder.java b/src/main/java/org/metricshub/ipmi/core/coding/protocol/encoder/Protocolv15Encoder.java index 8b4db5b..1bbd48d 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/protocol/encoder/Protocolv15Encoder.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/protocol/encoder/Protocolv15Encoder.java @@ -34,114 +34,119 @@ */ public class Protocolv15Encoder extends ProtocolEncoder { - /** - * @param ipmiMessage - * - IPMI message to be encoded. Must be {@link Ipmiv15Message}. - * @throws InvalidKeyException - * - when initiation of the confidentiality algorithm fails - * @throws IllegalArgumentException - * when IPMI protocol version is incorrect. - * @see Ipmiv15Message - */ - @Override - public byte[] encode(IpmiMessage ipmiMessage) throws InvalidKeyException { - if (!(ipmiMessage instanceof Ipmiv15Message)) { - throw new IllegalArgumentException( - "IPMIMessage must be in 1.5 version."); - } - Ipmiv15Message message = (Ipmiv15Message) ipmiMessage; - - byte[] raw = new byte[getMessageLength(message)]; - - raw[0] = encodeAuthenticationType(message.getAuthenticationType()); - - int offset = 1; - - encodeSessionSequenceNumber(message.getSessionSequenceNumber(), raw, - offset); - offset += 4; - - encodeSessionId(message.getSessionID(), raw, offset); - offset += 4; - - if (message.getAuthenticationType() != AuthenticationType.None) { - encodeAuthenticationCode(message.getAuthCode(), raw, offset); - offset += message.getAuthCode().length; - } - - byte[] payload = message.getPayload().getEncryptedPayload(); - - if (payload == null) { - message.getPayload().encryptPayload( - message.getConfidentialityAlgorithm()); - payload = message.getPayload().getEncryptedPayload(); - } - - encodePayloadLength(payload.length, raw, offset); - ++offset; - - offset = encodePayload(payload, raw, offset); - - encodeSessionTrailer(raw, offset); - - return raw; - } - - private int getMessageLength(IpmiMessage ipmiMessage) { - int length = 11 - + ipmiMessage.getConfidentialityAlgorithm() - .getConfidentialityOverheadSize( - ipmiMessage.getPayloadLength()) - + ipmiMessage.getPayloadLength(); - - if (ipmiMessage.getAuthenticationType() != AuthenticationType.None) { - length += 16; - } - - return length; - } - - /** - * Inserts authentication code into message at given offset. - * - * @param authCode - * @param message - * - message being encoded - * @param offset - * @throws IndexOutOfBoundsException - * when message is too short to hold value at given offset - */ - private void encodeAuthenticationCode(byte[] authCode, byte[] message, int offset) { - if (authCode.length + offset > message.length) { - throw new IndexOutOfBoundsException("Message is too short"); - } - System.arraycopy(authCode, 0, message, offset, authCode.length); - } - - @Override - protected void encodePayloadLength(int value, byte[] message, int offset) { - message[offset] = TypeConverter.intToByte(value); - } - - /** - * Creates session trailer.
- * Creates an inserts Legacy PAD. - * - * @param message - * - IPMI message being created - * @param offset - * - Should point at the beginning of the session trailer. - * @throws IndexOutOfBoundsException - * when message is too short to hold value at given offset - * @return Offset pointing after Authorization Code - */ - private int encodeSessionTrailer(byte[] message, int offset) { - if (1 + offset > message.length) { - throw new IndexOutOfBoundsException("Message is too short"); - } - - message[offset] = 0; - - return offset + 1; - } + /** + * @param ipmiMessage + * - IPMI message to be encoded. Must be {@link Ipmiv15Message}. + * @throws InvalidKeyException + * - when initiation of the confidentiality algorithm fails + * @throws IllegalArgumentException + * when IPMI protocol version is incorrect. + * @see Ipmiv15Message + */ + @Override + public byte[] encode(IpmiMessage ipmiMessage) throws InvalidKeyException { + if (!(ipmiMessage instanceof Ipmiv15Message)) { + throw new IllegalArgumentException( + "IPMIMessage must be in 1.5 version."); + } + Ipmiv15Message message = (Ipmiv15Message) ipmiMessage; + + byte[] raw = new byte[getMessageLength(message)]; + + raw[0] = encodeAuthenticationType(message.getAuthenticationType()); + + int offset = 1; + + encodeSessionSequenceNumber( + message.getSessionSequenceNumber(), + raw, + offset); + offset += 4; + + encodeSessionId(message.getSessionID(), raw, offset); + offset += 4; + + if (message.getAuthenticationType() != AuthenticationType.None) { + encodeAuthenticationCode(message.getAuthCode(), raw, offset); + offset += message.getAuthCode().length; + } + + byte[] payload = message.getPayload().getEncryptedPayload(); + + if (payload == null) { + message + .getPayload() + .encryptPayload( + message.getConfidentialityAlgorithm()); + payload = message.getPayload().getEncryptedPayload(); + } + + encodePayloadLength(payload.length, raw, offset); + ++offset; + + offset = encodePayload(payload, raw, offset); + + encodeSessionTrailer(raw, offset); + + return raw; + } + + private int getMessageLength(IpmiMessage ipmiMessage) { + int length = 11 + + ipmiMessage + .getConfidentialityAlgorithm() + .getConfidentialityOverheadSize( + ipmiMessage.getPayloadLength()) + + ipmiMessage.getPayloadLength(); + + if (ipmiMessage.getAuthenticationType() != AuthenticationType.None) { + length += 16; + } + + return length; + } + + /** + * Inserts authentication code into message at given offset. + * + * @param authCode + * @param message + * - message being encoded + * @param offset + * @throws IndexOutOfBoundsException + * when message is too short to hold value at given offset + */ + private void encodeAuthenticationCode(byte[] authCode, byte[] message, int offset) { + if (authCode.length + offset > message.length) { + throw new IndexOutOfBoundsException("Message is too short"); + } + System.arraycopy(authCode, 0, message, offset, authCode.length); + } + + @Override + protected void encodePayloadLength(int value, byte[] message, int offset) { + message[offset] = TypeConverter.intToByte(value); + } + + /** + * Creates session trailer.
+ * Creates an inserts Legacy PAD. + * + * @param message + * - IPMI message being created + * @param offset + * - Should point at the beginning of the session trailer. + * @throws IndexOutOfBoundsException + * when message is too short to hold value at given offset + * @return Offset pointing after Authorization Code + */ + private int encodeSessionTrailer(byte[] message, int offset) { + if (1 + offset > message.length) { + throw new IndexOutOfBoundsException("Message is too short"); + } + + message[offset] = 0; + + return offset + 1; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/protocol/encoder/Protocolv20Encoder.java b/src/main/java/org/metricshub/ipmi/core/coding/protocol/encoder/Protocolv20Encoder.java index 15614de..7830bd8 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/protocol/encoder/Protocolv20Encoder.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/protocol/encoder/Protocolv20Encoder.java @@ -34,226 +34,235 @@ * Encodes IPMI v2.0 message. */ public class Protocolv20Encoder extends ProtocolEncoder { - /** - * @param ipmiMessage - * - IPMI message to be encoded. Must be {@link Ipmiv20Message}. - * @throws IllegalArgumentException - * when IPMI protocol version or authentication type is - * incorrect. - * @throws InvalidKeyException - * - when initiation of the confidentiality algorithm fails - * @see Ipmiv20Message - */ - @Override - public byte[] encode(IpmiMessage ipmiMessage) throws InvalidKeyException { - if (!(ipmiMessage instanceof Ipmiv20Message)) { - throw new IllegalArgumentException( - "IPMIMessage must be in 2.0 version."); - } - Ipmiv20Message message = (Ipmiv20Message) ipmiMessage; - - byte[] payload = message.getPayload().getEncryptedPayload(); - - if (payload == null) { - message.getPayload().encryptPayload( - message.getConfidentialityAlgorithm()); - payload = message.getPayload().getEncryptedPayload(); - } - - byte[] raw = new byte[getMessageLength(message)]; - - if (message.getAuthenticationType() != AuthenticationType.RMCPPlus) { - throw new IllegalArgumentException( - "Authentication type must be RMCP+ for IPMI v2.0"); - } - - raw[0] = encodeAuthenticationType(message.getAuthenticationType()); - - int offset = 1; - - raw[offset] = encodePayloadType(message.isPayloadEncrypted(), - message.isPayloadAuthenticated(), message.getPayloadType()); - - ++offset; - - if (message.getPayloadType() == PayloadType.Oem) { - encodeOEMIANA(message.getOemIANA(), raw, offset); - offset += 4; - - encodeOEMPayloadId(message.getOemPayloadID(), raw, offset); - offset += 2; - } - - encodeSessionId(message.getSessionID(), raw, offset); - offset += 4; - - encodeSessionSequenceNumber(message.getSessionSequenceNumber(), raw, - offset); - offset += 4; - - encodePayloadLength(payload.length, raw, offset); - offset += 2; - - offset = encodePayload(payload, raw, offset); - - if (message.isPayloadAuthenticated() && message.getSessionID() != 0) { - encodeSessionTrailer(message.getAuthCode(), raw, offset); - } - - return raw; - } - - /** - * Calculates length of the IPMI message. - * - * @param ipmiMessage - * - message which length is to be calculated - */ - private int getMessageLength(Ipmiv20Message ipmiMessage) { - int length = 12 - + ipmiMessage.getConfidentialityAlgorithm() - .getConfidentialityOverheadSize( - ipmiMessage.getPayloadLength()) - + ipmiMessage.getPayloadLength(); - - if (ipmiMessage.getPayloadType() == PayloadType.Oem) { - length += 6; - } - - if (ipmiMessage.isPayloadAuthenticated() - && ipmiMessage.getSessionID() != 0) { - if (ipmiMessage.getAuthCode() != null) { - if ((length + ipmiMessage.getAuthCode().length + 2) % 4 != 0) { - length += 4 - (length + ipmiMessage.getAuthCode().length + 2) % 4; - } - length += ipmiMessage.getAuthCode().length; - } - length += 2; - } - - return length; - } - - private byte encodePayloadType(boolean isEncrypted, - boolean isAuthenticated, PayloadType payloadType) { - byte result = 0; - - if (isEncrypted) { - result |= TypeConverter.intToByte(0x80); - } - - if (isAuthenticated) { - result |= TypeConverter.intToByte(0x40); - } - - result |= TypeConverter.intToByte(payloadType.getCode()); - - return result; - } - - /** - * Encodes OEM IANA and inserts it into message at given offset. - * - * @param value - * @param message - * - IPMI message being created - * @param offset - * @throws IndexOutOfBoundsException - * when message is too short to hold value at given offset - */ - private void encodeOEMIANA(int value, byte[] message, int offset) { - encodeInt(value, message, offset); - } - - /** - * Encodes OEM payload ID and inserts it into message at given offset. To - * implement manufacturer-specific OEM Payload ID encoding, override this - * function. - * - * @param value - * @param message - * - IPMI message being created - * @param offset - * @throws IndexOutOfBoundsException - * when message is too short to hold value at given offset - * @throws IllegalArgumentException - * when value is incorrect. - */ - protected void encodeOEMPayloadId(Object value, byte[] message, int offset) { - byte[] oemId = null; - try { - oemId = (byte[]) value; - } catch (Exception e) { - throw new IllegalArgumentException("Value is corrupted", e); - } - if (oemId.length != 2) { - throw new IllegalArgumentException("Value has invalid length"); - } - if (oemId.length + offset > message.length) { - throw new IndexOutOfBoundsException("Message is too short"); - } - - System.arraycopy(oemId, 0, message, offset, 2); - } - - @Override - protected void encodePayloadLength(int value, byte[] message, int offset) { - byte[] payloadLength = TypeConverter.intToLittleEndianByteArray(value); - message[offset] = payloadLength[0]; - message[offset + 1] = payloadLength[1]; - } - - /** - * Creates session trailer.
- * Encodes Authorization Code and inserts it into message.
- * Adds integrity pad if needed and inserts pad length and next header - * fields. - * - * @param authCode - * - Value of the Authorization Code - * @param message - * - IPMI message being created - * @param offset - * - Should point at the beginning of the session trailer. - * @throws IndexOutOfBoundsException - * when message is too short to hold value at given offset - * @return Offset pointing after Authorization Code - */ - private int encodeSessionTrailer(final byte[] authCode, final byte[] message, final int offset) { - int pad = 0; - - if (authCode != null && authCode.length + offset > message.length) { - throw new IndexOutOfBoundsException("Message is too short"); - } - - if (authCode != null) { - pad = (offset + authCode.length + 2) % 4; - } - - if (pad > 0) { - pad = 4 - pad; - } else { - pad = 0; - } - - int currentOffset = offset; - - for (int i = 0; i < pad; ++i) { - message[currentOffset] = TypeConverter.intToByte(0xff); - ++currentOffset; - } - - message[currentOffset] = TypeConverter.intToByte(pad); - ++currentOffset; - - // Next header - reserved - message[currentOffset] = TypeConverter.intToByte(0x07); - ++currentOffset; - if (authCode != null) { - System.arraycopy(authCode, 0, message, currentOffset, authCode.length); - currentOffset += authCode.length; - } - - return currentOffset; - } + /** + * @param ipmiMessage + * - IPMI message to be encoded. Must be {@link Ipmiv20Message}. + * @throws IllegalArgumentException + * when IPMI protocol version or authentication type is + * incorrect. + * @throws InvalidKeyException + * - when initiation of the confidentiality algorithm fails + * @see Ipmiv20Message + */ + @Override + public byte[] encode(IpmiMessage ipmiMessage) throws InvalidKeyException { + if (!(ipmiMessage instanceof Ipmiv20Message)) { + throw new IllegalArgumentException( + "IPMIMessage must be in 2.0 version."); + } + Ipmiv20Message message = (Ipmiv20Message) ipmiMessage; + + byte[] payload = message.getPayload().getEncryptedPayload(); + + if (payload == null) { + message + .getPayload() + .encryptPayload( + message.getConfidentialityAlgorithm()); + payload = message.getPayload().getEncryptedPayload(); + } + + byte[] raw = new byte[getMessageLength(message)]; + + if (message.getAuthenticationType() != AuthenticationType.RMCPPlus) { + throw new IllegalArgumentException( + "Authentication type must be RMCP+ for IPMI v2.0"); + } + + raw[0] = encodeAuthenticationType(message.getAuthenticationType()); + + int offset = 1; + + raw[offset] = encodePayloadType( + message.isPayloadEncrypted(), + message.isPayloadAuthenticated(), + message.getPayloadType()); + + ++offset; + + if (message.getPayloadType() == PayloadType.Oem) { + encodeOEMIANA(message.getOemIANA(), raw, offset); + offset += 4; + + encodeOEMPayloadId(message.getOemPayloadID(), raw, offset); + offset += 2; + } + + encodeSessionId(message.getSessionID(), raw, offset); + offset += 4; + + encodeSessionSequenceNumber( + message.getSessionSequenceNumber(), + raw, + offset); + offset += 4; + + encodePayloadLength(payload.length, raw, offset); + offset += 2; + + offset = encodePayload(payload, raw, offset); + + if (message.isPayloadAuthenticated() && message.getSessionID() != 0) { + encodeSessionTrailer(message.getAuthCode(), raw, offset); + } + + return raw; + } + + /** + * Calculates length of the IPMI message. + * + * @param ipmiMessage + * - message which length is to be calculated + */ + private int getMessageLength(Ipmiv20Message ipmiMessage) { + int length = 12 + + ipmiMessage + .getConfidentialityAlgorithm() + .getConfidentialityOverheadSize( + ipmiMessage.getPayloadLength()) + + ipmiMessage.getPayloadLength(); + + if (ipmiMessage.getPayloadType() == PayloadType.Oem) { + length += 6; + } + + if (ipmiMessage.isPayloadAuthenticated() + && ipmiMessage.getSessionID() != 0) { + if (ipmiMessage.getAuthCode() != null) { + if ((length + ipmiMessage.getAuthCode().length + 2) % 4 != 0) { + length += 4 - (length + ipmiMessage.getAuthCode().length + 2) % 4; + } + length += ipmiMessage.getAuthCode().length; + } + length += 2; + } + + return length; + } + + private byte encodePayloadType( + boolean isEncrypted, + boolean isAuthenticated, + PayloadType payloadType) { + byte result = 0; + + if (isEncrypted) { + result |= TypeConverter.intToByte(0x80); + } + + if (isAuthenticated) { + result |= TypeConverter.intToByte(0x40); + } + + result |= TypeConverter.intToByte(payloadType.getCode()); + + return result; + } + + /** + * Encodes OEM IANA and inserts it into message at given offset. + * + * @param value + * @param message + * - IPMI message being created + * @param offset + * @throws IndexOutOfBoundsException + * when message is too short to hold value at given offset + */ + private void encodeOEMIANA(int value, byte[] message, int offset) { + encodeInt(value, message, offset); + } + + /** + * Encodes OEM payload ID and inserts it into message at given offset. To + * implement manufacturer-specific OEM Payload ID encoding, override this + * function. + * + * @param value + * @param message + * - IPMI message being created + * @param offset + * @throws IndexOutOfBoundsException + * when message is too short to hold value at given offset + * @throws IllegalArgumentException + * when value is incorrect. + */ + protected void encodeOEMPayloadId(Object value, byte[] message, int offset) { + byte[] oemId = null; + try { + oemId = (byte[]) value; + } catch (Exception e) { + throw new IllegalArgumentException("Value is corrupted", e); + } + if (oemId.length != 2) { + throw new IllegalArgumentException("Value has invalid length"); + } + if (oemId.length + offset > message.length) { + throw new IndexOutOfBoundsException("Message is too short"); + } + + System.arraycopy(oemId, 0, message, offset, 2); + } + + @Override + protected void encodePayloadLength(int value, byte[] message, int offset) { + byte[] payloadLength = TypeConverter.intToLittleEndianByteArray(value); + message[offset] = payloadLength[0]; + message[offset + 1] = payloadLength[1]; + } + + /** + * Creates session trailer.
+ * Encodes Authorization Code and inserts it into message.
+ * Adds integrity pad if needed and inserts pad length and next header + * fields. + * + * @param authCode + * - Value of the Authorization Code + * @param message + * - IPMI message being created + * @param offset + * - Should point at the beginning of the session trailer. + * @throws IndexOutOfBoundsException + * when message is too short to hold value at given offset + * @return Offset pointing after Authorization Code + */ + private int encodeSessionTrailer(final byte[] authCode, final byte[] message, final int offset) { + int pad = 0; + + if (authCode != null && authCode.length + offset > message.length) { + throw new IndexOutOfBoundsException("Message is too short"); + } + + if (authCode != null) { + pad = (offset + authCode.length + 2) % 4; + } + + if (pad > 0) { + pad = 4 - pad; + } else { + pad = 0; + } + + int currentOffset = offset; + + for (int i = 0; i < pad; ++i) { + message[currentOffset] = TypeConverter.intToByte(0xff); + ++currentOffset; + } + + message[currentOffset] = TypeConverter.intToByte(pad); + ++currentOffset; + + // Next header - reserved + message[currentOffset] = TypeConverter.intToByte(0x07); + ++currentOffset; + if (authCode != null) { + System.arraycopy(authCode, 0, message, currentOffset, authCode.length); + currentOffset += authCode.length; + } + + return currentOffset; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/protocol/encoder/package-info.java b/src/main/java/org/metricshub/ipmi/core/coding/protocol/encoder/package-info.java index 2041ff7..e4ff210 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/protocol/encoder/package-info.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/protocol/encoder/package-info.java @@ -1,6 +1,7 @@ /** * IPMI protocol encoder classes. - * To implement custom protocol encoder, implement {@link org.metricshub.ipmi.core.coding.protocol.encoder.IpmiEncoder} interface. + * To implement custom protocol encoder, implement {@link org.metricshub.ipmi.core.coding.protocol.encoder.IpmiEncoder} + * interface. */ package org.metricshub.ipmi.core.coding.protocol.encoder; /*- diff --git a/src/main/java/org/metricshub/ipmi/core/coding/protocol/package-info.java b/src/main/java/org/metricshub/ipmi/core/coding/protocol/package-info.java index 9a64727..79eb1ba 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/protocol/package-info.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/protocol/package-info.java @@ -1,6 +1,5 @@ /** * The IPMI protocol messages, encoder and decoder. - * */ package org.metricshub.ipmi.core.coding.protocol; /*- diff --git a/src/main/java/org/metricshub/ipmi/core/coding/rmcp/RmcpClassOfMessage.java b/src/main/java/org/metricshub/ipmi/core/coding/rmcp/RmcpClassOfMessage.java index eccb6e3..bb90f94 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/rmcp/RmcpClassOfMessage.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/rmcp/RmcpClassOfMessage.java @@ -26,42 +26,44 @@ * Types of RMCP messages. */ public enum RmcpClassOfMessage { - /** - * ASF ACK Class of Message - */ - Ack(RmcpClassOfMessage.ACK), Asf(RmcpClassOfMessage.ASF), - /** - * OEM-defined Class of Message - */ - Oem(RmcpClassOfMessage.OEM), Ipmi(RmcpClassOfMessage.IPMI), ; + /** + * ASF ACK Class of Message + */ + Ack(RmcpClassOfMessage.ACK), + Asf(RmcpClassOfMessage.ASF), + /** + * OEM-defined Class of Message + */ + Oem(RmcpClassOfMessage.OEM), + Ipmi(RmcpClassOfMessage.IPMI),; - private static final int ACK = 134; - private static final int ASF = 6; - private static final int OEM = 8; - private static final int IPMI = 7; + private static final int ACK = 134; + private static final int ASF = 6; + private static final int OEM = 8; + private static final int IPMI = 7; - private int code; + private int code; - RmcpClassOfMessage(int code) { - this.code = code; - } + RmcpClassOfMessage(int code) { + this.code = code; + } - public int getCode() { - return code; - } + public int getCode() { + return code; + } - public static RmcpClassOfMessage parseInt(int value) { - switch (value) { - case ACK: - return Ack; - case ASF: - return Asf; - case OEM: - return Oem; - case IPMI: - return Ipmi; - default: - throw new IllegalArgumentException("Invalid value: " + value); - } - } + public static RmcpClassOfMessage parseInt(int value) { + switch (value) { + case ACK: + return Ack; + case ASF: + return Asf; + case OEM: + return Oem; + case IPMI: + return Ipmi; + default: + throw new IllegalArgumentException("Invalid value: " + value); + } + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/rmcp/RmcpConstants.java b/src/main/java/org/metricshub/ipmi/core/coding/rmcp/RmcpConstants.java index 7e5c38a..a9b3957 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/rmcp/RmcpConstants.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/rmcp/RmcpConstants.java @@ -27,28 +27,28 @@ /** * Set of constants. * Byte constants are encoded as pseudo unsigned bytes. - * RMCPConstants doesn't use {@link TypeConverter} because + * RMCPConstants doesn't use {@link TypeConverter} because * fields need to be runtime constants. + * * @see TypeConverter#byteToInt(byte) * @see TypeConverter#intToByte(int) */ public final class RmcpConstants { - /** - * RMCP version 1.0 - */ - public static final byte RMCP_V1_0 = 0x06; + /** + * RMCP version 1.0 + */ + public static final byte RMCP_V1_0 = 0x06; - /** - * IANA Enterprise Number = ASF IANA - */ - public static final int ASFIANA = 4542; + /** + * IANA Enterprise Number = ASF IANA + */ + public static final int ASFIANA = 4542; - /** - * ASF Message type = Presence Ping - */ - public static final byte PRESENCE_PING = (byte) (0x80 - 256); + /** + * ASF Message type = Presence Ping + */ + public static final byte PRESENCE_PING = (byte) (0x80 - 256); - private RmcpConstants() { - } + private RmcpConstants() {} } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/rmcp/RmcpDecoder.java b/src/main/java/org/metricshub/ipmi/core/coding/rmcp/RmcpDecoder.java index 5d299da..b183720 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/rmcp/RmcpDecoder.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/rmcp/RmcpDecoder.java @@ -29,58 +29,58 @@ */ public final class RmcpDecoder { - private RmcpDecoder() { - } + private RmcpDecoder() {} - /** - * Decodes the RMCP packet from raw data. - * @param rawMessage - * - packet data in a byte form - * @return RMCPMessage - * @throws IllegalArgumentException - * - occurs when message is too short or contains invalid data - */ - public static RmcpMessage decode(byte[] rawMessage) { - RmcpMessage message = new RmcpMessage(); + /** + * Decodes the RMCP packet from raw data. + * + * @param rawMessage + * - packet data in a byte form + * @return RMCPMessage + * @throws IllegalArgumentException + * - occurs when message is too short or contains invalid data + */ + public static RmcpMessage decode(byte[] rawMessage) { + RmcpMessage message = new RmcpMessage(); - if (rawMessage.length < 4) { - throw new IllegalArgumentException("Message is corrupted"); - } + if (rawMessage.length < 4) { + throw new IllegalArgumentException("Message is corrupted"); + } - message.setVersion(decodeVersion(rawMessage[0])); + message.setVersion(decodeVersion(rawMessage[0])); - // byte 1 is reserved + // byte 1 is reserved - message.setSequenceNumber(decodeSequenceNumber(rawMessage[2])); + message.setSequenceNumber(decodeSequenceNumber(rawMessage[2])); - message.setClassOfMessage(decodeClassOfMessage(rawMessage[3])); + message.setClassOfMessage(decodeClassOfMessage(rawMessage[3])); - message.setData(decodeData(rawMessage)); + message.setData(decodeData(rawMessage)); - return message; - } + return message; + } - private static RmcpVersion decodeVersion(byte version) { - if (version == RmcpConstants.RMCP_V1_0) { - return RmcpVersion.RMCP1_0; - } + private static RmcpVersion decodeVersion(byte version) { + if (version == RmcpConstants.RMCP_V1_0) { + return RmcpVersion.RMCP1_0; + } - throw new IllegalArgumentException("Illegal RMCP version"); - } + throw new IllegalArgumentException("Illegal RMCP version"); + } - private static int decodeSequenceNumber(byte sequenceNumber) { - return TypeConverter.byteToInt(sequenceNumber); - } + private static int decodeSequenceNumber(byte sequenceNumber) { + return TypeConverter.byteToInt(sequenceNumber); + } - private static RmcpClassOfMessage decodeClassOfMessage(byte classOfMessage) { - return RmcpClassOfMessage.parseInt(TypeConverter.byteToInt(classOfMessage) & 0x9f); - // bits 5 and 6 are reserved so we need to get rid of them - } + private static RmcpClassOfMessage decodeClassOfMessage(byte classOfMessage) { + return RmcpClassOfMessage.parseInt(TypeConverter.byteToInt(classOfMessage) & 0x9f); + // bits 5 and 6 are reserved so we need to get rid of them + } - private static byte[] decodeData(byte[] rawMessage) { - byte[] data = new byte[rawMessage.length - 4]; - System.arraycopy(rawMessage, 4, data, 0, data.length); - return data; - } + private static byte[] decodeData(byte[] rawMessage) { + byte[] data = new byte[rawMessage.length - 4]; + System.arraycopy(rawMessage, 4, data, 0, data.length); + return data; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/rmcp/RmcpEncoder.java b/src/main/java/org/metricshub/ipmi/core/coding/rmcp/RmcpEncoder.java index e803f63..be2e65f 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/rmcp/RmcpEncoder.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/rmcp/RmcpEncoder.java @@ -29,59 +29,58 @@ */ public final class RmcpEncoder { - private RmcpEncoder() { - } + private RmcpEncoder() {} - /** - * Encodes RMCPMessage into RMCP packet. - * - * @param message - * - RMCP message to be encoded - * @return byte data containing ready to send RMCP packet - */ - public static byte[] encode(RmcpMessage message) { - byte[] data = new byte[message.getData().length + 4]; + /** + * Encodes RMCPMessage into RMCP packet. + * + * @param message + * - RMCP message to be encoded + * @return byte data containing ready to send RMCP packet + */ + public static byte[] encode(RmcpMessage message) { + byte[] data = new byte[message.getData().length + 4]; - data[0] = encodeVersion(message.getVersion()); + data[0] = encodeVersion(message.getVersion()); - data[1] = 0; // reserved + data[1] = 0; // reserved - data[2] = encodeSequenceNumber(message.getSequenceNumber()); + data[2] = encodeSequenceNumber(message.getSequenceNumber()); - data[3] = encodeRMCPClassOfMessage(message.getClassOfMessage()); + data[3] = encodeRMCPClassOfMessage(message.getClassOfMessage()); - encodeData(message.getData(), data); + encodeData(message.getData(), data); - return data; - } + return data; + } - private static byte encodeVersion(RmcpVersion version) { - switch (version) { - case RMCP1_0: - return RmcpConstants.RMCP_V1_0; - default: - throw new IllegalArgumentException("Invalid RMCP version"); - } - } + private static byte encodeVersion(RmcpVersion version) { + switch (version) { + case RMCP1_0: + return RmcpConstants.RMCP_V1_0; + default: + throw new IllegalArgumentException("Invalid RMCP version"); + } + } - private static byte encodeSequenceNumber(byte sequenceNumber) { - return sequenceNumber; - } + private static byte encodeSequenceNumber(byte sequenceNumber) { + return sequenceNumber; + } - private static byte encodeRMCPClassOfMessage( - RmcpClassOfMessage classOfMessage) { - return TypeConverter.intToByte(classOfMessage.getCode()); - } + private static byte encodeRMCPClassOfMessage( + RmcpClassOfMessage classOfMessage) { + return TypeConverter.intToByte(classOfMessage.getCode()); + } - /** - * Copies data to message - * - * @param data - * - source data of RMCPMessage - * @param message - * - result message - */ - private static void encodeData(byte[] data, byte[] message) { - System.arraycopy(data, 0, message, 4, data.length); - } + /** + * Copies data to message + * + * @param data + * - source data of RMCPMessage + * @param message + * - result message + */ + private static void encodeData(byte[] data, byte[] message) { + System.arraycopy(data, 0, message, 4, data.length); + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/rmcp/RmcpIpmiMessage.java b/src/main/java/org/metricshub/ipmi/core/coding/rmcp/RmcpIpmiMessage.java index bf69b52..fe31c85 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/rmcp/RmcpIpmiMessage.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/rmcp/RmcpIpmiMessage.java @@ -26,15 +26,16 @@ * A wrapper class for ASF ping message. */ public class RmcpIpmiMessage extends RmcpMessage { - /** - * Prepares a ready to send ASF IPMI message. - * @param ipmiMessage - IPMI message encoded as a byte array. - */ - public RmcpIpmiMessage(byte[] ipmiMessage) { - setVersion(RmcpVersion.RMCP1_0); - setSequenceNumber(0xff); - setClassOfMessage(RmcpClassOfMessage.Ipmi); - setData(ipmiMessage); - } + /** + * Prepares a ready to send ASF IPMI message. + * + * @param ipmiMessage - IPMI message encoded as a byte array. + */ + public RmcpIpmiMessage(byte[] ipmiMessage) { + setVersion(RmcpVersion.RMCP1_0); + setSequenceNumber(0xff); + setClassOfMessage(RmcpClassOfMessage.Ipmi); + setData(ipmiMessage); + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/rmcp/RmcpMessage.java b/src/main/java/org/metricshub/ipmi/core/coding/rmcp/RmcpMessage.java index 2530716..2e33e43 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/rmcp/RmcpMessage.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/rmcp/RmcpMessage.java @@ -28,52 +28,53 @@ * A wrapper class for RMCP message. */ public class RmcpMessage { - private RmcpVersion version; - private byte sequenceNumber; - private RmcpClassOfMessage classOfMessage; - private byte[] data; + private RmcpVersion version; + private byte sequenceNumber; + private RmcpClassOfMessage classOfMessage; + private byte[] data; - public RmcpMessage() { - setSequenceNumber(0xff); - } + public RmcpMessage() { + setSequenceNumber(0xff); + } - public void setVersion(RmcpVersion version) { - this.version = version; - } + public void setVersion(RmcpVersion version) { + this.version = version; + } - public RmcpVersion getVersion() { - return version; - } + public RmcpVersion getVersion() { + return version; + } - /** - * Set RMCP sequence number. Must be 0-254 if ACK is desired, 255 if no ACK is desired. - * @param sequenceNumber - */ - public void setSequenceNumber(int sequenceNumber) { - this.sequenceNumber = TypeConverter.intToByte(sequenceNumber); - } + /** + * Set RMCP sequence number. Must be 0-254 if ACK is desired, 255 if no ACK is desired. + * + * @param sequenceNumber + */ + public void setSequenceNumber(int sequenceNumber) { + this.sequenceNumber = TypeConverter.intToByte(sequenceNumber); + } - public byte getSequenceNumber() { - return sequenceNumber; - } + public byte getSequenceNumber() { + return sequenceNumber; + } - public int getIntSequenceNumber() { - return TypeConverter.byteToInt(sequenceNumber); - } + public int getIntSequenceNumber() { + return TypeConverter.byteToInt(sequenceNumber); + } - public void setClassOfMessage(RmcpClassOfMessage classOfMessage) { - this.classOfMessage = classOfMessage; - } + public void setClassOfMessage(RmcpClassOfMessage classOfMessage) { + this.classOfMessage = classOfMessage; + } - public RmcpClassOfMessage getClassOfMessage() { - return classOfMessage; - } + public RmcpClassOfMessage getClassOfMessage() { + return classOfMessage; + } - public void setData(byte[] data) { - this.data = data; - } + public void setData(byte[] data) { + this.data = data; + } - public byte[] getData() { - return data; - } + public byte[] getData() { + return data; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/rmcp/RmcpPingMessage.java b/src/main/java/org/metricshub/ipmi/core/coding/rmcp/RmcpPingMessage.java index da10991..46d74f7 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/rmcp/RmcpPingMessage.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/rmcp/RmcpPingMessage.java @@ -28,44 +28,49 @@ * A wrapper class for ASF ping message. */ public class RmcpPingMessage extends RmcpMessage { - /** - * Prepares a ready to send ASF ping message. - * - * @param sequenceNumber - * Used for pairing request with response. Can't be 255. - * @throws IllegalArgumentException - * when sequence number is 255. - */ - public RmcpPingMessage(int sequenceNumber) { - super(); - if (sequenceNumber > 254 || sequenceNumber < 0) { - throw new IllegalArgumentException( - "Sequence number must be in range 0-254"); - } - setVersion(RmcpVersion.RMCP1_0); - setClassOfMessage(RmcpClassOfMessage.Asf); - setData(preparePingMessage(sequenceNumber)); - } + /** + * Prepares a ready to send ASF ping message. + * + * @param sequenceNumber + * Used for pairing request with response. Can't be 255. + * @throws IllegalArgumentException + * when sequence number is 255. + */ + public RmcpPingMessage(int sequenceNumber) { + super(); + if (sequenceNumber > 254 || sequenceNumber < 0) { + throw new IllegalArgumentException( + "Sequence number must be in range 0-254"); + } + setVersion(RmcpVersion.RMCP1_0); + setClassOfMessage(RmcpClassOfMessage.Asf); + setData(preparePingMessage(sequenceNumber)); + } - private byte[] preparePingMessage(int sequenceNumber) { - byte[] message = new byte[8]; + private byte[] preparePingMessage(int sequenceNumber) { + byte[] message = new byte[8]; - // set IANA Enterprise Number - System.arraycopy(TypeConverter.intToByteArray(RmcpConstants.ASFIANA), - 0, message, 0, 4); + // set IANA Enterprise Number + System + .arraycopy( + TypeConverter.intToByteArray(RmcpConstants.ASFIANA), + 0, + message, + 0, + 4); - // set message type as presence ping - message[4] = RmcpConstants.PRESENCE_PING; + // set message type as presence ping + message[4] = RmcpConstants.PRESENCE_PING; - // set message tag (ASF version of a sequence number) - message[5] = TypeConverter.intToByte(sequenceNumber); + // set message tag (ASF version of a sequence number) + message[5] = TypeConverter.intToByte(sequenceNumber); - // reserved - message[6] = 0; + // reserved + message[6] = 0; - // data length - message[7] = 0; + // data length + message[7] = 0; - return message; - } + return message; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/rmcp/RmcpVersion.java b/src/main/java/org/metricshub/ipmi/core/coding/rmcp/RmcpVersion.java index 01ab06d..964431d 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/rmcp/RmcpVersion.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/rmcp/RmcpVersion.java @@ -24,8 +24,7 @@ /** * Supported versions of RMCP protocol - * */ public enum RmcpVersion { - RMCP1_0, + RMCP1_0, } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/security/AuthenticationAlgorithm.java b/src/main/java/org/metricshub/ipmi/core/coding/security/AuthenticationAlgorithm.java index 22fa749..81a0ad6 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/security/AuthenticationAlgorithm.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/security/AuthenticationAlgorithm.java @@ -73,16 +73,17 @@ private AuthenticationAlgorithm(Mac mac) { /** * Checks value of the Key Exchange Authentication Code in RAKP messages * - * @param data - The base for authentication algorithm. Depends on RAKP - * Message. - * @param key - the Key Exchange Authentication Code to check. + * @param data - The base for authentication algorithm. Depends on RAKP + * Message. + * @param key - the Key Exchange Authentication Code to check. * @param password - password of the user establishing a session * @return True if authentication check was successful, false otherwise. * @throws NoSuchAlgorithmException when initiation of the algorithm fails - * @throws InvalidKeyException when creating of the algorithm key fails + * @throws InvalidKeyException when creating of the algorithm key fails */ public boolean checkKeyExchangeAuthenticationCode(byte[] data, byte[] key, String password) - throws NoSuchAlgorithmException, InvalidKeyException { + throws NoSuchAlgorithmException, + InvalidKeyException { byte[] check = getKeyExchangeAuthenticationCode(data, password); return Arrays.equals(check, key); } @@ -90,14 +91,15 @@ public boolean checkKeyExchangeAuthenticationCode(byte[] data, byte[] key, Strin /** * Calculates value of the Key Exchange Authentication Code in RAKP messages * - * @param data - The base for authentication algorithm. Depends on RAKP - * Message. + * @param data - The base for authentication algorithm. Depends on RAKP + * Message. * @param password - password of the user establishing a session * @throws NoSuchAlgorithmException when initiation of the algorithm fails - * @throws InvalidKeyException when creating of the algorithm key fails + * @throws InvalidKeyException when creating of the algorithm key fails */ public byte[] getKeyExchangeAuthenticationCode(byte[] data, String password) - throws NoSuchAlgorithmException, InvalidKeyException { + throws NoSuchAlgorithmException, + InvalidKeyException { final byte[] key = password.getBytes(); @@ -110,21 +112,22 @@ public byte[] getKeyExchangeAuthenticationCode(byte[] data, String password) /** * Validates Integrity Check Value in RAKP Message 4. * - * @param data - The base for authentication algorithm. + * @param data - The base for authentication algorithm. * @param reference - The Integrity Check Value to validate. - * @param sik - The Session Integrity Key generated on base of RAKP - * Messages 1 and 2. + * @param sik - The Session Integrity Key generated on base of RAKP + * Messages 1 and 2. * @see Rakp1#calculateSik(org.metricshub.ipmi.core.coding.commands.session.Rakp1ResponseData) * @return True if integrity check was successful, false otherwise. * @throws NoSuchAlgorithmException when initiation of the algorithm fails - * @throws InvalidKeyException when creating of the algorithm key fails + * @throws InvalidKeyException when creating of the algorithm key fails */ public boolean doIntegrityCheck(byte[] data, byte[] reference, byte[] sik) - throws InvalidKeyException, NoSuchAlgorithmException { + throws InvalidKeyException, + NoSuchAlgorithmException { SecretKeySpec sKey = new SecretKeySpec(sik, getAlgorithmName()); mac.init(sKey); - + final int integrityCheckLength = getIntegrityCheckBaseLength(); final byte[] result = new byte[integrityCheckLength]; diff --git a/src/main/java/org/metricshub/ipmi/core/coding/security/AuthenticationRakpHmacSha1.java b/src/main/java/org/metricshub/ipmi/core/coding/security/AuthenticationRakpHmacSha1.java index 8b15999..8a1b5ee 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/security/AuthenticationRakpHmacSha1.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/security/AuthenticationRakpHmacSha1.java @@ -26,9 +26,9 @@ * RAKP-HMAC-SHA1 authentication algorithm. */ public class AuthenticationRakpHmacSha1 extends AuthenticationAlgorithm { - + private static final String ALGORITHM_NAME = "HmacSHA1"; - + /** * Initiates RAKP-HMAC-SHA1 authentication algorithm. */ diff --git a/src/main/java/org/metricshub/ipmi/core/coding/security/AuthenticationRakpNone.java b/src/main/java/org/metricshub/ipmi/core/coding/security/AuthenticationRakpNone.java index 430dd33..cfd330d 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/security/AuthenticationRakpNone.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/security/AuthenticationRakpNone.java @@ -28,8 +28,8 @@ public class AuthenticationRakpNone extends AuthenticationAlgorithm { /** - * Constructs an instance of the RAKP-None authentication algorithm. - */ + * Constructs an instance of the RAKP-None authentication algorithm. + */ public AuthenticationRakpNone() { super(""); } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/security/CipherSuite.java b/src/main/java/org/metricshub/ipmi/core/coding/security/CipherSuite.java index 2964938..a568357 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/security/CipherSuite.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/security/CipherSuite.java @@ -40,54 +40,57 @@ */ public class CipherSuite { - public static final String NOT_YET_IMPLEMENTED_MESSAGE = "Not yet implemented."; + public static final String NOT_YET_IMPLEMENTED_MESSAGE = "Not yet implemented."; - private byte id; + private byte id; - private byte authenticationAlgorithm; - private byte integrityAlgorithm; - private byte confidentialityAlgorithm; + private byte authenticationAlgorithm; + private byte integrityAlgorithm; + private byte confidentialityAlgorithm; - private AuthenticationAlgorithm aa; - private ConfidentialityAlgorithm ca; - private IntegrityAlgorithm ia; + private AuthenticationAlgorithm aa; + private ConfidentialityAlgorithm ca; + private IntegrityAlgorithm ia; - public byte getId() { - return id; - } + public byte getId() { + return id; + } - public CipherSuite(byte id, byte authenticationAlgorithm, - byte confidentialityAlgorithm, byte integrityAlgorithm) { - this.id = id; - this.authenticationAlgorithm = (authenticationAlgorithm); - this.confidentialityAlgorithm = (confidentialityAlgorithm); - this.integrityAlgorithm = (integrityAlgorithm); - } + public CipherSuite(byte id, byte authenticationAlgorithm, + byte confidentialityAlgorithm, byte integrityAlgorithm) { + this.id = id; + this.authenticationAlgorithm = (authenticationAlgorithm); + this.confidentialityAlgorithm = (confidentialityAlgorithm); + this.integrityAlgorithm = (integrityAlgorithm); + } - /** - * Initializes algorithms contained in this {@link CipherSuite}. - * - * @param sik - * - Session Integrity Key calculated during the opening of the - * session or user password if 'one-key' logins are enabled. - * @throws IllegalArgumentException - * @throws InvalidKeyException - * - when initiation of the algorithm fails - * @throws NoSuchAlgorithmException - * - when initiation of the algorithm fails - * @throws NoSuchPaddingException - * - when initiation of the algorithm fails - */ - public void initializeAlgorithms(byte[] sik) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException { - getIntegrityAlgorithm().initialize(sik); - getConfidentialityAlgorithm().initialize(sik, getAuthenticationAlgorithm()); - } + /** + * Initializes algorithms contained in this {@link CipherSuite}. + * + * @param sik + * - Session Integrity Key calculated during the opening of the + * session or user password if 'one-key' logins are enabled. + * @throws IllegalArgumentException + * @throws InvalidKeyException + * - when initiation of the algorithm fails + * @throws NoSuchAlgorithmException + * - when initiation of the algorithm fails + * @throws NoSuchPaddingException + * - when initiation of the algorithm fails + */ + public void initializeAlgorithms(byte[] sik) + throws InvalidKeyException, + NoSuchAlgorithmException, + NoSuchPaddingException { + getIntegrityAlgorithm().initialize(sik); + getConfidentialityAlgorithm().initialize(sik, getAuthenticationAlgorithm()); + } /** * Returns instance of AuthenticationAlgorithm class. * * @throws IllegalArgumentException when authentication algorithm code is - * incorrect. + * incorrect. */ public AuthenticationAlgorithm getAuthenticationAlgorithm() { if (aa != null && aa.getCode() != authenticationAlgorithm) { @@ -133,95 +136,101 @@ public IntegrityAlgorithm getIntegrityAlgorithm() { } } - /** - * Returns instance of ConfidentialityAlgorithm class. - * - * @throws IllegalArgumentException - * when confidentiality algorithm code is incorrect. - */ - public ConfidentialityAlgorithm getConfidentialityAlgorithm() { - if (ca != null && ca.getCode() != confidentialityAlgorithm) { - throw new IllegalArgumentException( - "Invalid confidentiality algorithm code"); - } - switch (confidentialityAlgorithm) { - case SecurityConstants.CA_NONE: - if (ca == null) { - ca = new ConfidentialityNone(); - } - return ca; - case SecurityConstants.CA_AES_CBC128: - if (ca == null) { - ca = new ConfidentialityAesCbc128(); - } - return ca; - case SecurityConstants.CA_XRC4_40: - // TODO: XRc4-40 - throw new IllegalArgumentException("Confidentiality algorithm XRC4-40 is not yet implemented."); - case SecurityConstants.CA_XRC4_128: - // TODO: XRc4-128 - throw new IllegalArgumentException("Confidentiality algorithm XRC4-128 is not yet implemented."); - default: - throw new IllegalArgumentException( - "Invalid confidentiality algorithm."); + /** + * Returns instance of ConfidentialityAlgorithm class. + * + * @throws IllegalArgumentException + * when confidentiality algorithm code is incorrect. + */ + public ConfidentialityAlgorithm getConfidentialityAlgorithm() { + if (ca != null && ca.getCode() != confidentialityAlgorithm) { + throw new IllegalArgumentException( + "Invalid confidentiality algorithm code"); + } + switch (confidentialityAlgorithm) { + case SecurityConstants.CA_NONE: + if (ca == null) { + ca = new ConfidentialityNone(); + } + return ca; + case SecurityConstants.CA_AES_CBC128: + if (ca == null) { + ca = new ConfidentialityAesCbc128(); + } + return ca; + case SecurityConstants.CA_XRC4_40: + // TODO: XRc4-40 + throw new IllegalArgumentException("Confidentiality algorithm XRC4-40 is not yet implemented."); + case SecurityConstants.CA_XRC4_128: + // TODO: XRc4-128 + throw new IllegalArgumentException("Confidentiality algorithm XRC4-128 is not yet implemented."); + default: + throw new IllegalArgumentException( + "Invalid confidentiality algorithm."); - } - } + } + } - /** - * Builds Cipher Suites collection from raw data received by - * {@link GetChannelCipherSuites} commands. Cannot be executed in - * {@link GetChannelCipherSuitesResponseData} since data comes in 16-byte - * packets and is fragmented. Supports only one integrity and one - * confidentiality algorithm per suite. - * - * @param bytes - * - concatenated Cipher Suite Records received by - * {@link GetChannelCipherSuites} commands. - * @return list of Cipher Suites supported by BMC. - */ - public static List getCipherSuites(byte[] bytes) { - ArrayList suites = new ArrayList(); + /** + * Builds Cipher Suites collection from raw data received by + * {@link GetChannelCipherSuites} commands. Cannot be executed in + * {@link GetChannelCipherSuitesResponseData} since data comes in 16-byte + * packets and is fragmented. Supports only one integrity and one + * confidentiality algorithm per suite. + * + * @param bytes + * - concatenated Cipher Suite Records received by + * {@link GetChannelCipherSuites} commands. + * @return list of Cipher Suites supported by BMC. + */ + public static List getCipherSuites(byte[] bytes) { + ArrayList suites = new ArrayList(); - int offset = 0; + int offset = 0; - while (offset < bytes.length) { - byte id = bytes[offset + 1]; - if (bytes[offset] == TypeConverter.intToByte(0xC0)) { - offset += 2; - } else { - offset += 5; - } - byte aa = bytes[offset]; - byte ca = -1; - byte ia = -1; - ++offset; - while (offset < bytes.length - && bytes[offset] != TypeConverter.intToByte(0xC0) - && bytes[offset] != TypeConverter.intToByte(0xC1)) { - if ((TypeConverter.byteToInt(bytes[offset]) & 0xC0) == 0x80) { - ca = TypeConverter.intToByte(TypeConverter - .byteToInt(bytes[offset]) & 0x3f); - } else if ((TypeConverter.byteToInt(bytes[offset]) & 0xC0) == 0x40) { - ia = TypeConverter.intToByte(TypeConverter - .byteToInt(bytes[offset]) & 0x3f); - } - ++offset; - } - suites.add(new CipherSuite(id, aa, ca, ia)); - } + while (offset < bytes.length) { + byte id = bytes[offset + 1]; + if (bytes[offset] == TypeConverter.intToByte(0xC0)) { + offset += 2; + } else { + offset += 5; + } + byte aa = bytes[offset]; + byte ca = -1; + byte ia = -1; + ++offset; + while (offset < bytes.length + && bytes[offset] != TypeConverter.intToByte(0xC0) + && bytes[offset] != TypeConverter.intToByte(0xC1)) { + if ((TypeConverter.byteToInt(bytes[offset]) & 0xC0) == 0x80) { + ca = TypeConverter + .intToByte( + TypeConverter + .byteToInt(bytes[offset]) + & 0x3f); + } else if ((TypeConverter.byteToInt(bytes[offset]) & 0xC0) == 0x40) { + ia = TypeConverter + .intToByte( + TypeConverter + .byteToInt(bytes[offset]) + & 0x3f); + } + ++offset; + } + suites.add(new CipherSuite(id, aa, ca, ia)); + } - return suites; - } + return suites; + } - /** - * @return {@link CipherSuite} with algorithms set to - * {@link AuthenticationRakpNone}, {@link ConfidentialityNone} and - * {@link IntegrityNone}. - */ - public static CipherSuite getEmpty() { - return new CipherSuite((byte) 0, (byte) 0, (byte) 0, (byte) 0); - } + /** + * @return {@link CipherSuite} with algorithms set to + * {@link AuthenticationRakpNone}, {@link ConfidentialityNone} and + * {@link IntegrityNone}. + */ + public static CipherSuite getEmpty() { + return new CipherSuite((byte) 0, (byte) 0, (byte) 0, (byte) 0); + } /** * Creates an instance of AuthenticationAlgorithm. @@ -235,7 +244,7 @@ private AuthenticationAlgorithm instantiateAuthenticationAlgorithm( } return aa; } - + /** * Creates an instance of IntegrityAlgorithm. * diff --git a/src/main/java/org/metricshub/ipmi/core/coding/security/ConfidentialityAesCbc128.java b/src/main/java/org/metricshub/ipmi/core/coding/security/ConfidentialityAesCbc128.java index c1c9289..11798a3 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/security/ConfidentialityAesCbc128.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/security/ConfidentialityAesCbc128.java @@ -44,109 +44,111 @@ public class ConfidentialityAesCbc128 extends ConfidentialityAlgorithm { Arrays.fill(CONST2, (byte) 2); } - private Cipher cipher; + private Cipher cipher; - private SecretKeySpec cipherKey; + private SecretKeySpec cipherKey; - @Override - public byte getCode() { - return SecurityConstants.CA_AES_CBC128; - } + @Override + public byte getCode() { + return SecurityConstants.CA_AES_CBC128; + } - @Override - public void initialize(byte[] sik, AuthenticationAlgorithm authenticationAlgorithm) throws InvalidKeyException, - NoSuchAlgorithmException, NoSuchPaddingException { - super.initialize(sik, authenticationAlgorithm); + @Override + public void initialize(byte[] sik, AuthenticationAlgorithm authenticationAlgorithm) + throws InvalidKeyException, + NoSuchAlgorithmException, + NoSuchPaddingException { + super.initialize(sik, authenticationAlgorithm); - final String algorithmName = authenticationAlgorithm.getAlgorithmName(); + final String algorithmName = authenticationAlgorithm.getAlgorithmName(); SecretKeySpec k2 = new SecretKeySpec(sik, algorithmName); - Mac mac = Mac.getInstance(algorithmName); - mac.init(k2); + Mac mac = Mac.getInstance(algorithmName); + mac.init(k2); - byte[] ckey = mac.doFinal(CONST2); + byte[] ckey = mac.doFinal(CONST2); - byte[] ciphKey = new byte[16]; + byte[] ciphKey = new byte[16]; - System.arraycopy(ckey, 0, ciphKey, 0, 16); + System.arraycopy(ckey, 0, ciphKey, 0, 16); - cipherKey = new SecretKeySpec(ciphKey, "AES"); + cipherKey = new SecretKeySpec(ciphKey, "AES"); - cipher = Cipher.getInstance("AES/CBC/NoPadding"); - } + cipher = Cipher.getInstance("AES/CBC/NoPadding"); + } - @Override - public byte[] encrypt(byte[] data) throws InvalidKeyException { - int length = data.length + 17; - int pad = 0; - if (length % 16 != 0) { - pad = 16 - length % 16; - } - length += pad; + @Override + public byte[] encrypt(byte[] data) throws InvalidKeyException { + int length = data.length + 17; + int pad = 0; + if (length % 16 != 0) { + pad = 16 - length % 16; + } + length += pad; - byte[] result = new byte[length - 16]; + byte[] result = new byte[length - 16]; - cipher.init(Cipher.ENCRYPT_MODE, cipherKey); + cipher.init(Cipher.ENCRYPT_MODE, cipherKey); - System.arraycopy(data, 0, result, 0, data.length); + System.arraycopy(data, 0, result, 0, data.length); - for (int i = 0; i < pad; ++i) { - result[i + data.length] = TypeConverter.intToByte(i + 1); - } + for (int i = 0; i < pad; ++i) { + result[i + data.length] = TypeConverter.intToByte(i + 1); + } - result[length - 17] = TypeConverter.intToByte(pad); + result[length - 17] = TypeConverter.intToByte(pad); - try { - byte[] encrypted = cipher.doFinal(result); + try { + byte[] encrypted = cipher.doFinal(result); - result = new byte[encrypted.length + 16]; + result = new byte[encrypted.length + 16]; - System.arraycopy(encrypted, 0, result, 16, encrypted.length); // encrypted - // payload - System.arraycopy(cipher.getIV(), 0, result, 0, 16); // Initialization - // vector + System.arraycopy(encrypted, 0, result, 16, encrypted.length); // encrypted + // payload + System.arraycopy(cipher.getIV(), 0, result, 0, 16); // Initialization + // vector - return result; - } catch (Exception e) { - throw new IllegalArgumentException(e.getMessage(), e); - } - } + return result; + } catch (Exception e) { + throw new IllegalArgumentException(e.getMessage(), e); + } + } - @Override - public byte[] decrypt(byte[] data) { + @Override + public byte[] decrypt(byte[] data) { - byte[] decrypted = null; - try { - byte[] iv = new byte[16]; + byte[] decrypted = null; + try { + byte[] iv = new byte[16]; - System.arraycopy(data, 0, iv, 0, 16); + System.arraycopy(data, 0, iv, 0, 16); - byte[] encrypted = new byte[data.length - 16]; + byte[] encrypted = new byte[data.length - 16]; - System.arraycopy(data, 16, encrypted, 0, encrypted.length); + System.arraycopy(data, 16, encrypted, 0, encrypted.length); - cipher.init(Cipher.DECRYPT_MODE, cipherKey, new IvParameterSpec(iv)); - decrypted = cipher.doFinal(encrypted); - } catch (Exception e) { - throw new IllegalArgumentException("Decryption failed", e); - } + cipher.init(Cipher.DECRYPT_MODE, cipherKey, new IvParameterSpec(iv)); + decrypted = cipher.doFinal(encrypted); + } catch (Exception e) { + throw new IllegalArgumentException("Decryption failed", e); + } - int pad = TypeConverter.byteToInt(decrypted[decrypted.length - 1]); + int pad = TypeConverter.byteToInt(decrypted[decrypted.length - 1]); - byte[] result = new byte[decrypted.length - pad - 1]; + byte[] result = new byte[decrypted.length - pad - 1]; - System.arraycopy(decrypted, 0, result, 0, result.length); + System.arraycopy(decrypted, 0, result, 0, result.length); - return result; - } + return result; + } - @Override - public int getConfidentialityOverheadSize(int payloadSize) { - int size = 17; - if ((size + payloadSize) % 16 != 0) { - size += 16 - (size + payloadSize) % 16; - } - return size; - } + @Override + public int getConfidentialityOverheadSize(int payloadSize) { + int size = 17; + if ((size + payloadSize) % 16 != 0) { + size += 16 - (size + payloadSize) % 16; + } + return size; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/security/ConfidentialityAlgorithm.java b/src/main/java/org/metricshub/ipmi/core/coding/security/ConfidentialityAlgorithm.java index 8e2d03d..cc518e6 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/security/ConfidentialityAlgorithm.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/security/ConfidentialityAlgorithm.java @@ -31,63 +31,75 @@ * implement constructor(byte[]). */ public abstract class ConfidentialityAlgorithm { - protected byte[] sik; - /** - * Initializes Confidentiality Algorithm - * - * @param sik - * - Session Integrity Key calculated during the opening of the - * session or user password if 'one-key' logins are enabled. - * @param authenticationAlgorithm - * - Algorithm used for authentication. - * @throws InvalidKeyException - * - when initiation of the algorithm fails - * @throws NoSuchAlgorithmException - * - when initiation of the algorithm fails - * @throws NoSuchPaddingException - * - when initiation of the algorithm fails - */ - public void initialize(byte[] sik, AuthenticationAlgorithm authenticationAlgorithm) throws InvalidKeyException, - NoSuchAlgorithmException, NoSuchPaddingException { - this.sik = sik; - } + private byte[] sik; - /** - * Returns the algorithm's ID. - */ - public abstract byte getCode(); + /** + * Initializes Confidentiality Algorithm + * + * @param key + * - Session Integrity Key calculated during the opening of the + * session or user password if 'one-key' logins are enabled. + * @param authenticationAlgorithm + * - Algorithm used for authentication. + * @throws InvalidKeyException + * - when initiation of the algorithm fails + * @throws NoSuchAlgorithmException + * - when initiation of the algorithm fails + * @throws NoSuchPaddingException + * - when initiation of the algorithm fails + */ + public void initialize(byte[] key, AuthenticationAlgorithm authenticationAlgorithm) + throws InvalidKeyException, + NoSuchAlgorithmException, + NoSuchPaddingException { + this.sik = key; + } - /** - * Encrypts the data. - * - * @param data - * - payload to be encrypted - * @return encrypted data encapsulated in COnfidentiality Header and - * Trailer. - * @throws InvalidKeyException - * - when initiation of the algorithm fails - */ - public abstract byte[] encrypt(byte[] data) throws InvalidKeyException; + /** + * Returns the Session Integrity Key passed to {@link #initialize(byte[], AuthenticationAlgorithm)}. + * + * @return the Session Integrity Key, or null if not initialized + */ + protected byte[] getSik() { + return sik; + } - /** - * Decrypts the data. - * - * @param data - * - encrypted data encapsulated in COnfidentiality Header and - * Trailer. - * @return decrypted data. - * @throws IllegalArgumentException - * - when initiation of the algorithm fails - */ - public abstract byte[] decrypt(byte[] data); + /** + * Returns the algorithm's ID. + */ + public abstract byte getCode(); - /** - * Calculates size of the confidentiality header and trailer specific for - * the algorithm. - * - * @param payloadSize - * - size of the data that will be encrypted - */ - public abstract int getConfidentialityOverheadSize(int payloadSize); + /** + * Encrypts the data. + * + * @param data + * - payload to be encrypted + * @return encrypted data encapsulated in COnfidentiality Header and + * Trailer. + * @throws InvalidKeyException + * - when initiation of the algorithm fails + */ + public abstract byte[] encrypt(byte[] data) throws InvalidKeyException; + + /** + * Decrypts the data. + * + * @param data + * - encrypted data encapsulated in COnfidentiality Header and + * Trailer. + * @return decrypted data. + * @throws IllegalArgumentException + * - when initiation of the algorithm fails + */ + public abstract byte[] decrypt(byte[] data); + + /** + * Calculates size of the confidentiality header and trailer specific for + * the algorithm. + * + * @param payloadSize + * - size of the data that will be encrypted + */ + public abstract int getConfidentialityOverheadSize(int payloadSize); } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/security/ConfidentialityNone.java b/src/main/java/org/metricshub/ipmi/core/coding/security/ConfidentialityNone.java index 9c445dc..2ad69f5 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/security/ConfidentialityNone.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/security/ConfidentialityNone.java @@ -27,28 +27,28 @@ */ public class ConfidentialityNone extends ConfidentialityAlgorithm { - public ConfidentialityNone() { - super(); - } - - @Override - public byte getCode() { - return SecurityConstants.CA_NONE; - } - - @Override - public byte[] encrypt(byte[] data) { - return data; - } - - @Override - public byte[] decrypt(byte[] data) { - return data; - } - - @Override - public int getConfidentialityOverheadSize(int payloadSize) { - return 0; - } + public ConfidentialityNone() { + super(); + } + + @Override + public byte getCode() { + return SecurityConstants.CA_NONE; + } + + @Override + public byte[] encrypt(byte[] data) { + return data; + } + + @Override + public byte[] decrypt(byte[] data) { + return data; + } + + @Override + public int getConfidentialityOverheadSize(int payloadSize) { + return 0; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/security/IntegrityAlgorithm.java b/src/main/java/org/metricshub/ipmi/core/coding/security/IntegrityAlgorithm.java index eee25b0..949e15b 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/security/IntegrityAlgorithm.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/security/IntegrityAlgorithm.java @@ -42,7 +42,7 @@ public abstract class IntegrityAlgorithm { Arrays.fill(CONST1, (byte) 1); } - protected byte[] sik; + private byte[] sik; private final Mac mac; /** @@ -54,7 +54,7 @@ protected IntegrityAlgorithm(String algorithmName) { /** * Constructs an integrity algorithm with the provided MAC. - * + * * @param mac the MAC instance to use */ private IntegrityAlgorithm(Mac mac) { @@ -64,14 +64,14 @@ private IntegrityAlgorithm(Mac mac) { /** * Initializes Integrity Algorithm * - * @param sik - Session Integrity Key calculated during the opening of the - * session or user password if 'one-key' logins are enabled. + * @param key - Session Integrity Key calculated during the opening of the + * session or user password if 'one-key' logins are enabled. */ - public void initialize(byte[] sik) throws InvalidKeyException { - this.sik = sik; + public void initialize(byte[] key) throws InvalidKeyException { + this.sik = key; final String algorithmName = getAlgorithmName(); - - SecretKeySpec k1 = new SecretKeySpec(sik, algorithmName); + + SecretKeySpec k1 = new SecretKeySpec(key, algorithmName); mac.init(k1); k1 = new SecretKeySpec(mac.doFinal(CONST1), algorithmName); @@ -79,6 +79,24 @@ public void initialize(byte[] sik) throws InvalidKeyException { mac.init(k1); } + /** + * Returns the Session Integrity Key passed to {@link #initialize(byte[])}. + * + * @return the Session Integrity Key, or null if not initialized + */ + protected byte[] getSik() { + return sik; + } + + /** + * Stores the Session Integrity Key without initializing the MAC, for algorithms that do not use one. + * + * @param sik the Session Integrity Key + */ + protected void setSik(byte[] sik) { + this.sik = sik; + } + /** * Returns the algorithm's ID. */ @@ -88,9 +106,8 @@ public void initialize(byte[] sik) throws InvalidKeyException { * Creates AuthCode field for message. * * @param base - data starting with the AuthType/Format field up to and - * including the field that immediately precedes the AuthCode field + * including the field that immediately precedes the AuthCode field * @return AuthCode field. Might be null if empty AuthCOde field is generated. - * * @see Rakp1#calculateSik(org.metricshub.ipmi.core.coding.commands.session.Rakp1ResponseData) */ public byte[] generateAuthCode(final byte[] base) { @@ -98,7 +115,7 @@ public byte[] generateAuthCode(final byte[] base) { if (sik == null) { throw new NullPointerException("Algorithm not initialized."); } - + final int authCodeLength = getAuthCodeLength(); final byte[] result = new byte[authCodeLength]; byte[] updatedBase; @@ -118,7 +135,7 @@ public byte[] generateAuthCode(final byte[] base) { * Modifies the algorithm base since with null Auth Code during encoding * Integrity Pad isn't calculated. * - * @param base - integrity algorithm base without Integrity Pad. + * @param base - integrity algorithm base without Integrity Pad. * @param authCodeLength - expected length of the Auth Code field. * @return - integrity algorithm base with Integrity Pad and updated Pad Length * field. diff --git a/src/main/java/org/metricshub/ipmi/core/coding/security/IntegrityHmacMd5_128.java b/src/main/java/org/metricshub/ipmi/core/coding/security/IntegrityHmacMd5_128.java index 3fd46ea..a2159b5 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/security/IntegrityHmacMd5_128.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/security/IntegrityHmacMd5_128.java @@ -22,10 +22,13 @@ * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ */ +// Name mirrors the IPMI 2.0 integrity algorithm name (HMAC-xxx-nn); kept for API compatibility +// CHECKSTYLE.OFF: TypeName /** * HMAC-MD5-128 integrity algorithm. */ public class IntegrityHmacMd5_128 extends IntegrityAlgorithm { + // CHECKSTYLE.ON: TypeName public static final String ALGORITHM_NAME = "HmacMD5"; @@ -50,4 +53,4 @@ public String getAlgorithmName() { public int getAuthCodeLength() { return 16; } -} \ No newline at end of file +} diff --git a/src/main/java/org/metricshub/ipmi/core/coding/security/IntegrityHmacSha1_96.java b/src/main/java/org/metricshub/ipmi/core/coding/security/IntegrityHmacSha1_96.java index 0ea1505..76f0a53 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/security/IntegrityHmacSha1_96.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/security/IntegrityHmacSha1_96.java @@ -22,32 +22,35 @@ * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ */ +// Name mirrors the IPMI 2.0 integrity algorithm name (HMAC-xxx-nn); kept for API compatibility +// CHECKSTYLE.OFF: TypeName /** * HMAC-SHA1-96 integrity algorithm. */ public class IntegrityHmacSha1_96 extends IntegrityAlgorithm { + // CHECKSTYLE.ON: TypeName - public static final String ALGORITHM_NAME = "HmacSHA1"; + public static final String ALGORITHM_NAME = "HmacSHA1"; - /** - * Initiates HMAC-SHA1-96 integrity algorithm. - */ - public IntegrityHmacSha1_96() { - super(ALGORITHM_NAME); - } + /** + * Initiates HMAC-SHA1-96 integrity algorithm. + */ + public IntegrityHmacSha1_96() { + super(ALGORITHM_NAME); + } + + @Override + public byte getCode() { + return SecurityConstants.IA_HMAC_SHA1_96; + } - @Override - public byte getCode() { - return SecurityConstants.IA_HMAC_SHA1_96; - } + @Override + public String getAlgorithmName() { + return ALGORITHM_NAME; + } - @Override - public String getAlgorithmName() { - return ALGORITHM_NAME; - } - @Override public int getAuthCodeLength() { - return 12; + return 12; } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/security/IntegrityHmacSha256_128.java b/src/main/java/org/metricshub/ipmi/core/coding/security/IntegrityHmacSha256_128.java index e72bed3..a27781f 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/security/IntegrityHmacSha256_128.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/security/IntegrityHmacSha256_128.java @@ -22,10 +22,13 @@ * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ */ +// Name mirrors the IPMI 2.0 integrity algorithm name (HMAC-xxx-nn); kept for API compatibility +// CHECKSTYLE.OFF: TypeName /** * HMAC-SHA256-128 integrity algorithm. */ public class IntegrityHmacSha256_128 extends IntegrityAlgorithm { + // CHECKSTYLE.ON: TypeName private static final String ALGORITHM_NAME = "HmacSHA256"; diff --git a/src/main/java/org/metricshub/ipmi/core/coding/security/IntegrityNone.java b/src/main/java/org/metricshub/ipmi/core/coding/security/IntegrityNone.java index 1ef1763..480650d 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/security/IntegrityNone.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/security/IntegrityNone.java @@ -38,7 +38,8 @@ public IntegrityNone() { @Override public void initialize(byte[] sik) throws InvalidKeyException { - this.sik = sik; + // No MAC to initialize: generateAuthCode() is overridden and never uses the key + setSik(sik); } @Override diff --git a/src/main/java/org/metricshub/ipmi/core/coding/security/SecurityConstants.java b/src/main/java/org/metricshub/ipmi/core/coding/security/SecurityConstants.java index 7213535..f7f9b8c 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/security/SecurityConstants.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/security/SecurityConstants.java @@ -28,73 +28,72 @@ * Set of constants. Byte constants are encoded as pseudo unsigned bytes. * SecurityConstants doesn't use {@link TypeConverter} because fields need to be * runtime constants. - * + * * @see TypeConverter#byteToInt(byte) * @see TypeConverter#intToByte(int) */ public final class SecurityConstants { - /** - * Authentication algorithm = RAKP-none - */ - public static final byte AA_RAKP_NONE = 0x0; - /** - * Authentication algorithm = RAKP-HMAC-SHA1 - */ - public static final byte AA_RAKP_HMAC_SHA1 = 0x1; - /** - * Authentication algorithm = RAKP-HMAC-MD5 - */ - public static final byte AA_RAKP_HMAC_MD5 = 0x2; - /** - * Authentication algorithm = RAKP-HMAC-SHA256 - */ - public static final byte AA_RAKP_HMAC_SHA256 = 0x3; + /** + * Authentication algorithm = RAKP-none + */ + public static final byte AA_RAKP_NONE = 0x0; + /** + * Authentication algorithm = RAKP-HMAC-SHA1 + */ + public static final byte AA_RAKP_HMAC_SHA1 = 0x1; + /** + * Authentication algorithm = RAKP-HMAC-MD5 + */ + public static final byte AA_RAKP_HMAC_MD5 = 0x2; + /** + * Authentication algorithm = RAKP-HMAC-SHA256 + */ + public static final byte AA_RAKP_HMAC_SHA256 = 0x3; - /** - * Integrity algorithm = none - */ - public static final byte IA_NONE = 0x0; + /** + * Integrity algorithm = none + */ + public static final byte IA_NONE = 0x0; - /** - * Integrity algorithm = HMAC-SHA1-96 - */ - public static final byte IA_HMAC_SHA1_96 = 0x1; + /** + * Integrity algorithm = HMAC-SHA1-96 + */ + public static final byte IA_HMAC_SHA1_96 = 0x1; - /** - * Integrity algorithm = HMAC-MD5-128 - */ - public static final byte IA_HMAC_MD5_128 = 0x2; + /** + * Integrity algorithm = HMAC-MD5-128 + */ + public static final byte IA_HMAC_MD5_128 = 0x2; - /** - * Integrity algorithm = MD5-128 - */ - public static final byte IA_MD5_128 = 0x3; + /** + * Integrity algorithm = MD5-128 + */ + public static final byte IA_MD5_128 = 0x3; - /** - * Integrity algorithm = HMAC-SHA256-128 - */ - public static final byte IA_HMAC_SHA256_128 = 0x4; + /** + * Integrity algorithm = HMAC-SHA256-128 + */ + public static final byte IA_HMAC_SHA256_128 = 0x4; - /** - * Confidentiality algorithm = None - */ - public static final byte CA_NONE = 0x0; + /** + * Confidentiality algorithm = None + */ + public static final byte CA_NONE = 0x0; - /** - * Confidentiality algorithm = AES-CBC-128 - */ - public static final byte CA_AES_CBC128 = 0x1; + /** + * Confidentiality algorithm = AES-CBC-128 + */ + public static final byte CA_AES_CBC128 = 0x1; - /** - * Confidentiality algorithm = xRC4-128 - */ - public static final byte CA_XRC4_128 = 0x2; + /** + * Confidentiality algorithm = xRC4-128 + */ + public static final byte CA_XRC4_128 = 0x2; - /** - * Confidentiality algorithm = xRC4-40 - */ - public static final byte CA_XRC4_40 = 0x3; + /** + * Confidentiality algorithm = xRC4-40 + */ + public static final byte CA_XRC4_40 = 0x3; - private SecurityConstants() { - } + private SecurityConstants() {} } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/security/package-info.java b/src/main/java/org/metricshub/ipmi/core/coding/security/package-info.java index 0bff2ad..366f4be 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/security/package-info.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/security/package-info.java @@ -1,8 +1,11 @@ /** * Authentication, confidentiality and integrity algorithms. - * To implement custom authentication algorithm extend {@link org.metricshub.ipmi.core.coding.security.AuthenticationAlgorithm} class. - * To implement custom confidentiality algorithm extend {@link org.metricshub.ipmi.core.coding.security.ConfidentialityAlgorithm} class. - * To implement custom integrity algorithm extend {@link org.metricshub.ipmi.core.coding.security.IntegrityAlgorithm} class. + * To implement custom authentication algorithm extend + * {@link org.metricshub.ipmi.core.coding.security.AuthenticationAlgorithm} class. + * To implement custom confidentiality algorithm extend + * {@link org.metricshub.ipmi.core.coding.security.ConfidentialityAlgorithm} class. + * To implement custom integrity algorithm extend {@link org.metricshub.ipmi.core.coding.security.IntegrityAlgorithm} + * class. */ package org.metricshub.ipmi.core.coding.security; /*- diff --git a/src/main/java/org/metricshub/ipmi/core/coding/sol/SolCoder.java b/src/main/java/org/metricshub/ipmi/core/coding/sol/SolCoder.java index 5417891..32416fd 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/sol/SolCoder.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/sol/SolCoder.java @@ -51,132 +51,159 @@ */ public class SolCoder extends PayloadCoder { - private final byte[] message; - private final byte ackNackSequenceNumber; - private final byte acceptedCharacters; - private final SolAckState ackState; - private final Set operations; - private boolean acknowledgeOnly; - - - /** - * Creates new {@link SolCoder}. Use this constructor if you want to send character data, operations and ACK/NACK in single packet. - * - * @param message - * data to send as byte array - * @param ackNackSequenceNumber - * sequence number of packet that is ACKd/NACKd - * @param acceptedCharacters - * number of characters accepted from the ACKd/NACKd packet - * @param ackState - * actual acknowledge state - {@link SolAckState#ACK} or {@link SolAckState#NACK} - * @param operations - * set of operations to invoke on remote serial port - * @param cipherSuite - * {@link CipherSuite} containing authentication, confidentiality and integrity algorithms for this session - */ - public SolCoder(byte[] message, byte ackNackSequenceNumber, byte acceptedCharacters, SolAckState ackState, - Set operations, CipherSuite cipherSuite) { - super(IpmiVersion.V20, cipherSuite, AuthenticationType.RMCPPlus); - this.message = message; - this.ackNackSequenceNumber = ackNackSequenceNumber; - this.acceptedCharacters = acceptedCharacters; - this.ackState = ackState; - this.operations = operations; - } - - /** - * Creates new {@link SolCoder}. Use this constructor for character data only packets (no ACK/NACK and no operations will be sent). - * - * @param message - * data to send as byte array - * @param cipherSuite - * {@link CipherSuite} containing authentication, confidentiality and integrity algorithms for this session. - */ - public SolCoder(byte[] message, CipherSuite cipherSuite) { - this(message, (byte) 0, (byte) 0, SolAckState.ACK, new HashSet(), cipherSuite); - } - - /** - * Creates new {@link SolCoder}. Use this constructor for packets that should only invoke operations on remote serial port. - * - * @param operations - * set of operations to invoke on remote serial port. - * @param cipherSuite - * {@link CipherSuite} containing authentication, confidentiality and integrity algorithms for this session - */ - public SolCoder(Set operations, CipherSuite cipherSuite) { - this(new byte[] { '\0' }, (byte) 0, (byte) 0, SolAckState.ACK, operations, cipherSuite); - } - - /** - * Creates new {@link SolCoder}. Use this constructor for ACK/NACK packet, that only sends ACK/NACK for specific remote message. - * - * @param ackNackSequenceNumber - * sequence number of packet that is ACKd/NACKd - * @param acceptedCharacters - * number of characters accepted from the ACKd/NACKd packet - * @param ackState - * actual acknowledge state - {@link SolAckState#ACK} or {@link SolAckState#NACK} - * @param cipherSuite - * {@link CipherSuite} containing authentication, confidentiality and integrity algorithms for this session. - */ - public SolCoder(byte ackNackSequenceNumber, byte acceptedCharacters, SolAckState ackState, CipherSuite cipherSuite) { - this(null, ackNackSequenceNumber, acceptedCharacters, ackState, new HashSet(), cipherSuite); - - this.acknowledgeOnly = true; - } - - @Override - public PayloadType getSupportedPayloadType() { - return PayloadType.Sol; - } - - @Override - protected IpmiPayload preparePayload(int sequenceNumber) throws NoSuchAlgorithmException, InvalidKeyException { - byte actualSequenceNumber = acknowledgeOnly ? 0 : TypeConverter.intToByte(sequenceNumber); - - SolOutboundMessage request = new SolOutboundMessage(actualSequenceNumber, ackNackSequenceNumber, acceptedCharacters, - new SolOutboundOperationField(ackState, operations)); - - if (message != null && message.length > 0) { - request.setData(message); - } - - return request; - } - - @Override - public ResponseData getResponseData(IpmiMessage message) throws IPMIException, NoSuchAlgorithmException, InvalidKeyException { - final SolInboundMessage payload = (SolInboundMessage) message.getPayload(); - SolInboundStatusField statusField = payload.getStatusField(); - - return new SolResponseData(payload.getAckNackSequenceNumber(), statusField.getAckState(), statusField.getStatuses(), payload.getAcceptedCharacterCount()); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - SolCoder solCoder = (SolCoder) o; - - if (ackNackSequenceNumber != solCoder.ackNackSequenceNumber) return false; - if (acceptedCharacters != solCoder.acceptedCharacters) return false; - if (acknowledgeOnly != solCoder.acknowledgeOnly) return false; - if (!Arrays.equals(message, solCoder.message)) return false; - if (ackState != solCoder.ackState) return false; - return operations != null ? operations.equals(solCoder.operations) : solCoder.operations == null; - } - - @Override - public int hashCode() { - int result = Arrays.hashCode(message); - result = 31 * result + (int) ackNackSequenceNumber; - result = 31 * result + (int) acceptedCharacters; - result = 31 * result + (ackState != null ? ackState.hashCode() : 0); - result = 31 * result + (operations != null ? operations.hashCode() : 0); - result = 31 * result + (acknowledgeOnly ? 1 : 0); - return result; - } + private final byte[] message; + private final byte ackNackSequenceNumber; + private final byte acceptedCharacters; + private final SolAckState ackState; + private final Set operations; + private boolean acknowledgeOnly; + + /** + * Creates new {@link SolCoder}. Use this constructor if you want to send character data, operations and ACK/NACK in + * single packet. + * + * @param message + * data to send as byte array + * @param ackNackSequenceNumber + * sequence number of packet that is ACKd/NACKd + * @param acceptedCharacters + * number of characters accepted from the ACKd/NACKd packet + * @param ackState + * actual acknowledge state - {@link SolAckState#ACK} or {@link SolAckState#NACK} + * @param operations + * set of operations to invoke on remote serial port + * @param cipherSuite + * {@link CipherSuite} containing authentication, confidentiality and integrity algorithms for this session + */ + public SolCoder(byte[] message, byte ackNackSequenceNumber, byte acceptedCharacters, SolAckState ackState, + Set operations, CipherSuite cipherSuite) { + super(IpmiVersion.V20, cipherSuite, AuthenticationType.RMCPPlus); + this.message = message; + this.ackNackSequenceNumber = ackNackSequenceNumber; + this.acceptedCharacters = acceptedCharacters; + this.ackState = ackState; + this.operations = operations; + } + + /** + * Creates new {@link SolCoder}. Use this constructor for character data only packets (no ACK/NACK and no operations + * will be sent). + * + * @param message + * data to send as byte array + * @param cipherSuite + * {@link CipherSuite} containing authentication, confidentiality and integrity algorithms for this session. + */ + public SolCoder(byte[] message, CipherSuite cipherSuite) { + this(message, (byte) 0, (byte) 0, SolAckState.ACK, new HashSet(), cipherSuite); + } + + /** + * Creates new {@link SolCoder}. Use this constructor for packets that should only invoke operations on remote serial + * port. + * + * @param operations + * set of operations to invoke on remote serial port. + * @param cipherSuite + * {@link CipherSuite} containing authentication, confidentiality and integrity algorithms for this session + */ + public SolCoder(Set operations, CipherSuite cipherSuite) { + this(new byte[] { '\0' }, (byte) 0, (byte) 0, SolAckState.ACK, operations, cipherSuite); + } + + /** + * Creates new {@link SolCoder}. Use this constructor for ACK/NACK packet, that only sends ACK/NACK for specific + * remote message. + * + * @param ackNackSequenceNumber + * sequence number of packet that is ACKd/NACKd + * @param acceptedCharacters + * number of characters accepted from the ACKd/NACKd packet + * @param ackState + * actual acknowledge state - {@link SolAckState#ACK} or {@link SolAckState#NACK} + * @param cipherSuite + * {@link CipherSuite} containing authentication, confidentiality and integrity algorithms for this session. + */ + public SolCoder(byte ackNackSequenceNumber, byte acceptedCharacters, SolAckState ackState, CipherSuite cipherSuite) { + this(null, ackNackSequenceNumber, acceptedCharacters, ackState, new HashSet(), cipherSuite); + + this.acknowledgeOnly = true; + } + + @Override + public PayloadType getSupportedPayloadType() { + return PayloadType.Sol; + } + + @Override + protected IpmiPayload preparePayload(int sequenceNumber) throws NoSuchAlgorithmException, InvalidKeyException { + byte actualSequenceNumber = acknowledgeOnly ? 0 : TypeConverter.intToByte(sequenceNumber); + + SolOutboundMessage request = new SolOutboundMessage( + actualSequenceNumber, + ackNackSequenceNumber, + acceptedCharacters, + new SolOutboundOperationField(ackState, operations)); + + if (message != null && message.length > 0) { + request.setData(message); + } + + return request; + } + + @Override + public ResponseData getResponseData(IpmiMessage ipmiMessage) + throws IPMIException, + NoSuchAlgorithmException, + InvalidKeyException { + final SolInboundMessage payload = (SolInboundMessage) ipmiMessage.getPayload(); + SolInboundStatusField statusField = payload.getStatusField(); + + return new SolResponseData( + payload.getAckNackSequenceNumber(), + statusField.getAckState(), + statusField.getStatuses(), + payload.getAcceptedCharacterCount()); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + SolCoder solCoder = (SolCoder) o; + + if (ackNackSequenceNumber != solCoder.ackNackSequenceNumber) { + return false; + } + if (acceptedCharacters != solCoder.acceptedCharacters) { + return false; + } + if (acknowledgeOnly != solCoder.acknowledgeOnly) { + return false; + } + if (!Arrays.equals(message, solCoder.message)) { + return false; + } + if (ackState != solCoder.ackState) { + return false; + } + return operations != null ? operations.equals(solCoder.operations) : solCoder.operations == null; + } + + @Override + public int hashCode() { + int result = Arrays.hashCode(message); + result = 31 * result + (int) ackNackSequenceNumber; + result = 31 * result + (int) acceptedCharacters; + result = 31 * result + (ackState != null ? ackState.hashCode() : 0); + result = 31 * result + (operations != null ? operations.hashCode() : 0); + result = 31 * result + (acknowledgeOnly ? 1 : 0); + return result; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/coding/sol/SolResponseData.java b/src/main/java/org/metricshub/ipmi/core/coding/sol/SolResponseData.java index 81efd6d..ae949ec 100644 --- a/src/main/java/org/metricshub/ipmi/core/coding/sol/SolResponseData.java +++ b/src/main/java/org/metricshub/ipmi/core/coding/sol/SolResponseData.java @@ -33,65 +33,66 @@ */ public class SolResponseData implements ResponseData { - /** - * Sequence number of corresponding request message. - */ - private final byte requestSequenceNumber; + /** + * Sequence number of corresponding request message. + */ + private final byte requestSequenceNumber; - /** - * Information if corresponding message was ACKd or NACKd by remote system. - */ - private final SolAckState acknowledgeState; + /** + * Information if corresponding message was ACKd or NACKd by remote system. + */ + private final SolAckState acknowledgeState; - /** - * Set of statuses returned by the remote system in a response for corresponging message. - */ - private final Set statuses; + /** + * Set of statuses returned by the remote system in a response for corresponging message. + */ + private final Set statuses; - /** - * Number of characters accepted from the corresponding message. - */ - private final byte acceptedCharactersNumber; + /** + * Number of characters accepted from the corresponding message. + */ + private final byte acceptedCharactersNumber; - /** - * Creates new instance of {@link SolResponseData} filled with given data. - * - * @param acknowledgeState - * Acknowledge status for corresponding request message - * @param statuses - * Set of statuses - */ - public SolResponseData(byte requestSequenceNumber, SolAckState acknowledgeState, Set statuses, byte acceptedCharactersNumber) { - this.requestSequenceNumber = requestSequenceNumber; - this.acknowledgeState = acknowledgeState; - this.statuses = statuses; - this.acceptedCharactersNumber = acceptedCharactersNumber; - } + /** + * Creates new instance of {@link SolResponseData} filled with given data. + * + * @param acknowledgeState + * Acknowledge status for corresponding request message + * @param statuses + * Set of statuses + */ + public SolResponseData(byte requestSequenceNumber, SolAckState acknowledgeState, Set statuses, + byte acceptedCharactersNumber) { + this.requestSequenceNumber = requestSequenceNumber; + this.acknowledgeState = acknowledgeState; + this.statuses = statuses; + this.acceptedCharactersNumber = acceptedCharactersNumber; + } - public byte getRequestSequenceNumber() { - return requestSequenceNumber; - } + public byte getRequestSequenceNumber() { + return requestSequenceNumber; + } - public SolAckState getAcknowledgeState() { - return acknowledgeState; - } + public SolAckState getAcknowledgeState() { + return acknowledgeState; + } - public Set getStatuses() { - return statuses; - } + public Set getStatuses() { + return statuses; + } - public byte getAcceptedCharactersNumber() { - return acceptedCharactersNumber; - } + public byte getAcceptedCharactersNumber() { + return acceptedCharactersNumber; + } - @Override - public String toString() { - final StringBuilder sb = new StringBuilder("SolResponseData{"); - sb.append("requestSequenceNumber=").append(requestSequenceNumber); - sb.append(", acknowledgeState=").append(acknowledgeState); - sb.append(", statuses=").append(statuses); - sb.append(", acceptedCharactersNumber=").append(acceptedCharactersNumber); - sb.append('}'); - return sb.toString(); - } + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("SolResponseData{"); + sb.append("requestSequenceNumber=").append(requestSequenceNumber); + sb.append(", acknowledgeState=").append(acknowledgeState); + sb.append(", statuses=").append(statuses); + sb.append(", acceptedCharactersNumber=").append(acceptedCharactersNumber); + sb.append('}'); + return sb.toString(); + } } diff --git a/src/main/java/org/metricshub/ipmi/core/common/ByteBuffer.java b/src/main/java/org/metricshub/ipmi/core/common/ByteBuffer.java index 16af863..81b67d3 100644 --- a/src/main/java/org/metricshub/ipmi/core/common/ByteBuffer.java +++ b/src/main/java/org/metricshub/ipmi/core/common/ByteBuffer.java @@ -24,133 +24,134 @@ /** * {@link ByteBuffer} is a wrapper for byte[], and allows to safely read and write from the buffer. - * {@link ByteBuffer} is thread safe and guarantees proper handling of subsequent reads and writes, if they are within availabla buffer size. + * {@link ByteBuffer} is thread safe and guarantees proper handling of subsequent reads and writes, if they are within + * availabla buffer size. */ public class ByteBuffer { - /** - * Main buffer, in which all data is stored. - */ - private byte[] buffer; - - /** - * Current position of read marker. - */ - private int readMarker; - - /** - * Current position of write marker. - */ - private int writeMarker; - - /** - * Allocate new {@link ByteBuffer} with given size. - * - * @param capacity - * max capacity of constructed buffer. - */ - public ByteBuffer(int capacity) { - if (capacity <= 0) { - throw new IllegalArgumentException("Buffer must have positive capacity"); - } - - buffer = new byte[capacity]; - readMarker = 0; - writeMarker = 0; - } - - /** - * Attempts to write given byte array to this {@link ByteBuffer}. - * Writes as many bytes as it can, so that partial data from given array can be written - * if not available space for whole array is found in buffer. - * - * @param bytes - * bytes to write - * - * @return number of bytes that were actualy written - */ - public synchronized int write(byte[] bytes) { - if (shouldRewindBuffer(bytes)) { - rewind(); - } - - int actualBytesToWrite = Math.min(bytes.length, buffer.length - writeMarker); - - System.arraycopy(bytes, 0, buffer, writeMarker, actualBytesToWrite); - - writeMarker += actualBytesToWrite; - - return actualBytesToWrite; - } - - /** - * Attempts to read given number of bytes from this {@link ByteBuffer}. - * If buffer currently contains less bytes than requested, this method reads only available number of bytes. - * - * @param numberOfBytes - * requested number of bytes to read - * @return actual bytes that could be read from this buffer. - */ - public synchronized byte[] read(int numberOfBytes) { - int actualNumberOfBytes = Math.min(numberOfBytes, size()); - byte[] result = new byte[actualNumberOfBytes]; - - System.arraycopy(buffer, readMarker, result, 0, result.length); - - readMarker += actualNumberOfBytes; - - return result; - } - - /** - * Returns current size of the buffer (number of available data to read). - * - * @return size of the buffer in bytes - */ - public synchronized int size() { - return writeMarker - readMarker; - } - - /** - * Returns max capacity of the buffer (number of total data that can be stored in the buffer). - * - * @return capacity of the buffer in bytes - */ - public synchronized int capacity() { - return buffer.length; - } - - /** - * Returns remainig space in the buffer (number of bytes that can still be written to this buffer until it gets full). - * - * @return remaining free space in this buffer - */ - public synchronized int remainingSpace() { - return capacity() - size(); - } - - /** - * Check if buffer should be rewind in order to write given byte array. - * - * @param bytesToWrite - * byte array that we want to write to a buffer - * @return true if buffer can and should be rewind, false otherwise - */ - private boolean shouldRewindBuffer(byte[] bytesToWrite) { - return bytesToWrite.length > buffer.length - writeMarker && readMarker > 0; - } - - /** - * Moves all unread bytes to the beginning of the buffer, removing bytes that are already read and freeing space for new writes. - */ - private void rewind() { - int currentSize = size(); - - byte[] newBuffer = new byte[capacity()]; - System.arraycopy(buffer, readMarker, newBuffer, 0, currentSize); - buffer = newBuffer; - - readMarker = 0; - writeMarker = currentSize; - } + /** + * Main buffer, in which all data is stored. + */ + private byte[] buffer; + + /** + * Current position of read marker. + */ + private int readMarker; + + /** + * Current position of write marker. + */ + private int writeMarker; + + /** + * Allocate new {@link ByteBuffer} with given size. + * + * @param capacity + * max capacity of constructed buffer. + */ + public ByteBuffer(int capacity) { + if (capacity <= 0) { + throw new IllegalArgumentException("Buffer must have positive capacity"); + } + + buffer = new byte[capacity]; + readMarker = 0; + writeMarker = 0; + } + + /** + * Attempts to write given byte array to this {@link ByteBuffer}. + * Writes as many bytes as it can, so that partial data from given array can be written + * if not available space for whole array is found in buffer. + * + * @param bytes + * bytes to write + * @return number of bytes that were actualy written + */ + public synchronized int write(byte[] bytes) { + if (shouldRewindBuffer(bytes)) { + rewind(); + } + + int actualBytesToWrite = Math.min(bytes.length, buffer.length - writeMarker); + + System.arraycopy(bytes, 0, buffer, writeMarker, actualBytesToWrite); + + writeMarker += actualBytesToWrite; + + return actualBytesToWrite; + } + + /** + * Attempts to read given number of bytes from this {@link ByteBuffer}. + * If buffer currently contains less bytes than requested, this method reads only available number of bytes. + * + * @param numberOfBytes + * requested number of bytes to read + * @return actual bytes that could be read from this buffer. + */ + public synchronized byte[] read(int numberOfBytes) { + int actualNumberOfBytes = Math.min(numberOfBytes, size()); + byte[] result = new byte[actualNumberOfBytes]; + + System.arraycopy(buffer, readMarker, result, 0, result.length); + + readMarker += actualNumberOfBytes; + + return result; + } + + /** + * Returns current size of the buffer (number of available data to read). + * + * @return size of the buffer in bytes + */ + public synchronized int size() { + return writeMarker - readMarker; + } + + /** + * Returns max capacity of the buffer (number of total data that can be stored in the buffer). + * + * @return capacity of the buffer in bytes + */ + public synchronized int capacity() { + return buffer.length; + } + + /** + * Returns remainig space in the buffer (number of bytes that can still be written to this buffer until it gets full). + * + * @return remaining free space in this buffer + */ + public synchronized int remainingSpace() { + return capacity() - size(); + } + + /** + * Check if buffer should be rewind in order to write given byte array. + * + * @param bytesToWrite + * byte array that we want to write to a buffer + * @return true if buffer can and should be rewind, false otherwise + */ + private boolean shouldRewindBuffer(byte[] bytesToWrite) { + return bytesToWrite.length > buffer.length - writeMarker && readMarker > 0; + } + + /** + * Moves all unread bytes to the beginning of the buffer, removing bytes that are already read and freeing space for + * new writes. + */ + private void rewind() { + int currentSize = size(); + + byte[] newBuffer = new byte[capacity()]; + System.arraycopy(buffer, readMarker, newBuffer, 0, currentSize); + buffer = newBuffer; + + readMarker = 0; + writeMarker = currentSize; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/common/Constants.java b/src/main/java/org/metricshub/ipmi/core/common/Constants.java index e5eda25..c67467f 100644 --- a/src/main/java/org/metricshub/ipmi/core/common/Constants.java +++ b/src/main/java/org/metricshub/ipmi/core/common/Constants.java @@ -27,13 +27,12 @@ */ public final class Constants { - /** - * The port BMC is listening for IPMI messages on. - */ - public static final int IPMI_PORT = 0x26F; + /** + * The port BMC is listening for IPMI messages on. + */ + public static final int IPMI_PORT = 0x26F; - public static final int TIMEOUT = 500; + public static final int TIMEOUT = 500; - private Constants() { - } + private Constants() {} } diff --git a/src/main/java/org/metricshub/ipmi/core/common/MessageComposer.java b/src/main/java/org/metricshub/ipmi/core/common/MessageComposer.java index 0ab4d66..f9d5c74 100644 --- a/src/main/java/org/metricshub/ipmi/core/common/MessageComposer.java +++ b/src/main/java/org/metricshub/ipmi/core/common/MessageComposer.java @@ -25,55 +25,55 @@ /** * Class used for composing byte messages aout from smaller byte subarrays. */ -public class MessageComposer { +public final class MessageComposer { - private final byte[] message; - private int pointer = 0; + private final byte[] message; + private int pointer = 0; - public static MessageComposer get(int messageSize) { - return new MessageComposer(messageSize); - } + public static MessageComposer get(int messageSize) { + return new MessageComposer(messageSize); + } - private MessageComposer(int messageSize) { - if (messageSize < 0) { - throw new IllegalArgumentException("Message size cannot be negative"); - } + private MessageComposer(int messageSize) { + if (messageSize < 0) { + throw new IllegalArgumentException("Message size cannot be negative"); + } - this.message = new byte[messageSize]; - } + this.message = new byte[messageSize]; + } - /** - * Append single-byte field to the message. - * - * @param fieldData - * single byte containing data that should be appended - */ - public MessageComposer appendField(byte fieldData) { - message[pointer++] = fieldData; + /** + * Append single-byte field to the message. + * + * @param fieldData + * single byte containing data that should be appended + */ + public MessageComposer appendField(byte fieldData) { + message[pointer++] = fieldData; - return this; - } + return this; + } - /** - * Append byte arrach field to the message. - * - * @param fieldData - * byte array containing data that should be appended - */ - public MessageComposer appendField(byte[] fieldData) { - System.arraycopy(fieldData, 0, message, pointer, fieldData.length); + /** + * Append byte arrach field to the message. + * + * @param fieldData + * byte array containing data that should be appended + */ + public MessageComposer appendField(byte[] fieldData) { + System.arraycopy(fieldData, 0, message, pointer, fieldData.length); - pointer += fieldData.length; + pointer += fieldData.length; - return this; - } + return this; + } - /** - * Returns final message consisting all messages appended till now. - * - * @return composed message - */ - public byte[] getMessage() { - return message; - } + /** + * Returns final message consisting all messages appended till now. + * + * @return composed message + */ + public byte[] getMessage() { + return message; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/common/MessageReader.java b/src/main/java/org/metricshub/ipmi/core/common/MessageReader.java index 705cc7f..8aa3f23 100644 --- a/src/main/java/org/metricshub/ipmi/core/common/MessageReader.java +++ b/src/main/java/org/metricshub/ipmi/core/common/MessageReader.java @@ -27,27 +27,27 @@ */ public class MessageReader { - private final byte[] message; - private int pointer = 0; + private final byte[] message; + private int pointer = 0; - /** - * Create new instance of {@link MessageReader}, that will operate on given message. - */ - public MessageReader(byte[] message) { - if (message == null) { - throw new NullPointerException("Message cannot be null"); - } + /** + * Create new instance of {@link MessageReader}, that will operate on given message. + */ + public MessageReader(byte[] message) { + if (message == null) { + throw new NullPointerException("Message cannot be null"); + } - this.message = message; - } + this.message = message; + } - public byte[] readNextField(int fieldLength) { - byte[] fieldData = new byte[fieldLength]; - System.arraycopy(message, pointer, fieldData, 0, fieldLength); + public byte[] readNextField(int fieldLength) { + byte[] fieldData = new byte[fieldLength]; + System.arraycopy(message, pointer, fieldData, 0, fieldLength); - pointer += fieldLength; + pointer += fieldLength; - return fieldData; - } + return fieldData; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/common/PropertiesManager.java b/src/main/java/org/metricshub/ipmi/core/common/PropertiesManager.java index b2e4f12..84384a4 100644 --- a/src/main/java/org/metricshub/ipmi/core/common/PropertiesManager.java +++ b/src/main/java/org/metricshub/ipmi/core/common/PropertiesManager.java @@ -32,46 +32,46 @@ public final class PropertiesManager { - private static PropertiesManager instance; + private static PropertiesManager instance; - private Map properties; + private Map properties; - private Logger logger = LoggerFactory.getLogger(PropertiesManager.class); + private Logger logger = LoggerFactory.getLogger(PropertiesManager.class); - private PropertiesManager() { - properties = new HashMap(); + private PropertiesManager() { + properties = new HashMap(); - loadProperties("/connection.properties"); - loadProperties("/vxipmi.properties"); - } + loadProperties("/connection.properties"); + loadProperties("/vxipmi.properties"); + } - public static PropertiesManager getInstance() { - if (instance == null) { - instance = new PropertiesManager(); - } - return instance; - } + public static PropertiesManager getInstance() { + if (instance == null) { + instance = new PropertiesManager(); + } + return instance; + } - private void loadProperties(String name) { - try { - Properties props = new Properties(); - props.load(getClass().getResourceAsStream(name)); + private void loadProperties(String name) { + try { + Properties props = new Properties(); + props.load(getClass().getResourceAsStream(name)); - for (Object key : props.keySet()) { - this.properties.put(key.toString(), props.getProperty(key.toString())); - } + for (Object key : props.keySet()) { + this.properties.put(key.toString(), props.getProperty(key.toString())); + } - } catch (IOException e) { - logger.error(e.getMessage(), e); - } - } + } catch (IOException e) { + logger.error(e.getMessage(), e); + } + } - public String getProperty(String key) { - logger.info("Getting " + key + ": " + properties.get(key)); - return properties.get(key); - } + public String getProperty(String key) { + logger.info("Getting " + key + ": " + properties.get(key)); + return properties.get(key); + } - public void setProperty(String key, String value) { - properties.put(key, value); - } + public void setProperty(String key, String value) { + properties.put(key, value); + } } diff --git a/src/main/java/org/metricshub/ipmi/core/common/Randomizer.java b/src/main/java/org/metricshub/ipmi/core/common/Randomizer.java index 2096b39..608bf4e 100644 --- a/src/main/java/org/metricshub/ipmi/core/common/Randomizer.java +++ b/src/main/java/org/metricshub/ipmi/core/common/Randomizer.java @@ -27,18 +27,16 @@ /** * Utility class for generating random numbers. - * */ public final class Randomizer { - private static Random rand = new Random(new Date().getTime()); + private static Random rand = new Random(new Date().getTime()); - private Randomizer() { - } + private Randomizer() {} - /** - * @return Generated random {@link Integer} - */ - public static int getInt() { - return rand.nextInt(); - } + /** + * @return Generated random {@link Integer} + */ + public static int getInt() { + return rand.nextInt(); + } } diff --git a/src/main/java/org/metricshub/ipmi/core/common/TypeConverter.java b/src/main/java/org/metricshub/ipmi/core/common/TypeConverter.java index cefbee5..9a0d722 100644 --- a/src/main/java/org/metricshub/ipmi/core/common/TypeConverter.java +++ b/src/main/java/org/metricshub/ipmi/core/common/TypeConverter.java @@ -31,391 +31,414 @@ */ public final class TypeConverter { - /** - * Array that maps bit position to its value in a single little-endian byte. - */ - private static final int[] SINGLE_BIT_MASKS = new int[] {1, 2, 4, 8, 16, 32, 64, 128}; - - private static final int MAX_WORD_SIZE = 65535; - - private TypeConverter() { - } - - /** - * Converts int to byte array in BigEndian convention. Encodes unsigned byte - * in Java byte representation. - * - * @see TypeConverter#intToByte(int) - * @param value - * @return int converted to byte array - */ - public static byte[] intToByteArray(int value) { - byte[] b = new byte[4]; - for (int i = 0; i < 4; i++) { - int offset = (b.length - 1 - i) * 8; - b[i] = intToByte(((value >>> offset) & 0xFF)); - } - return b; - } - - /** - * Converts byte array in BigEndian convention to int. Encodes unsigned - * byte in Java byte representation. - * - * @see TypeConverter#intToByte(int) - * @param value - * Byte array holding values. - * @return Byte array converted to int in a big endian convention. - * @throws IndexOutOfBoundsException - * when value's length is not 4. - */ - public static int byteArrayToInt(byte[] value) { - if (value.length != 4) { - throw new IndexOutOfBoundsException("Value's length must be 4."); - } - int result = 0; - for (int i = 0; i < 4; i++) { - int offset = (value.length - 1 - i) * 8; - result |= byteToInt(value[i]) << offset; - } - return result; - } - - /** - * Converts int to byte array in LittleEndian convention. Encodes unsigned - * byte in Java byte representation. - * - * @see TypeConverter#intToByte(int) - * @param value - * @return int converted to byte array - */ - public static byte[] intToLittleEndianByteArray(int value) { - byte[] b = new byte[4]; - for (int i = 3; i >= 0; i--) { - int offset = i * 8; - b[i] = intToByte(((value >>> offset) & 0xFF)); - } - return b; - } - - /** - * Converts byte array in LittleEndian convention to int. Encodes unsigned - * byte in Java byte representation. - * - * @see TypeConverter#intToByte(int) - * @param value - * Byte array holding values. - * @return Byte array converted to int in a little endian convention. - * @throws IndexOutOfBoundsException - * when value's length is not 4. - */ - public static int littleEndianByteArrayToInt(byte[] value) { - if (value.length != 4) { - throw new IndexOutOfBoundsException("Value's length must be 4."); - } - int result = 0; - for (int i = 3; i >= 0; --i) { - int offset = 8 * i; - result |= byteToInt(value[i]) << offset; - } - return result; - } - - /** - * Because Java doesn't support unsigned byte values, simple type casting - * leads to overflows and wrong values. This function casts int to pseudo - * unsigned byte. - * - * @param value - * int value (must be in range 0-255) - * @return byte value - * @throws IllegalArgumentException - * when value is out of range. - */ - public static byte intToByte(int value) { - if (value > 255 || value < 0) { - throw new IllegalArgumentException("Value must be in range 0-255."); - } - // if value is less than 128 everything is fine - // if value would be out of Java byte's range, subtract 255, - // so it falls into negative byte's range and 2's compliment - // turns it into proper byte code - return value < 128 ? (byte) value : (byte) (value - 256); - } - - /** - * Because Java doesn't support unsigned byte values, simple type casting - * leads to overflows and wrong values. This function casts pseudo unsigned - * byte to int. - * - * @param value - * byte value - * @return int value - */ - public static int byteToInt(byte value) { - // if value is not less than 0 everything is fine - // if value is lesser than 0, it means that we encoded there a number - // greater than 127 - return value >= 0 ? (int) value : ((int) value) + 256; - } - - /** - * Converts int to BigEndian word (double bytes array). - * - * @param value - * integer value to be converted to word (2-bytes array). Must be between 0 and {@link TypeConverter#MAX_WORD_SIZE}. - * @return double bytes array - */ - public static byte[] intToWord(int value) { - if (value < 0 || value > MAX_WORD_SIZE) { - throw new IllegalArgumentException("Integer to convert to word must be between 0 and " + MAX_WORD_SIZE); - } - - byte[] tmpBytArray = intToByteArray(value); - return Arrays.copyOfRange(tmpBytArray, 2, tmpBytArray.length); - } - - /** - * Converts int to LittleEndian word (double bytes array). - * - * @param value - * integer value to be converted to word (2-bytes array). Must be between 0 and {@link TypeConverter#MAX_WORD_SIZE}. - * @return double bytes array - */ - public static byte[] intToLittleEndianWord(int value) { - if (value < 0 || value > MAX_WORD_SIZE) { - throw new IllegalArgumentException("Integer to convert to word must be between 0 and " + MAX_WORD_SIZE); - } - - byte[] tmpBytArray = intToLittleEndianByteArray(value); - return Arrays.copyOf(tmpBytArray, 2); - } - - /** - * Converts BigEndian word (double bytes array) to int. - * - * @param word - * double bytes array. - * @return int value - */ - public static int wordToInt(byte[] word) { - if (word == null || word.length != 2) { - throw new IllegalArgumentException("Word must consists of 2 bytes"); - } - - byte[] tmpBytArray = new byte[4]; - System.arraycopy(word, 0, tmpBytArray, 2, 2); - - return TypeConverter.byteArrayToInt(tmpBytArray); - } - - /** - * Converts LittleEndian word (double bytes array) to int. - * - * @param word - * double bytes array. - * @return int value - */ - public static int littleEndianWordToInt(byte[] word) { - if (word == null || word.length != 2) { - throw new IllegalArgumentException("Word must consists of 2 bytes"); - } - - byte[] tmpBytArray = new byte[4]; - System.arraycopy(word, 0, tmpBytArray, 0, 2); - - return TypeConverter.littleEndianByteArrayToInt(tmpBytArray); - } - - /** - * Converts BCD encoded byte with bits 7:4 holding the Least Significant - * digit of the revision and bits 3:0 holding the Most Significant bits. - * - * @param value - * decoded value - * @return decoded value - */ - public static int littleEndianBcdByteToInt(byte value) { - int lower = (byteToInt(value) & 0xf0) >> 4; - int higher = byteToInt(value) & 0x0f; - - return higher * 10 + lower; - } - - /** - * Decodes 2's complement value that is encoded on lesser than 16 number of - * bits. - * - * @param value - * - value to be decoded - * @param msb - * - 0-based index at which the encoded value begins - * @return decoded value - */ - public static int decode2sComplement(int value, int msb) { - int result = value; - boolean base = false; - if ((value & (0x1 << msb)) != 0) { - base = true; - } - for (int i = 31; i > msb; --i) { - int mask = 0x1 << i; - if (!base) { - result &= ~mask; - } else { - result |= mask; - } - } - return result; - } - - /** - * Decodes 1's complement value that is encoded on lesser than 16 number of - * bits. - * - * @param value - * - value to be decoded - * @param msb - * - 0-based index at which the encoded value begins - * @return decoded value - */ - public static int decode1sComplement(int value, int msb) { - int result = value; - boolean base = false; - if ((value & (0x1 << msb)) != 0) { - base = true; - } - if (base) { - - for (int i = 31; i > msb; --i) { - int mask = 0x1 << i; - result |= mask; - } - result = -(~result); - } - return result; - } - - /** - * Decodes text encoded in BCD plus format. - */ - public static String decodeBcdPlus(byte[] text) { - char[] result = new char[text.length * 2]; - - for (int i = 0; i < text.length; ++i) { - result[2 * i] = decodeBcdPlusChar(TypeConverter - .intToByte((TypeConverter.byteToInt(text[i]) & 0xf0) >> 4)); - result[2 * i + 1] = decodeBcdPlusChar(TypeConverter - .intToByte(TypeConverter.byteToInt(text[i]) & 0xf)); - } - - return new String(result); - } - - private static char decodeBcdPlusChar(byte ch) { - switch (TypeConverter.byteToInt(ch)) { - case 0x0: - return '0'; - case 0x1: - return '1'; - case 0x2: - return '2'; - case 0x3: - return '3'; - case 0x4: - return '4'; - case 0x5: - return '5'; - case 0x6: - return '6'; - case 0x7: - return '7'; - case 0x8: - return '8'; - case 0x9: - return '9'; - case 0xa: - return ' '; - case 0xb: - return '-'; - case 0xc: - return '.'; - case 0xd: - return ':'; - case 0xe: - return ','; - case 0xf: - return '_'; - default: - throw new IllegalArgumentException("Invalid ch value"); - } - } - - public static String decode6bitAscii(byte[] text) { - int cnt = text.length; - if (cnt % 3 != 0) { - cnt += 3 - cnt % 3; - } - - byte[] newText = new byte[cnt / 3 * 4]; - - int index = 0; - for (int i = 0; i < text.length; ++i) { - switch (i % 3) { - case 0: - newText[index++] = TypeConverter.intToByte(TypeConverter - .byteToInt(text[i]) & 0x3f); - newText[index] = TypeConverter.intToByte((TypeConverter - .byteToInt(text[i]) & 0xc0) >> 6); - break; - case 1: - newText[index++] |= TypeConverter.intToByte((TypeConverter - .byteToInt(text[i]) & 0xf) << 2); - newText[index] = TypeConverter.intToByte((TypeConverter - .byteToInt(text[i]) & 0xf0) >> 4); - break; - case 2: - newText[index++] |= TypeConverter.intToByte((TypeConverter - .byteToInt(text[i]) & 0x3) << 4); - newText[index++] = TypeConverter.intToByte((TypeConverter - .byteToInt(text[i]) & 0xfc) >> 2); - break; - default: - break; - } - } - - for (int i = 0; i < newText.length; ++i) { - newText[i] = TypeConverter.intToByte(TypeConverter - .byteToInt(newText[i]) + 0x20); - } - - return new String(newText, Charset.forName("US-ASCII")); - } - - /** - * Decodes date encoded as number of seconds from 00:00:00, January 1, 1970 - * GMT. - */ - public static Date decodeDate(int date) { - return new Date((long) date * 1000); - } - - /** - * Checks whether single bit on given position is set in given little-endian byte. - * - * @param position - * - position of bit to check. - * Allowed values are 0 - 7, where 0 is first (less significant) bit and 7 is last (most significant) bit. - * @param value - * - byte in which we check the bytes. - * @return - */ - public static boolean isBitSetOnPosition(int position, byte value) { - return ((value & SINGLE_BIT_MASKS[position]) > 0); - } - - public static byte setBitOnPosition(int position, byte value) { - return (byte) (value | SINGLE_BIT_MASKS[position]); - } + /** + * Array that maps bit position to its value in a single little-endian byte. + */ + private static final int[] SINGLE_BIT_MASKS = new int[] { 1, 2, 4, 8, 16, 32, 64, 128 }; + + private static final int MAX_WORD_SIZE = 65535; + + private TypeConverter() {} + + /** + * Converts int to byte array in BigEndian convention. Encodes unsigned byte + * in Java byte representation. + * + * @see TypeConverter#intToByte(int) + * @param value + * @return int converted to byte array + */ + public static byte[] intToByteArray(int value) { + byte[] b = new byte[4]; + for (int i = 0; i < 4; i++) { + int offset = (b.length - 1 - i) * 8; + b[i] = intToByte(((value >>> offset) & 0xFF)); + } + return b; + } + + /** + * Converts byte array in BigEndian convention to int. Encodes unsigned + * byte in Java byte representation. + * + * @see TypeConverter#intToByte(int) + * @param value + * Byte array holding values. + * @return Byte array converted to int in a big endian convention. + * @throws IndexOutOfBoundsException + * when value's length is not 4. + */ + public static int byteArrayToInt(byte[] value) { + if (value.length != 4) { + throw new IndexOutOfBoundsException("Value's length must be 4."); + } + int result = 0; + for (int i = 0; i < 4; i++) { + int offset = (value.length - 1 - i) * 8; + result |= byteToInt(value[i]) << offset; + } + return result; + } + + /** + * Converts int to byte array in LittleEndian convention. Encodes unsigned + * byte in Java byte representation. + * + * @see TypeConverter#intToByte(int) + * @param value + * @return int converted to byte array + */ + public static byte[] intToLittleEndianByteArray(int value) { + byte[] b = new byte[4]; + for (int i = 3; i >= 0; i--) { + int offset = i * 8; + b[i] = intToByte(((value >>> offset) & 0xFF)); + } + return b; + } + + /** + * Converts byte array in LittleEndian convention to int. Encodes unsigned + * byte in Java byte representation. + * + * @see TypeConverter#intToByte(int) + * @param value + * Byte array holding values. + * @return Byte array converted to int in a little endian convention. + * @throws IndexOutOfBoundsException + * when value's length is not 4. + */ + public static int littleEndianByteArrayToInt(byte[] value) { + if (value.length != 4) { + throw new IndexOutOfBoundsException("Value's length must be 4."); + } + int result = 0; + for (int i = 3; i >= 0; --i) { + int offset = 8 * i; + result |= byteToInt(value[i]) << offset; + } + return result; + } + + /** + * Because Java doesn't support unsigned byte values, simple type casting + * leads to overflows and wrong values. This function casts int to pseudo + * unsigned byte. + * + * @param value + * int value (must be in range 0-255) + * @return byte value + * @throws IllegalArgumentException + * when value is out of range. + */ + public static byte intToByte(int value) { + if (value > 255 || value < 0) { + throw new IllegalArgumentException("Value must be in range 0-255."); + } + // if value is less than 128 everything is fine + // if value would be out of Java byte's range, subtract 255, + // so it falls into negative byte's range and 2's compliment + // turns it into proper byte code + return value < 128 ? (byte) value : (byte) (value - 256); + } + + /** + * Because Java doesn't support unsigned byte values, simple type casting + * leads to overflows and wrong values. This function casts pseudo unsigned + * byte to int. + * + * @param value + * byte value + * @return int value + */ + public static int byteToInt(byte value) { + // if value is not less than 0 everything is fine + // if value is lesser than 0, it means that we encoded there a number + // greater than 127 + return value >= 0 ? (int) value : ((int) value) + 256; + } + + /** + * Converts int to BigEndian word (double bytes array). + * + * @param value + * integer value to be converted to word (2-bytes array). Must be between 0 and + * {@link TypeConverter#MAX_WORD_SIZE}. + * @return double bytes array + */ + public static byte[] intToWord(int value) { + if (value < 0 || value > MAX_WORD_SIZE) { + throw new IllegalArgumentException("Integer to convert to word must be between 0 and " + MAX_WORD_SIZE); + } + + byte[] tmpBytArray = intToByteArray(value); + return Arrays.copyOfRange(tmpBytArray, 2, tmpBytArray.length); + } + + /** + * Converts int to LittleEndian word (double bytes array). + * + * @param value + * integer value to be converted to word (2-bytes array). Must be between 0 and + * {@link TypeConverter#MAX_WORD_SIZE}. + * @return double bytes array + */ + public static byte[] intToLittleEndianWord(int value) { + if (value < 0 || value > MAX_WORD_SIZE) { + throw new IllegalArgumentException("Integer to convert to word must be between 0 and " + MAX_WORD_SIZE); + } + + byte[] tmpBytArray = intToLittleEndianByteArray(value); + return Arrays.copyOf(tmpBytArray, 2); + } + + /** + * Converts BigEndian word (double bytes array) to int. + * + * @param word + * double bytes array. + * @return int value + */ + public static int wordToInt(byte[] word) { + if (word == null || word.length != 2) { + throw new IllegalArgumentException("Word must consists of 2 bytes"); + } + + byte[] tmpBytArray = new byte[4]; + System.arraycopy(word, 0, tmpBytArray, 2, 2); + + return TypeConverter.byteArrayToInt(tmpBytArray); + } + + /** + * Converts LittleEndian word (double bytes array) to int. + * + * @param word + * double bytes array. + * @return int value + */ + public static int littleEndianWordToInt(byte[] word) { + if (word == null || word.length != 2) { + throw new IllegalArgumentException("Word must consists of 2 bytes"); + } + + byte[] tmpBytArray = new byte[4]; + System.arraycopy(word, 0, tmpBytArray, 0, 2); + + return TypeConverter.littleEndianByteArrayToInt(tmpBytArray); + } + + /** + * Converts BCD encoded byte with bits 7:4 holding the Least Significant + * digit of the revision and bits 3:0 holding the Most Significant bits. + * + * @param value + * decoded value + * @return decoded value + */ + public static int littleEndianBcdByteToInt(byte value) { + int lower = (byteToInt(value) & 0xf0) >> 4; + int higher = byteToInt(value) & 0x0f; + + return higher * 10 + lower; + } + + /** + * Decodes 2's complement value that is encoded on lesser than 16 number of + * bits. + * + * @param value + * - value to be decoded + * @param msb + * - 0-based index at which the encoded value begins + * @return decoded value + */ + public static int decode2sComplement(int value, int msb) { + int result = value; + boolean base = false; + if ((value & (0x1 << msb)) != 0) { + base = true; + } + for (int i = 31; i > msb; --i) { + int mask = 0x1 << i; + if (!base) { + result &= ~mask; + } else { + result |= mask; + } + } + return result; + } + + /** + * Decodes 1's complement value that is encoded on lesser than 16 number of + * bits. + * + * @param value + * - value to be decoded + * @param msb + * - 0-based index at which the encoded value begins + * @return decoded value + */ + public static int decode1sComplement(int value, int msb) { + int result = value; + boolean base = false; + if ((value & (0x1 << msb)) != 0) { + base = true; + } + if (base) { + + for (int i = 31; i > msb; --i) { + int mask = 0x1 << i; + result |= mask; + } + result = -(~result); + } + return result; + } + + /** + * Decodes text encoded in BCD plus format. + */ + public static String decodeBcdPlus(byte[] text) { + char[] result = new char[text.length * 2]; + + for (int i = 0; i < text.length; ++i) { + result[2 * i] = decodeBcdPlusChar( + TypeConverter + .intToByte((TypeConverter.byteToInt(text[i]) & 0xf0) >> 4)); + result[2 * i + 1] = decodeBcdPlusChar( + TypeConverter + .intToByte(TypeConverter.byteToInt(text[i]) & 0xf)); + } + + return new String(result); + } + + private static char decodeBcdPlusChar(byte ch) { + switch (TypeConverter.byteToInt(ch)) { + case 0x0: + return '0'; + case 0x1: + return '1'; + case 0x2: + return '2'; + case 0x3: + return '3'; + case 0x4: + return '4'; + case 0x5: + return '5'; + case 0x6: + return '6'; + case 0x7: + return '7'; + case 0x8: + return '8'; + case 0x9: + return '9'; + case 0xa: + return ' '; + case 0xb: + return '-'; + case 0xc: + return '.'; + case 0xd: + return ':'; + case 0xe: + return ','; + case 0xf: + return '_'; + default: + throw new IllegalArgumentException("Invalid ch value"); + } + } + + public static String decode6bitAscii(byte[] text) { + int cnt = text.length; + if (cnt % 3 != 0) { + cnt += 3 - cnt % 3; + } + + byte[] newText = new byte[cnt / 3 * 4]; + + int index = 0; + for (int i = 0; i < text.length; ++i) { + switch (i % 3) { + case 0: + newText[index++] = TypeConverter + .intToByte( + TypeConverter + .byteToInt(text[i]) + & 0x3f); + newText[index] = TypeConverter + .intToByte( + (TypeConverter + .byteToInt(text[i]) + & 0xc0) >> 6); + break; + case 1: + newText[index++] |= TypeConverter + .intToByte( + (TypeConverter + .byteToInt(text[i]) + & 0xf) << 2); + newText[index] = TypeConverter + .intToByte( + (TypeConverter + .byteToInt(text[i]) + & 0xf0) >> 4); + break; + case 2: + newText[index++] |= TypeConverter + .intToByte( + (TypeConverter + .byteToInt(text[i]) + & 0x3) << 4); + newText[index++] = TypeConverter + .intToByte( + (TypeConverter + .byteToInt(text[i]) + & 0xfc) >> 2); + break; + default: + break; + } + } + + for (int i = 0; i < newText.length; ++i) { + newText[i] = TypeConverter + .intToByte( + TypeConverter + .byteToInt(newText[i]) + 0x20); + } + + return new String(newText, Charset.forName("US-ASCII")); + } + + /** + * Decodes date encoded as number of seconds from 00:00:00, January 1, 1970 + * GMT. + */ + public static Date decodeDate(int date) { + return new Date((long) date * 1000); + } + + /** + * Checks whether single bit on given position is set in given little-endian byte. + * + * @param position + * - position of bit to check. + * Allowed values are 0 - 7, where 0 is first (less significant) bit and 7 is last (most significant) bit. + * @param value + * - byte in which we check the bytes. + * @return + */ + public static boolean isBitSetOnPosition(int position, byte value) { + return ((value & SINGLE_BIT_MASKS[position]) > 0); + } + + public static byte setBitOnPosition(int position, byte value) { + return (byte) (value | SINGLE_BIT_MASKS[position]); + } } diff --git a/src/main/java/org/metricshub/ipmi/core/connection/Connection.java b/src/main/java/org/metricshub/ipmi/core/connection/Connection.java index 04d2879..4f3e81f 100644 --- a/src/main/java/org/metricshub/ipmi/core/connection/Connection.java +++ b/src/main/java/org/metricshub/ipmi/core/connection/Connection.java @@ -82,126 +82,128 @@ * A connection with the specific remote host. */ public class Connection extends TimerTask implements MachineObserver { - private static final Logger logger = LoggerFactory.getLogger(Connection.class); - - private static final int DEFAULT_CIPHER_SUITE = 3; - private static final int SESSION_SEQUENCE_NUMBER_UPPER_BOUND = Integer.MAX_VALUE / 4; - private static final String ILLEGAL_CONNECTION_STATE_MESSAGE = "Illegal connection state: "; - - private List listeners; - private StateMachine stateMachine; - - /** - * Time in ms after which a message times out. - */ - private int timeout = -1; - private StateMachineAction lastAction; - private int sessionId; - private int managedSystemSessionId; - private byte[] sik; - - private int handle; - - public int getHandle() { - return handle; - } - - private Map messageHandlers; - - private Timer timer; - - private AtomicInteger currentSessionSequenceNumber; - - public int getTimeout() { - return timeout; - } - - public void setTimeout(int timeout) { - this.timeout = timeout; - - for (MessageHandler messageHandler : messageHandlers.values()) { - messageHandler.setTimeout(timeout); - } - } - - /** - * Creates the connection. - * - * @param messenger - * - {@link Messenger} associated with the proper - * {@link Constants#IPMI_PORT} - * @param handle - * - id of the connection - */ - public Connection(Messenger messenger, int handle) { - stateMachine = new StateMachine(messenger); - this.handle = handle; - listeners = new ArrayList(); - timeout = Integer.parseInt(PropertiesManager.getInstance().getProperty("timeout")); - messageHandlers = new EnumMap(PayloadType.class); - currentSessionSequenceNumber = new AtomicInteger(0); - } - - /** - * Registers the listener so it will receive notifications from this - * connection - * - * @param listener - * - {@link ConnectionListener} to processResponse - */ - public void registerListener(ConnectionListener listener) { - listeners.add(listener); - } - - /** - * Unregisters the {@link ConnectionListener} - * - * @param listener - * {@link ConnectionListener} to unregister - */ - public void unregisterListener(ConnectionListener listener) { - listeners.remove(listener); - } - - /** - * Starts the connection to the specified {@link InetAddress} - * - * @param address - * - IP address of the managed system - * @param pingPeriod - * - frequency of the no-op commands that will be sent to keep up - * the session - * @throws IOException - * - when properties file was not found - * @throws FileNotFoundException - * - when properties file was not found - * @see #disconnect() - */ - public void connect(InetAddress address, int port, long pingPeriod) - throws IOException { - connect(address, port, pingPeriod, false); - } - - /** - * Starts the connection to the specified {@link InetAddress} - * @param address - * - IP address of the managed system - * @param pingPeriod - * - frequency of the no-op commands that will be sent to keep up the session - * @param skipCiphers - * - determines if the getAvailableCipherSuites and getChannelAuthenticationCapabilities phases should be skipped - * @throws IOException - * - when properties file was not found - * @throws FileNotFoundException - * - when properties file was not found - * @see #disconnect() - */ - public void connect(InetAddress address, int port, long pingPeriod, boolean skipCiphers) throws IOException { - MessageHandler ipmiMessageHandler = new IpmiMessageHandler(this, timeout); - messageHandlers.put(PayloadType.Ipmi, ipmiMessageHandler); - - MessageHandler solMessageHandler = new SolMessageHandler(this, timeout); - messageHandlers.put(PayloadType.Sol, solMessageHandler); + private static final Logger LOGGER = LoggerFactory.getLogger(Connection.class); + + private static final int DEFAULT_CIPHER_SUITE = 3; + private static final int SESSION_SEQUENCE_NUMBER_UPPER_BOUND = Integer.MAX_VALUE / 4; + private static final String ILLEGAL_CONNECTION_STATE_MESSAGE = "Illegal connection state: "; + + private List listeners; + private StateMachine stateMachine; + + /** + * Time in ms after which a message times out. + */ + private int timeout = -1; + private StateMachineAction lastAction; + private int sessionId; + private int managedSystemSessionId; + private byte[] sik; + + private int handle; + + public int getHandle() { + return handle; + } + + private Map messageHandlers; + + private Timer timer; + + private AtomicInteger currentSessionSequenceNumber; + + public int getTimeout() { + return timeout; + } + + public void setTimeout(int timeout) { + this.timeout = timeout; + + for (MessageHandler messageHandler : messageHandlers.values()) { + messageHandler.setTimeout(timeout); + } + } + + /** + * Creates the connection. + * + * @param messenger + * - {@link Messenger} associated with the proper + * {@link Constants#IPMI_PORT} + * @param handle + * - id of the connection + */ + public Connection(Messenger messenger, int handle) { + stateMachine = new StateMachine(messenger); + this.handle = handle; + listeners = new ArrayList(); + timeout = Integer.parseInt(PropertiesManager.getInstance().getProperty("timeout")); + messageHandlers = new EnumMap(PayloadType.class); + currentSessionSequenceNumber = new AtomicInteger(0); + } + + /** + * Registers the listener so it will receive notifications from this + * connection + * + * @param listener + * - {@link ConnectionListener} to processResponse + */ + public void registerListener(ConnectionListener listener) { + listeners.add(listener); + } + + /** + * Unregisters the {@link ConnectionListener} + * + * @param listener + * {@link ConnectionListener} to unregister + */ + public void unregisterListener(ConnectionListener listener) { + listeners.remove(listener); + } + + /** + * Starts the connection to the specified {@link InetAddress} + * + * @param address + * - IP address of the managed system + * @param pingPeriod + * - frequency of the no-op commands that will be sent to keep up + * the session + * @throws IOException + * - when properties file was not found + * @throws FileNotFoundException + * - when properties file was not found + * @see #disconnect() + */ + public void connect(InetAddress address, int port, long pingPeriod) + throws IOException { + connect(address, port, pingPeriod, false); + } + + /** + * Starts the connection to the specified {@link InetAddress} + * + * @param address + * - IP address of the managed system + * @param pingPeriod + * - frequency of the no-op commands that will be sent to keep up the session + * @param skipCiphers + * - determines if the getAvailableCipherSuites and getChannelAuthenticationCapabilities phases should be + * skipped + * @throws IOException + * - when properties file was not found + * @throws FileNotFoundException + * - when properties file was not found + * @see #disconnect() + */ + public void connect(InetAddress address, int port, long pingPeriod, boolean skipCiphers) throws IOException { + MessageHandler ipmiMessageHandler = new IpmiMessageHandler(this, timeout); + messageHandlers.put(PayloadType.Ipmi, ipmiMessageHandler); + + MessageHandler solMessageHandler = new SolMessageHandler(this, timeout); + messageHandlers.put(PayloadType.Sol, solMessageHandler); // If the pingPeriod greater than 0, start the timer otherwise don't start it // means that the connection won't be kept alive by sending no-op messages @@ -210,403 +212,447 @@ public void connect(InetAddress address, int port, long pingPeriod, boolean skip timer.schedule(this, pingPeriod, pingPeriod); } - stateMachine.register(this); - if (skipCiphers) { - stateMachine.start(address, port); - sessionId = SessionManager.generateSessionId(); - stateMachine.setCurrent(new Authcap()); - } else { - stateMachine.start(address, port); - } - } - - /** - * Ends the connection. - * - * @see #connect(InetAddress, int, int) - */ - public void disconnect() { + stateMachine.register(this); + if (skipCiphers) { + stateMachine.start(address, port); + sessionId = SessionManager.generateSessionId(); + stateMachine.setCurrent(new Authcap()); + } else { + stateMachine.start(address, port); + } + } + + /** + * Ends the connection. + * + * @see #connect(InetAddress, int, int) + */ + public void disconnect() { if (timer != null) { timer.cancel(); } - stateMachine.stop(); + stateMachine.stop(); + + for (MessageHandler messageHandler : messageHandlers.values()) { + messageHandler.tearDown(); + } + } + + /** + * Checks if the connection is active + * + * @return true if the connection is active, false otherwise + * @see #connect(InetAddress, int, int) + * @see #disconnect() + */ + public boolean isActive() { + return stateMachine.isActive(); + } + + /** + * Gets from the managed system supported {@link CipherSuite}s. Should be + * performed only immediately after {@link #connect(InetAddress, int, int)}. + * + * @param tag + * - the integer from range 0-63 to match request with response + * @return list of the {@link CipherSuite}s supported by the managed system. + * @throws ConnectionException + * when connection is in the state that does not allow to + * perform this operation. + * @throws Exception + * when sending message to the managed system fails + */ + public List getAvailableCipherSuites(int tag) throws Exception { + + if (stateMachine.getCurrent().getClass() != Uninitialized.class) { + throw new ConnectionException( + ILLEGAL_CONNECTION_STATE_MESSAGE + stateMachine.getCurrent().getClass().getSimpleName()); + } + + boolean process = true; + + ArrayList rawCipherSuites = new ArrayList(); + + while (process) { + + lastAction = null; + + stateMachine.doTransition(new GetChannelCipherSuitesPending(tag)); + + waitForResponse(); + + ResponseAction action = (ResponseAction) lastAction; + + if (!(action.getIpmiResponseData() instanceof GetChannelCipherSuitesResponseData)) { + stateMachine.doTransition(new Timeout()); + throw new ConnectionException( + "Response data not matching Get Channel Cipher Suites command."); + } + + GetChannelCipherSuitesResponseData responseData = (GetChannelCipherSuitesResponseData) action + .getIpmiResponseData(); + + rawCipherSuites.add(responseData.getCipherSuiteData()); + + if (responseData.getCipherSuiteData().length < 16) { + process = false; + } + } + + stateMachine.doTransition(new DefaultAck()); + + int length = 0; + + for (byte[] partial : rawCipherSuites) { + length += partial.length; + } + + byte[] csRaw = new byte[length]; + + int index = 0; + + for (byte[] partial : rawCipherSuites) { + System.arraycopy(partial, 0, csRaw, index, partial.length); + index += partial.length; + } + + return CipherSuite.getCipherSuites(csRaw); + } + + private void waitForResponse() throws Exception { + int time = 0; + + while (time < timeout && lastAction == null) { + try { + Thread.sleep(1); + } catch (InterruptedException e) { + LOGGER.error(e.getMessage(), e); + } + ++time; + } + + if (lastAction == null) { + stateMachine.doTransition(new Timeout()); + throw new ConnectionException("Command timed out"); + } + if (!(lastAction instanceof ResponseAction || lastAction instanceof GetSikAction)) { + if (lastAction instanceof ErrorAction) { + throw ((ErrorAction) lastAction).getException(); + } + throw new ConnectionException( + "Invalid StateMachine response: " + + lastAction.getClass().getSimpleName()); + } + } + + /** + * Queries the managed system for the details of the authentification + * process. Must be performed after {@link #getAvailableCipherSuites(int)} + * + * @param tag + * - the integer from range 0-63 to match request with response + * @param cipherSuite + * - {@link CipherSuite} requested for the session + * @param requestedPrivilegeLevel + * - {@link PrivilegeLevel} requested for the session + * @return {@link GetChannelAuthenticationCapabilitiesResponseData} + * @throws ConnectionException + * when connection is in the state that does not allow to + * perform this operation. + * @throws Exception + * when sending message to the managed system fails + */ + public GetChannelAuthenticationCapabilitiesResponseData getChannelAuthenticationCapabilities( + int tag, + CipherSuite cipherSuite, + PrivilegeLevel requestedPrivilegeLevel) + throws Exception { + + if (stateMachine.getCurrent().getClass() != Ciphers.class) { + throw new ConnectionException( + ILLEGAL_CONNECTION_STATE_MESSAGE + + stateMachine.getCurrent().getClass().getSimpleName()); + } + + lastAction = null; + + stateMachine + .doTransition( + new Default( + cipherSuite, + tag, + requestedPrivilegeLevel)); + + waitForResponse(); + + ResponseAction action = (ResponseAction) lastAction; + + if (!(action.getIpmiResponseData() instanceof GetChannelAuthenticationCapabilitiesResponseData)) { + stateMachine.doTransition(new Timeout()); + throw new ConnectionException( + "Response data not matching Get Channel Authentication Capabilities command."); + } + + GetChannelAuthenticationCapabilitiesResponseData responseData = (GetChannelAuthenticationCapabilitiesResponseData) action + .getIpmiResponseData(); - for (MessageHandler messageHandler : messageHandlers.values()) { - messageHandler.tearDown(); - } - } - - /** - * Checks if the connection is active - * - * @return true if the connection is active, false otherwise - * - * @see #connect(InetAddress, int, int) - * @see #disconnect() - */ - public boolean isActive() { - return stateMachine.isActive(); - } - - /** - * Gets from the managed system supported {@link CipherSuite}s. Should be - * performed only immediately after {@link #connect(InetAddress, int, int)}. - * - * @param tag - * - the integer from range 0-63 to match request with response - * - * @return list of the {@link CipherSuite}s supported by the managed system. - * @throws ConnectionException - * when connection is in the state that does not allow to - * perform this operation. - * @throws Exception - * when sending message to the managed system fails - */ - public List getAvailableCipherSuites(int tag) throws Exception { - - if (stateMachine.getCurrent().getClass() != Uninitialized.class) { - throw new ConnectionException(ILLEGAL_CONNECTION_STATE_MESSAGE + stateMachine.getCurrent().getClass().getSimpleName()); - } - - boolean process = true; - - ArrayList rawCipherSuites = new ArrayList(); - - while (process) { - - lastAction = null; - - stateMachine.doTransition(new GetChannelCipherSuitesPending(tag)); - - waitForResponse(); - - ResponseAction action = (ResponseAction) lastAction; - - if (!(action.getIpmiResponseData() instanceof GetChannelCipherSuitesResponseData)) { - stateMachine.doTransition(new Timeout()); - throw new ConnectionException( - "Response data not matching Get Channel Cipher Suites command."); - } - - GetChannelCipherSuitesResponseData responseData = (GetChannelCipherSuitesResponseData) action - .getIpmiResponseData(); - - rawCipherSuites.add(responseData.getCipherSuiteData()); - - if (responseData.getCipherSuiteData().length < 16) { - process = false; - } - } - - stateMachine.doTransition(new DefaultAck()); - - int length = 0; - - for (byte[] partial : rawCipherSuites) { - length += partial.length; - } - - byte[] csRaw = new byte[length]; - - int index = 0; - - for (byte[] partial : rawCipherSuites) { - System.arraycopy(partial, 0, csRaw, index, partial.length); - index += partial.length; - } - - return CipherSuite.getCipherSuites(csRaw); - } - - private void waitForResponse() throws Exception { - int time = 0; - - while (time < timeout && lastAction == null) { - try { - Thread.sleep(1); - } catch (InterruptedException e) { - logger.error(e.getMessage(), e); - } - ++time; - } - - if (lastAction == null) { - stateMachine.doTransition(new Timeout()); - throw new ConnectionException("Command timed out"); - } - if (!(lastAction instanceof ResponseAction || lastAction instanceof GetSikAction)) { - if (lastAction instanceof ErrorAction) { - throw ((ErrorAction) lastAction).getException(); - } - throw new ConnectionException("Invalid StateMachine response: " - + lastAction.getClass().getSimpleName()); - } - } - - /** - * Queries the managed system for the details of the authentification - * process. Must be performed after {@link #getAvailableCipherSuites(int)} - * - * @param tag - * - the integer from range 0-63 to match request with response - * @param cipherSuite - * - {@link CipherSuite} requested for the session - * @param requestedPrivilegeLevel - * - {@link PrivilegeLevel} requested for the session - * @return {@link GetChannelAuthenticationCapabilitiesResponseData} - * @throws ConnectionException - * when connection is in the state that does not allow to - * perform this operation. - * @throws Exception - * when sending message to the managed system fails - */ - public GetChannelAuthenticationCapabilitiesResponseData getChannelAuthenticationCapabilities( - int tag, CipherSuite cipherSuite, - PrivilegeLevel requestedPrivilegeLevel) throws Exception { - - if (stateMachine.getCurrent().getClass() != Ciphers.class) { - throw new ConnectionException(ILLEGAL_CONNECTION_STATE_MESSAGE - + stateMachine.getCurrent().getClass().getSimpleName()); - } - - lastAction = null; - - stateMachine.doTransition(new Default(cipherSuite, tag, - requestedPrivilegeLevel)); - - waitForResponse(); - - ResponseAction action = (ResponseAction) lastAction; - - if (!(action.getIpmiResponseData() instanceof GetChannelAuthenticationCapabilitiesResponseData)) { - stateMachine.doTransition(new Timeout()); - throw new ConnectionException( - "Response data not matching Get Channel Authentication Capabilities command."); - } - - GetChannelAuthenticationCapabilitiesResponseData responseData = (GetChannelAuthenticationCapabilitiesResponseData) action - .getIpmiResponseData(); - - sessionId = SessionManager.generateSessionId(); - - stateMachine.doTransition(new AuthenticationCapabilitiesReceived( - sessionId, requestedPrivilegeLevel)); - - return responseData; - } - - /** - * Initiates the session with the managed system. Must be performed after - * {@link #getChannelAuthenticationCapabilities(int, CipherSuite, PrivilegeLevel)} - * or {@link #closeSession()} - * - * @param tag - * - the integer from range 0-63 to match request with response - * @param cipherSuite - * - {@link CipherSuite} that will be used during the session - * @param privilegeLevel - * - requested {@link PrivilegeLevel} - most of the time it will - * be {@link PrivilegeLevel#User} - * @param username - * - the username - * @param password - * - the password matching the username - * @param bmcKey - * - the key that should be provided if the two-key - * authentication is enabled, null otherwise. - * @return id of the new session - * @throws ConnectionException - * when connection is in the state that does not allow to - * perform this operation. - * @throws Exception - * when sending message to the managed system or initializing - * one of the cipherSuite's algorithms fails - */ - public int startSession(int tag, CipherSuite cipherSuite, - PrivilegeLevel privilegeLevel, String username, String password, - byte[] bmcKey) throws Exception { - if (stateMachine.getCurrent().getClass() != Authcap.class) { - throw new ConnectionException(ILLEGAL_CONNECTION_STATE_MESSAGE - + stateMachine.getCurrent().getClass().getSimpleName()); - } - - lastAction = null; - - // Open Session - stateMachine.doTransition(new Authorize(cipherSuite, tag, - privilegeLevel, sessionId)); - - waitForResponse(); - - ResponseAction action = (ResponseAction) lastAction; - - lastAction = null; - - if (!(action.getIpmiResponseData() instanceof OpenSessionResponseData)) { - stateMachine.doTransition(new Timeout()); - throw new ConnectionException( - "Response data not matching OpenSession response data"); - } - - managedSystemSessionId = ((OpenSessionResponseData) action - .getIpmiResponseData()).getManagedSystemSessionId(); - - stateMachine.doTransition(new DefaultAck()); - - // RAKP 1 - stateMachine.doTransition(new OpenSessionAck(cipherSuite, - privilegeLevel, tag, managedSystemSessionId, username, - password, bmcKey)); - - waitForResponse(); - - action = (ResponseAction) lastAction; - - lastAction = null; - - if (!(action.getIpmiResponseData() instanceof Rakp1ResponseData)) { - stateMachine.doTransition(new Timeout()); - throw new ConnectionException( - "Response data not matching RAKP Message 2: " - + action.getIpmiResponseData().getClass() - .getSimpleName()); - } - - Rakp1ResponseData rakp1ResponseData = (Rakp1ResponseData) action - .getIpmiResponseData(); - - stateMachine.doTransition(new DefaultAck()); - - // RAKP 3 - stateMachine.doTransition(new Rakp2Ack(cipherSuite, tag, (byte) 0, - managedSystemSessionId, rakp1ResponseData)); - - waitForResponse(); - - action = (ResponseAction) lastAction; - - if (sik == null) { - throw new ConnectionException("Session Integrity Key is null"); - } - - cipherSuite.initializeAlgorithms(sik); - - lastAction = null; - - if (!(action.getIpmiResponseData() instanceof Rakp3ResponseData)) { - stateMachine.doTransition(new Timeout()); - throw new ConnectionException( - "Response data not matching RAKP Message 4"); - } - - stateMachine.doTransition(new DefaultAck()); - stateMachine.doTransition(new StartSession(cipherSuite, sessionId)); - - return sessionId; - } - - /** - * Closes the session. Can be performed only if the session is already open. - * - * @throws ConnectionException - * when connection is in the state that does not allow to - * perform this operation. - */ - public void closeSession() throws ConnectionException { - if (stateMachine.getCurrent().getClass() != SessionValid.class) { - throw new ConnectionException(ILLEGAL_CONNECTION_STATE_MESSAGE - + stateMachine.getCurrent().getClass().getSimpleName()); - } - - stateMachine.doTransition(new CloseSession(managedSystemSessionId, - messageHandlers.get(PayloadType.Ipmi).getSequenceNumber(), getNextSessionSequenceNumber())); - } - - /** - * Attempts to send IPMI request to the managed system. - * - * @param payloadCoder - * - {@link PayloadCoder} representing the request - * @param isOneWay - * - tells whether message is one way or not - * @return ID of the message that will be also attached to the response to - * pair request with response if queue was not full and message was - * sent, -1 if sending of the message failed. - * @throws ConnectionException - * when connection isn't in state where sending commands is - * allowed - * @throws ArithmeticException - * when {@link Connection} runs out of available ID's for the - * messages. If this happens session needs to be restarted. - */ - public int sendMessage(PayloadCoder payloadCoder, boolean isOneWay) throws ConnectionException { - MessageHandler messageHandler = messageHandlers.get(payloadCoder.getSupportedPayloadType()); - - if (messageHandler == null) { - // Handler for PayloadType.Ipmi is a default handler and in case no specific is found, we try default one. - messageHandler = messageHandlers.get(PayloadType.Ipmi); - } - - return messageHandler.sendMessage(payloadCoder, stateMachine, managedSystemSessionId, isOneWay); - } - - /** - * Attempts to retry sending a message. - * - * @param tag - * - tag of the message to retry - * @param messagePayloadType - * - {@link PayloadType} of the message that should be retried - * @return new tag if message was retried, -1 if operation failed - * @throws ConnectionException - * when connection isn't in state where sending commands is - * allowed - */ - public int retry(int tag, PayloadType messagePayloadType) throws ConnectionException { - - MessageHandler messageHandler = messageHandlers.containsKey(messagePayloadType) ? - messageHandlers.get(messagePayloadType) : messageHandlers.get(PayloadType.Ipmi); - - return messageHandler.retryMessage(tag, stateMachine, managedSystemSessionId); - } - - private void handleIncomingMessage(Ipmiv20Message message) { - MessageHandler messageHandler = messageHandlers.get(message.getPayloadType()); - messageHandler.handleIncomingMessage(message); - } - - public void notifyResponseListeners(int handle, int tag, ResponseData responseData, - Exception exception) { - for (ConnectionListener listener : listeners) { - if (listener != null) { - listener.processResponse(responseData, handle, tag, exception); - } - } - } - - public void notifyRequestListeners(IpmiPayload payload) { - for (ConnectionListener listener : listeners) { - if (listener != null) { - listener.processRequest(payload); - } - } - } - - @Override - public void notify(StateMachineAction action) { - if (action instanceof GetSikAction) { - sik = ((GetSikAction) action).getSik(); - } else if (!(action instanceof MessageAction)) { - lastAction = action; - if (action instanceof ErrorAction) { - ErrorAction errorAction = (ErrorAction) action; - logger.error(errorAction.getException().getMessage(), errorAction.getException()); - } - } else { - handleIncomingMessage(((MessageAction) action).getIpmiv20Message()); - } - } + sessionId = SessionManager.generateSessionId(); + + stateMachine + .doTransition( + new AuthenticationCapabilitiesReceived( + sessionId, + requestedPrivilegeLevel)); + + return responseData; + } + + /** + * Initiates the session with the managed system. Must be performed after + * {@link #getChannelAuthenticationCapabilities(int, CipherSuite, PrivilegeLevel)} + * or {@link #closeSession()} + * + * @param tag + * - the integer from range 0-63 to match request with response + * @param cipherSuite + * - {@link CipherSuite} that will be used during the session + * @param privilegeLevel + * - requested {@link PrivilegeLevel} - most of the time it will + * be {@link PrivilegeLevel#User} + * @param username + * - the username + * @param password + * - the password matching the username + * @param bmcKey + * - the key that should be provided if the two-key + * authentication is enabled, null otherwise. + * @return id of the new session + * @throws ConnectionException + * when connection is in the state that does not allow to + * perform this operation. + * @throws Exception + * when sending message to the managed system or initializing + * one of the cipherSuite's algorithms fails + */ + public int startSession( + int tag, + CipherSuite cipherSuite, + PrivilegeLevel privilegeLevel, + String username, + String password, + byte[] bmcKey) + throws Exception { + if (stateMachine.getCurrent().getClass() != Authcap.class) { + throw new ConnectionException( + ILLEGAL_CONNECTION_STATE_MESSAGE + + stateMachine.getCurrent().getClass().getSimpleName()); + } + + lastAction = null; + + // Open Session + stateMachine + .doTransition( + new Authorize( + cipherSuite, + tag, + privilegeLevel, + sessionId)); + + waitForResponse(); + + ResponseAction action = (ResponseAction) lastAction; + + lastAction = null; + + if (!(action.getIpmiResponseData() instanceof OpenSessionResponseData)) { + stateMachine.doTransition(new Timeout()); + throw new ConnectionException( + "Response data not matching OpenSession response data"); + } + + managedSystemSessionId = ((OpenSessionResponseData) action + .getIpmiResponseData()).getManagedSystemSessionId(); + + stateMachine.doTransition(new DefaultAck()); + + // RAKP 1 + stateMachine + .doTransition( + new OpenSessionAck( + cipherSuite, + privilegeLevel, + tag, + managedSystemSessionId, + username, + password, + bmcKey)); + + waitForResponse(); + + action = (ResponseAction) lastAction; + + lastAction = null; + + if (!(action.getIpmiResponseData() instanceof Rakp1ResponseData)) { + stateMachine.doTransition(new Timeout()); + throw new ConnectionException( + "Response data not matching RAKP Message 2: " + + action + .getIpmiResponseData() + .getClass() + .getSimpleName()); + } + + Rakp1ResponseData rakp1ResponseData = (Rakp1ResponseData) action + .getIpmiResponseData(); + + stateMachine.doTransition(new DefaultAck()); + + // RAKP 3 + stateMachine + .doTransition( + new Rakp2Ack( + cipherSuite, + tag, + (byte) 0, + managedSystemSessionId, + rakp1ResponseData)); + + waitForResponse(); + + action = (ResponseAction) lastAction; + + if (sik == null) { + throw new ConnectionException("Session Integrity Key is null"); + } + + cipherSuite.initializeAlgorithms(sik); + + lastAction = null; + + if (!(action.getIpmiResponseData() instanceof Rakp3ResponseData)) { + stateMachine.doTransition(new Timeout()); + throw new ConnectionException( + "Response data not matching RAKP Message 4"); + } + + stateMachine.doTransition(new DefaultAck()); + stateMachine.doTransition(new StartSession(cipherSuite, sessionId)); + + return sessionId; + } + + /** + * Closes the session. Can be performed only if the session is already open. + * + * @throws ConnectionException + * when connection is in the state that does not allow to + * perform this operation. + */ + public void closeSession() throws ConnectionException { + if (stateMachine.getCurrent().getClass() != SessionValid.class) { + throw new ConnectionException( + ILLEGAL_CONNECTION_STATE_MESSAGE + + stateMachine.getCurrent().getClass().getSimpleName()); + } + + stateMachine + .doTransition( + new CloseSession( + managedSystemSessionId, + messageHandlers.get(PayloadType.Ipmi).getSequenceNumber(), + getNextSessionSequenceNumber())); + } + + /** + * Attempts to send IPMI request to the managed system. + * + * @param payloadCoder + * - {@link PayloadCoder} representing the request + * @param isOneWay + * - tells whether message is one way or not + * @return ID of the message that will be also attached to the response to + * pair request with response if queue was not full and message was + * sent, -1 if sending of the message failed. + * @throws ConnectionException + * when connection isn't in state where sending commands is + * allowed + * @throws ArithmeticException + * when {@link Connection} runs out of available ID's for the + * messages. If this happens session needs to be restarted. + */ + public int sendMessage(PayloadCoder payloadCoder, boolean isOneWay) throws ConnectionException { + MessageHandler messageHandler = messageHandlers.get(payloadCoder.getSupportedPayloadType()); + + if (messageHandler == null) { + // Handler for PayloadType.Ipmi is a default handler and in case no specific is found, we try default one. + messageHandler = messageHandlers.get(PayloadType.Ipmi); + } + + return messageHandler.sendMessage(payloadCoder, stateMachine, managedSystemSessionId, isOneWay); + } + + /** + * Attempts to retry sending a message. + * + * @param tag + * - tag of the message to retry + * @param messagePayloadType + * - {@link PayloadType} of the message that should be retried + * @return new tag if message was retried, -1 if operation failed + * @throws ConnectionException + * when connection isn't in state where sending commands is + * allowed + */ + public int retry(int tag, PayloadType messagePayloadType) throws ConnectionException { + + MessageHandler messageHandler = messageHandlers.containsKey(messagePayloadType) ? + messageHandlers.get(messagePayloadType) : messageHandlers.get(PayloadType.Ipmi); + + return messageHandler.retryMessage(tag, stateMachine, managedSystemSessionId); + } + + private void handleIncomingMessage(Ipmiv20Message message) { + MessageHandler messageHandler = messageHandlers.get(message.getPayloadType()); + messageHandler.handleIncomingMessage(message); + } + + public void notifyResponseListeners( + int handleId, + int tag, + ResponseData responseData, + Exception exception) { + for (ConnectionListener listener : listeners) { + if (listener != null) { + listener.processResponse(responseData, handleId, tag, exception); + } + } + } + + public void notifyRequestListeners(IpmiPayload payload) { + for (ConnectionListener listener : listeners) { + if (listener != null) { + listener.processRequest(payload); + } + } + } + + @Override + public void notify(StateMachineAction action) { + if (action instanceof GetSikAction) { + sik = ((GetSikAction) action).getSik(); + } else if (!(action instanceof MessageAction)) { + lastAction = action; + if (action instanceof ErrorAction) { + ErrorAction errorAction = (ErrorAction) action; + LOGGER.error(errorAction.getException().getMessage(), errorAction.getException()); + } + } else { + handleIncomingMessage(((MessageAction) action).getIpmiv20Message()); + } + } /** * {@link TimerTask} runner - periodically sends no-op messages to keep the @@ -615,62 +661,63 @@ public void notify(StateMachineAction action) { @Override public void run() { int result = -1; - while ( - !Thread.currentThread().isInterrupted() - && result <= 0 - && stateMachine.getCurrent() instanceof SessionValid - ) { + while (!Thread.currentThread().isInterrupted() + && result <= 0 + && stateMachine.getCurrent() instanceof SessionValid) { try { result = sendMessage( - new org.metricshub.ipmi.core.coding.commands.session.GetChannelAuthenticationCapabilities( - IpmiVersion.V20, IpmiVersion.V20, - ((SessionValid) stateMachine.getCurrent()).getCipherSuite(), PrivilegeLevel.Callback, - TypeConverter.intToByte(0xe) - ), - false - ); + new org.metricshub.ipmi.core.coding.commands.session.GetChannelAuthenticationCapabilities( + IpmiVersion.V20, + IpmiVersion.V20, + ((SessionValid) stateMachine.getCurrent()).getCipherSuite(), + PrivilegeLevel.Callback, + TypeConverter.intToByte(0xe)), + false); Thread.sleep(1000); } catch (Exception e) { - logger.error(e.getMessage(), e); + LOGGER.error(e.getMessage(), e); } } } - public InetAddress getRemoteMachineAddress() { - return stateMachine.getRemoteMachineAddress(); - } + public InetAddress getRemoteMachineAddress() { + return stateMachine.getRemoteMachineAddress(); + } - public int getRemoteMachinePort() { - return stateMachine.getRemoteMachinePort(); - } + public int getRemoteMachinePort() { + return stateMachine.getRemoteMachinePort(); + } - /** - * Checks if session is currently open. - */ - public boolean isSessionValid() { - return stateMachine.getCurrent() instanceof SessionValid; - } + /** + * Checks if session is currently open. + */ + public boolean isSessionValid() { + return stateMachine.getCurrent() instanceof SessionValid; + } - public int getNextSessionSequenceNumber() { - int result = currentSessionSequenceNumber.incrementAndGet() % SESSION_SEQUENCE_NUMBER_UPPER_BOUND; + public int getNextSessionSequenceNumber() { + int result = currentSessionSequenceNumber.incrementAndGet() % SESSION_SEQUENCE_NUMBER_UPPER_BOUND; - if (result == 0) { - throw new ArithmeticException("Session sequence number overload. Reset session."); - } + if (result == 0) { + throw new ArithmeticException("Session sequence number overload. Reset session."); + } - return result; - } + return result; + } /** * @return Default cipher suite (3) */ public static CipherSuite getDefaultCipherSuite() { - return new CipherSuite((byte) DEFAULT_CIPHER_SUITE, new AuthenticationRakpHmacSha1().getCode(), - new ConfidentialityAesCbc128().getCode(), new IntegrityHmacSha1_96().getCode()); + return new CipherSuite( + (byte) DEFAULT_CIPHER_SUITE, + new AuthenticationRakpHmacSha1().getCode(), + new ConfidentialityAesCbc128().getCode(), + new IntegrityHmacSha1_96().getCode()); } diff --git a/src/main/java/org/metricshub/ipmi/core/connection/ConnectionException.java b/src/main/java/org/metricshub/ipmi/core/connection/ConnectionException.java index f006985..c93cd0d 100644 --- a/src/main/java/org/metricshub/ipmi/core/connection/ConnectionException.java +++ b/src/main/java/org/metricshub/ipmi/core/connection/ConnectionException.java @@ -27,12 +27,12 @@ */ public class ConnectionException extends Exception { - /** - * - */ - private static final long serialVersionUID = 3912859025179839078L; + /** + * + */ + private static final long serialVersionUID = 3912859025179839078L; - public ConnectionException(String message) { - super(message); - } + public ConnectionException(String message) { + super(message); + } } diff --git a/src/main/java/org/metricshub/ipmi/core/connection/ConnectionListener.java b/src/main/java/org/metricshub/ipmi/core/connection/ConnectionListener.java index 8956293..8c3bdcb 100644 --- a/src/main/java/org/metricshub/ipmi/core/connection/ConnectionListener.java +++ b/src/main/java/org/metricshub/ipmi/core/connection/ConnectionListener.java @@ -30,25 +30,32 @@ */ public interface ConnectionListener { - /** - * Notifies the {@link ConnectionListener}s of the one of the following - * events:
  • response to the request tagged with id arrived
  • request - * tagged with id timed out
- * - * @param responseData - * - {@link ResponseData} specific for the request if it was - * completed successfully, null if it timed out or an error - * occured during decoding. - * @param handle - * - the id of the connection that received the message - * @param id - * - tag of the request-response pair - * @param exception - * - null if everything went correctly or timeout occured, - * contains exception that occured during decoding if it failed. - */ - void processResponse(ResponseData responseData, int handle, int id, - Exception exception); + /** + * Notifies the {@link ConnectionListener}s of the one of the following + * events: + *
    + *
  • response to the request tagged with id arrived
  • + *
  • request + * tagged with id timed out
  • + *
+ * + * @param responseData + * - {@link ResponseData} specific for the request if it was + * completed successfully, null if it timed out or an error + * occured during decoding. + * @param handle + * - the id of the connection that received the message + * @param id + * - tag of the request-response pair + * @param exception + * - null if everything went correctly or timeout occured, + * contains exception that occured during decoding if it failed. + */ + void processResponse( + ResponseData responseData, + int handle, + int id, + Exception exception); - void processRequest(IpmiPayload payload); + void processRequest(IpmiPayload payload); } diff --git a/src/main/java/org/metricshub/ipmi/core/connection/ConnectionManager.java b/src/main/java/org/metricshub/ipmi/core/connection/ConnectionManager.java index 2310534..946bb9c 100644 --- a/src/main/java/org/metricshub/ipmi/core/connection/ConnectionManager.java +++ b/src/main/java/org/metricshub/ipmi/core/connection/ConnectionManager.java @@ -40,23 +40,23 @@ * Manages multiple {@link Connection}s */ public class ConnectionManager { - private Messenger messenger; - private List connections; + private Messenger messenger; + private List connections; - private static final AtomicInteger sessionlessTag = new AtomicInteger(0); - private static List reservedTags = new ArrayList(); + private static final AtomicInteger SESSIONLESS_TAG = new AtomicInteger(0); + private static List reservedTags = new ArrayList(); - /** - * Frequency of the no-op commands that will be sent to keep up the session - */ - private long pingPeriod = -1; + /** + * Frequency of the no-op commands that will be sent to keep up the session + */ + private long pingPeriod = -1; /** * Initiates the connection manager. Wildcard IP address will be used. * - * @param port the port at which {@link UdpListener} will work + * @param port the port at which {@link UdpListener} will work * @param pingPeriod frequency of the no-op commands that will be sent to keep - * up the session. 0 to disable ping requests. + * up the session. 0 to disable ping requests. * @throws IOException If UdpMessenger encountered an error */ public ConnectionManager(int port, long pingPeriod) throws IOException { @@ -64,343 +64,366 @@ public ConnectionManager(int port, long pingPeriod) throws IOException { this.pingPeriod = pingPeriod; } - /** - * Initiates the connection manager. Wildcard IP address will be used. - * - * @param port - * - the port at which {@link UdpListener} will work - * @throws IOException If UdpMessenger encountered an error - */ - public ConnectionManager(int port) throws IOException { - messenger = new UdpMessenger(port); - initialize(); - } + /** + * Initiates the connection manager. Wildcard IP address will be used. + * + * @param port + * - the port at which {@link UdpListener} will work + * @throws IOException If UdpMessenger encountered an error + */ + public ConnectionManager(int port) throws IOException { + messenger = new UdpMessenger(port); + initialize(); + } - /** - * Initiates the connection manager. - * - * @param port - * - the port at which {@link UdpListener} will work - * @param address - * - the IP interface {@link UdpListener} will bind to - * @throws IOException If UdpMessenger encountered an error - */ - public ConnectionManager(int port, InetAddress address) throws IOException { - messenger = new UdpMessenger(port, address); - initialize(); - } + /** + * Initiates the connection manager. + * + * @param port + * - the port at which {@link UdpListener} will work + * @param address + * - the IP interface {@link UdpListener} will bind to + * @throws IOException If UdpMessenger encountered an error + */ + public ConnectionManager(int port, InetAddress address) throws IOException { + messenger = new UdpMessenger(port, address); + initialize(); + } - /** - * Initiates the connection manager. - * - * @param messenger - * - {@link Messenger} to be used in communication - */ - public ConnectionManager(Messenger messenger) { - this.messenger = messenger; - initialize(); - } + /** + * Initiates the connection manager. + * + * @param messenger + * - {@link Messenger} to be used in communication + */ + public ConnectionManager(Messenger messenger) { + this.messenger = messenger; + initialize(); + } - private void initialize() { - connections = new ArrayList(); - reservedTags = new ArrayList(); - if (pingPeriod == -1) { - pingPeriod = Long.parseLong(PropertiesManager.getInstance().getProperty("pingPeriod")); - } - } + private void initialize() { + connections = new ArrayList(); + reservedTags = new ArrayList(); + if (pingPeriod == -1) { + pingPeriod = Long.parseLong(PropertiesManager.getInstance().getProperty("pingPeriod")); + } + } - /** - * Closes all open connections and disconnects {@link UdpListener}. - */ - public void close() { - synchronized (connections) { - for (Connection connection : connections) { - if (connection != null && connection.isActive()) { - connection.disconnect(); - } - } - } - messenger.closeConnection(); - } + /** + * Closes all open connections and disconnects {@link UdpListener}. + */ + public void close() { + synchronized (connections) { + for (Connection connection : connections) { + if (connection != null && connection.isActive()) { + connection.disconnect(); + } + } + } + messenger.closeConnection(); + } - /** - * The tag for messages sent outside the session generated by the - * {@link ConnectionManager}. Auto-incremented. - */ - public static int generateSessionlessTag() { - synchronized (sessionlessTag) { - boolean wait = true; - while (wait) { - sessionlessTag.incrementAndGet(); - sessionlessTag.set(sessionlessTag.get() % 60); - synchronized (reservedTags) { - if (!reservedTags.contains(sessionlessTag.get())) { - wait = false; - } - } - if (wait) { - try { - sessionlessTag.wait(1); - } catch (InterruptedException e) { - // TODO log - } - } - } - synchronized (reservedTags) { - reservedTags.add(sessionlessTag.get()); - } - return sessionlessTag.get(); - } - } + /** + * The tag for messages sent outside the session generated by the + * {@link ConnectionManager}. Auto-incremented. + */ + public static int generateSessionlessTag() { + synchronized (SESSIONLESS_TAG) { + boolean wait = true; + while (wait) { + SESSIONLESS_TAG.incrementAndGet(); + SESSIONLESS_TAG.set(SESSIONLESS_TAG.get() % 60); + synchronized (reservedTags) { + if (!reservedTags.contains(SESSIONLESS_TAG.get())) { + wait = false; + } + } + if (wait) { + try { + SESSIONLESS_TAG.wait(1); + } catch (InterruptedException e) { + // TODO log + } + } + } + synchronized (reservedTags) { + reservedTags.add(SESSIONLESS_TAG.get()); + } + return SESSIONLESS_TAG.get(); + } + } - /** - * Frees the sessionless tag for further use - * - * @param tag - * - tag to free - */ - public static void freeTag(int tag) { - synchronized (reservedTags) { - reservedTags.remove((Integer) tag); - } - } + /** + * Frees the sessionless tag for further use + * + * @param tag + * - tag to free + */ + public static void freeTag(int tag) { + synchronized (reservedTags) { + reservedTags.remove((Integer) tag); + } + } - /** - * Returns {@link Connection} identified by index. - * - * @param index - * - index of the connection to return - */ - public Connection getConnection(int index) { - return connections.get(index); - } + /** + * Returns {@link Connection} identified by index. + * + * @param index + * - index of the connection to return + */ + public Connection getConnection(int index) { + return connections.get(index); + } - /** - * Closes the connection with the given index. - */ - public void closeConnection(int index) { - connections.get(index).disconnect(); - } + /** + * Closes the connection with the given index. + */ + public void closeConnection(int index) { + connections.get(index).disconnect(); + } - /** - * Returns first {@link Connection} associated with the address - * - * @param address - * - {@link InetAddress} of the remote host to get connection - * with. - * @return First {@link Connection} to the address or null if none found - */ - public Connection getConnection(InetAddress address, int port) { - synchronized (connections) { - for (Connection connection : connections) { - if (connection != null && connection.isActive() - && connection.getRemoteMachineAddress() == address - && connection.getRemoteMachinePort() == port) { - return connection; - } - } - } - return null; - } + /** + * Returns first {@link Connection} associated with the address + * + * @param address + * - {@link InetAddress} of the remote host to get connection + * with. + * @return First {@link Connection} to the address or null if none found + */ + public Connection getConnection(InetAddress address, int port) { + synchronized (connections) { + for (Connection connection : connections) { + if (connection != null + && connection.isActive() + && connection.getRemoteMachineAddress() == address + && connection.getRemoteMachinePort() == port) { + return connection; + } + } + } + return null; + } - /** - * Creates and initiates {@link Connection} to the remote host. - * @param address - * - {@link InetAddress} of the remote host - * @param pingPeriod - * - frequency of the no-op commands that will be sent to keep up the session - * @param skipCiphers - * - determines if the getAvailableCipherSuites and getChannelAuthenticationCapabilities phases should be skipped - * @return index of the connection - * @throws IOException - * - when properties file was not found - */ - public int createConnection(InetAddress address, int port, int pingPeriod, boolean skipCiphers) throws IOException { - Connection connection = new Connection(messenger, 0); - connection.connect(address, port, pingPeriod, skipCiphers); + /** + * Creates and initiates {@link Connection} to the remote host. + * + * @param address + * - {@link InetAddress} of the remote host + * @param connectionPingPeriod + * - frequency of the no-op commands that will be sent to keep up the session + * @param skipCiphers + * - determines if the getAvailableCipherSuites and getChannelAuthenticationCapabilities phases should be + * skipped + * @return index of the connection + * @throws IOException + * - when properties file was not found + */ + public int createConnection(InetAddress address, int port, int connectionPingPeriod, boolean skipCiphers) + throws IOException { + Connection connection = new Connection(messenger, 0); + connection.connect(address, port, connectionPingPeriod, skipCiphers); - synchronized (connections) { - connections.add(connection); - return connections.size() - 1; - } - } + synchronized (connections) { + connections.add(connection); + return connections.size() - 1; + } + } - /** - * Creates and initiates {@link Connection} to the remote host. - * - * @param address - * - {@link InetAddress} of the remote host - * @param pingPeriod - * - frequency of the no-op commands that will be sent to keep up - * the session - * @return index of the connection - * @throws IOException - * - when properties file was not found - */ - public int createConnection(InetAddress address, int port, int pingPeriod) throws IOException { - Connection connection = new Connection(messenger, 0); - connection.connect(address, port, pingPeriod); + /** + * Creates and initiates {@link Connection} to the remote host. + * + * @param address + * - {@link InetAddress} of the remote host + * @param connectionPingPeriod + * - frequency of the no-op commands that will be sent to keep up + * the session + * @return index of the connection + * @throws IOException + * - when properties file was not found + */ + public int createConnection(InetAddress address, int port, int connectionPingPeriod) throws IOException { + Connection connection = new Connection(messenger, 0); + connection.connect(address, port, connectionPingPeriod); - synchronized (connections) { - connections.add(connection); - return connections.size() - 1; - } - } + synchronized (connections) { + connections.add(connection); + return connections.size() - 1; + } + } - /** - * Creates and initiates {@link Connection} to the remote host with the - * default ping frequency. - * - * @param address - * - {@link InetAddress} of the remote host - * @return index of the connection - * @throws IOException - * when properties file was not found - */ - public int createConnection(InetAddress address, int port) throws IOException { + /** + * Creates and initiates {@link Connection} to the remote host with the + * default ping frequency. + * + * @param address + * - {@link InetAddress} of the remote host + * @return index of the connection + * @throws IOException + * when properties file was not found + */ + public int createConnection(InetAddress address, int port) throws IOException { - synchronized (connections) { - Connection connection = new Connection(messenger, - connections.size()); - connection.connect(address, port, pingPeriod); - connections.add(connection); - return connections.size() - 1; - } - } + synchronized (connections) { + Connection connection = new Connection( + messenger, + connections.size()); + connection.connect(address, port, pingPeriod); + connections.add(connection); + return connections.size() - 1; + } + } - /** - * Creates and initiates {@link Connection} to the remote host with the default ping frequency. - * @param address - * - {@link InetAddress} of the remote host - * @param skipCiphers - * - determines if the getAvailableCipherSuites and getChannelAuthenticationCapabilities phases should be skipped - * @return index of the connection - * @throws IOException - * when properties file was not found - */ - public int createConnection(InetAddress address, int port, boolean skipCiphers) throws IOException { - synchronized (connections) { - Connection connection = new Connection(messenger, connections.size()); - connection.connect(address, port, pingPeriod, skipCiphers); - connections.add(connection); - return connections.size() - 1; - } - } + /** + * Creates and initiates {@link Connection} to the remote host with the default ping frequency. + * + * @param address + * - {@link InetAddress} of the remote host + * @param skipCiphers + * - determines if the getAvailableCipherSuites and getChannelAuthenticationCapabilities phases should be + * skipped + * @return index of the connection + * @throws IOException + * when properties file was not found + */ + public int createConnection(InetAddress address, int port, boolean skipCiphers) throws IOException { + synchronized (connections) { + Connection connection = new Connection(messenger, connections.size()); + connection.connect(address, port, pingPeriod, skipCiphers); + connections.add(connection); + return connections.size() - 1; + } + } - /** - * Gets from the managed system supported {@link CipherSuite}s. Should be - * performed only immediately after {@link #createConnection}. - * - * @param connection - * - index of the connection to get available Cipher Suites from - * - * @return list of the {@link CipherSuite}s supported by the managed system. - * @throws ConnectionException - * when connection is in the state that does not allow to - * perform this operation. - * @throws Exception - * when sending message to the managed system fails - */ - public List getAvailableCipherSuites(int connection) - throws Exception { - int tag = generateSessionlessTag(); - List suites; - try { - suites = connections.get(connection).getAvailableCipherSuites(tag); - } catch (Exception e) { - freeTag(tag); - throw e; - } - freeTag(tag); - return suites; - } + /** + * Gets from the managed system supported {@link CipherSuite}s. Should be + * performed only immediately after {@link #createConnection}. + * + * @param connection + * - index of the connection to get available Cipher Suites from + * @return list of the {@link CipherSuite}s supported by the managed system. + * @throws ConnectionException + * when connection is in the state that does not allow to + * perform this operation. + * @throws Exception + * when sending message to the managed system fails + */ + public List getAvailableCipherSuites(int connection) + throws Exception { + int tag = generateSessionlessTag(); + List suites; + try { + suites = connections.get(connection).getAvailableCipherSuites(tag); + } catch (Exception e) { + freeTag(tag); + throw e; + } + freeTag(tag); + return suites; + } - /** - * Queries the managed system for the details of the authentification - * process. Must be performed after {@link #getAvailableCipherSuites(int)} - * - * @param connection - * - index of the connection to get Channel Authentication - * Capabilities from - * @param cipherSuite - * - {@link CipherSuite} requested for the session - * @param requestedPrivilegeLevel - * - {@link PrivilegeLevel} requested for the session - * @return {@link GetChannelAuthenticationCapabilitiesResponseData} - * @throws ConnectionException - * when connection is in the state that does not allow to - * perform this operation. - * @throws Exception - * when sending message to the managed system fails - */ - public GetChannelAuthenticationCapabilitiesResponseData getChannelAuthenticationCapabilities( - int connection, CipherSuite cipherSuite, - PrivilegeLevel requestedPrivilegeLevel) throws Exception { - int tag = generateSessionlessTag(); - GetChannelAuthenticationCapabilitiesResponseData responseData; - try { - responseData = connections.get(connection) - .getChannelAuthenticationCapabilities(tag, cipherSuite, - requestedPrivilegeLevel); - } catch (Exception e) { - freeTag(tag); - throw e; - } - freeTag(tag); - return responseData; - } + /** + * Queries the managed system for the details of the authentification + * process. Must be performed after {@link #getAvailableCipherSuites(int)} + * + * @param connection + * - index of the connection to get Channel Authentication + * Capabilities from + * @param cipherSuite + * - {@link CipherSuite} requested for the session + * @param requestedPrivilegeLevel + * - {@link PrivilegeLevel} requested for the session + * @return {@link GetChannelAuthenticationCapabilitiesResponseData} + * @throws ConnectionException + * when connection is in the state that does not allow to + * perform this operation. + * @throws Exception + * when sending message to the managed system fails + */ + public GetChannelAuthenticationCapabilitiesResponseData getChannelAuthenticationCapabilities( + int connection, + CipherSuite cipherSuite, + PrivilegeLevel requestedPrivilegeLevel) + throws Exception { + int tag = generateSessionlessTag(); + GetChannelAuthenticationCapabilitiesResponseData responseData; + try { + responseData = connections + .get(connection) + .getChannelAuthenticationCapabilities( + tag, + cipherSuite, + requestedPrivilegeLevel); + } catch (Exception e) { + freeTag(tag); + throw e; + } + freeTag(tag); + return responseData; + } - /** - * Initiates the session with the managed system. Must be performed after - * {@link #getChannelAuthenticationCapabilities(int, CipherSuite, PrivilegeLevel)} - * - * @param connection - * - index of the connection that starts the session - * @param cipherSuite - * - {@link CipherSuite} that will be used during the session - * @param privilegeLevel - * - requested {@link PrivilegeLevel} - most of the time it will - * be {@link PrivilegeLevel#User} - * @param username - * - the username - * @param password - * - the password matching the username - * @param bmcKey - * - the key that should be provided if the two-key - * authentication is enabled, null otherwise. - * @throws ConnectionException - * when connection is in the state that does not allow to - * perform this operation. - * @throws Exception - * when sending message to the managed system or initializing - * one of the cipherSuite's algorithms fails - */ - public int startSession(int connection, CipherSuite cipherSuite, - PrivilegeLevel privilegeLevel, String username, String password, - byte[] bmcKey) throws Exception { - int sessionId; - int tag = generateSessionlessTag(); - try { - sessionId = connections.get(connection).startSession(tag, cipherSuite, - privilegeLevel, username, password, bmcKey); - } catch (Exception e) { - freeTag(tag); - throw e; - } - freeTag(tag); + /** + * Initiates the session with the managed system. Must be performed after + * {@link #getChannelAuthenticationCapabilities(int, CipherSuite, PrivilegeLevel)} + * + * @param connection + * - index of the connection that starts the session + * @param cipherSuite + * - {@link CipherSuite} that will be used during the session + * @param privilegeLevel + * - requested {@link PrivilegeLevel} - most of the time it will + * be {@link PrivilegeLevel#User} + * @param username + * - the username + * @param password + * - the password matching the username + * @param bmcKey + * - the key that should be provided if the two-key + * authentication is enabled, null otherwise. + * @throws ConnectionException + * when connection is in the state that does not allow to + * perform this operation. + * @throws Exception + * when sending message to the managed system or initializing + * one of the cipherSuite's algorithms fails + */ + public int startSession( + int connection, + CipherSuite cipherSuite, + PrivilegeLevel privilegeLevel, + String username, + String password, + byte[] bmcKey) + throws Exception { + int sessionId; + int tag = generateSessionlessTag(); + try { + sessionId = connections + .get(connection) + .startSession( + tag, + cipherSuite, + privilegeLevel, + username, + password, + bmcKey); + } catch (Exception e) { + freeTag(tag); + throw e; + } + freeTag(tag); - return sessionId; - } + return sessionId; + } - /** - * Registers the listener so it will receive notifications from connection - * - * @param connection - * - index of the {@link Connection} to listen to - * @param listener - * - {@link ConnectionListener} to processResponse - */ - public void registerListener(int connection, ConnectionListener listener) { - connections.get(connection).registerListener(listener); - } + /** + * Registers the listener so it will receive notifications from connection + * + * @param connection + * - index of the {@link Connection} to listen to + * @param listener + * - {@link ConnectionListener} to processResponse + */ + public void registerListener(int connection, ConnectionListener listener) { + connections.get(connection).registerListener(listener); + } } diff --git a/src/main/java/org/metricshub/ipmi/core/connection/IpmiMessageHandler.java b/src/main/java/org/metricshub/ipmi/core/connection/IpmiMessageHandler.java index 06d2afd..d44f9dc 100644 --- a/src/main/java/org/metricshub/ipmi/core/connection/IpmiMessageHandler.java +++ b/src/main/java/org/metricshub/ipmi/core/connection/IpmiMessageHandler.java @@ -38,48 +38,51 @@ */ public class IpmiMessageHandler extends MessageHandler { - private static final Logger logger = LoggerFactory.getLogger(IpmiMessageHandler.class); + private static final Logger LOGGER = LoggerFactory.getLogger(IpmiMessageHandler.class); - public IpmiMessageHandler(Connection connection, int timeout) throws IOException { - super(connection, timeout, IpmiLanMessage.MIN_SEQUENCE_NUMBER, IpmiLanMessage.MAX_SEQUENCE_NUMBER); - } + public IpmiMessageHandler(Connection connection, int timeout) throws IOException { + super(connection, timeout, IpmiLanMessage.MIN_SEQUENCE_NUMBER, IpmiLanMessage.MAX_SEQUENCE_NUMBER); + } - /** - * If message is of type {@link IpmiLanMessage}, finds corresponding request message and extracts response data from it, - * using data carried in this message. - * - * @param message - * received IPMI message - */ - @Override - protected void handleIncomingMessageInternal(Ipmiv20Message message) { - if (message.getPayload() instanceof IpmiLanMessage) { - IpmiLanMessage lanMessagePayload = (IpmiLanMessage) message.getPayload(); + /** + * If message is of type {@link IpmiLanMessage}, finds corresponding request message and extracts response data from + * it, + * using data carried in this message. + * + * @param message + * received IPMI message + */ + @Override + protected void handleIncomingMessageInternal(Ipmiv20Message message) { + if (message.getPayload() instanceof IpmiLanMessage) { + IpmiLanMessage lanMessagePayload = (IpmiLanMessage) message.getPayload(); - PayloadCoder coder = messageQueue.getMessageFromQueue(lanMessagePayload.getSequenceNumber()); - int tag = lanMessagePayload.getSequenceNumber(); + PayloadCoder coder = getMessageQueue().getMessageFromQueue(lanMessagePayload.getSequenceNumber()); + int tag = lanMessagePayload.getSequenceNumber(); - logger.debug("Received message with tag " + tag); + LOGGER.debug("Received message with tag " + tag); - if (coder == null) { - logger.debug("No message tagged with " + tag - + " in queue. Dropping orphan message."); - return; - } + if (coder == null) { + LOGGER + .debug( + "No message tagged with " + tag + + " in queue. Dropping orphan message."); + return; + } - if (coder.getClass() == GetChannelAuthenticationCapabilities.class) { - messageQueue.remove(tag); - } else { + if (coder.getClass() == GetChannelAuthenticationCapabilities.class) { + getMessageQueue().remove(tag); + } else { - try { - ResponseData responseData = coder.getResponseData(message); - connection.notifyResponseListeners(connection.getHandle(), tag, responseData, null); - } catch (Exception e) { - connection.notifyResponseListeners(connection.getHandle(), tag, null, e); - } - messageQueue.remove(lanMessagePayload.getSequenceNumber()); - } - } - } + try { + ResponseData responseData = coder.getResponseData(message); + getConnection().notifyResponseListeners(getConnection().getHandle(), tag, responseData, null); + } catch (Exception e) { + getConnection().notifyResponseListeners(getConnection().getHandle(), tag, null, e); + } + getMessageQueue().remove(lanMessagePayload.getSequenceNumber()); + } + } + } } diff --git a/src/main/java/org/metricshub/ipmi/core/connection/MessageHandler.java b/src/main/java/org/metricshub/ipmi/core/connection/MessageHandler.java index 5a41c16..c4e0517 100644 --- a/src/main/java/org/metricshub/ipmi/core/connection/MessageHandler.java +++ b/src/main/java/org/metricshub/ipmi/core/connection/MessageHandler.java @@ -37,117 +37,157 @@ */ public abstract class MessageHandler { - private static final Logger logger = LoggerFactory.getLogger(MessageHandler.class); - - protected int lastReceivedSequenceNumber = 0; - protected final MessageQueue messageQueue; - protected final Connection connection; - - public MessageHandler(Connection connection, int timeout, int minSequenceNumber, int maxSequenceNumber) { - this.messageQueue = new MessageQueue(connection, timeout, minSequenceNumber, maxSequenceNumber); - this.connection = connection; - } - - /** - * Attempts to send message encoded by given {@link PayloadCoder} to the remote system. - * - * @param payloadCoder - * instance of {@link PayloadCoder} that will produce payload for the message being sent. - * @param stateMachine - * {@link StateMachine} for the currenr connection. - * @param sessionId - * ID of the current session. - * @param isOneWay - * flag indicating, if message is one way and we shouldn't await response, - * or it isn't and needs response from remote system - * @return sequence number of the sent message - * @throws ConnectionException when could not send message due to some problems with connection - */ - public int sendMessage(PayloadCoder payloadCoder, StateMachine stateMachine, int sessionId, boolean isOneWay) - throws ConnectionException { - validateSessionState(stateMachine); - - int seq = isOneWay ? messageQueue.getSequenceNumber() : messageQueue.add(payloadCoder); - if (seq > 0) { - stateMachine.doTransition(new Sendv20Message(payloadCoder, sessionId, seq, connection.getNextSessionSequenceNumber())); - } - - return seq; - } - - /** - * Attempts to retry sending message with given tag, assuming that this message exists in message queue. - * - * @param tag - * tag of the message that we want to resend - * @param stateMachine - * {@link StateMachine} for the currenr connection. - * @param sessionId - * ID of the current session. - * @return sequence number of the retried message (should be the same as original message tag) or -1 if no message was found in the queue. - * @throws ConnectionException when could not send message due to some problems with connection - */ - public int retryMessage(int tag, StateMachine stateMachine, int sessionId) throws ConnectionException { - validateSessionState(stateMachine); - - PayloadCoder payloadCoder = messageQueue.getMessageFromQueue(tag); - - if (payloadCoder == null) { - return -1; - } - - stateMachine.doTransition(new Sendv20Message(payloadCoder, sessionId, tag, connection.getNextSessionSequenceNumber())); - - return tag; - } - - private void validateSessionState(StateMachine stateMachine) throws ConnectionException { - if (stateMachine.getCurrent().getClass() != SessionValid.class) { - throw new ConnectionException("Illegal connection state: " + stateMachine.getCurrent().getClass().getSimpleName()); - } - } - - /** - * Checks if received message is inside "sliding window range", and if it is, - * further processes the message in a cimplementation-specific way. - * - * @param message - */ - public void handleIncomingMessage(Ipmiv20Message message) { - - int seq = message.getSessionSequenceNumber(); - - if (seq != 0 && (seq > lastReceivedSequenceNumber + 15 || seq < lastReceivedSequenceNumber - 16)) { - logger.debug("Dropping message " + seq); - return; // if the message's sequence number gets out of the sliding - // window range we need to drop it - } - - if (seq != 0) { - lastReceivedSequenceNumber = (seq > lastReceivedSequenceNumber ? seq : lastReceivedSequenceNumber); - } - - handleIncomingMessageInternal(message); - } - - public void setTimeout(int timeout) { - messageQueue.setTimeout(timeout); - } - - public void tearDown() { - messageQueue.tearDown(); - } - - public int getSequenceNumber() { - return messageQueue.getSequenceNumber(); - } - - /** - * Abstract method for implementation-specific logic for handling incomming IPMI message. - * - * @param message - * IPMI message received from BMC - */ - protected abstract void handleIncomingMessageInternal(Ipmiv20Message message); + private static final Logger LOGGER = LoggerFactory.getLogger(MessageHandler.class); + + private int lastReceivedSequenceNumber = 0; + private final MessageQueue messageQueue; + private final Connection connection; + + /** + * Returns the queue of messages awaiting a response. + * + * @return the {@link MessageQueue} of this handler + */ + protected MessageQueue getMessageQueue() { + return messageQueue; + } + + /** + * Returns the connection this handler serves. + * + * @return the {@link Connection} of this handler + */ + protected Connection getConnection() { + return connection; + } + + /** + * Returns the highest sequence number received so far (sliding window state). + * + * @return the last received sequence number + */ + protected int getLastReceivedSequenceNumber() { + return lastReceivedSequenceNumber; + } + + /** + * Sets the highest sequence number received so far (sliding window state). + * + * @param lastReceivedSequenceNumber the last received sequence number + */ + protected void setLastReceivedSequenceNumber(int lastReceivedSequenceNumber) { + this.lastReceivedSequenceNumber = lastReceivedSequenceNumber; + } + + public MessageHandler(Connection connection, int timeout, int minSequenceNumber, int maxSequenceNumber) { + this.messageQueue = new MessageQueue(connection, timeout, minSequenceNumber, maxSequenceNumber); + this.connection = connection; + } + + /** + * Attempts to send message encoded by given {@link PayloadCoder} to the remote system. + * + * @param payloadCoder + * instance of {@link PayloadCoder} that will produce payload for the message being sent. + * @param stateMachine + * {@link StateMachine} for the currenr connection. + * @param sessionId + * ID of the current session. + * @param isOneWay + * flag indicating, if message is one way and we shouldn't await response, + * or it isn't and needs response from remote system + * @return sequence number of the sent message + * @throws ConnectionException when could not send message due to some problems with connection + */ + public int sendMessage(PayloadCoder payloadCoder, StateMachine stateMachine, int sessionId, boolean isOneWay) + throws ConnectionException { + validateSessionState(stateMachine); + + int seq = isOneWay ? messageQueue.getSequenceNumber() : messageQueue.add(payloadCoder); + if (seq > 0) { + stateMachine + .doTransition(new Sendv20Message(payloadCoder, sessionId, seq, connection.getNextSessionSequenceNumber())); + } + + return seq; + } + + /** + * Attempts to retry sending message with given tag, assuming that this message exists in message queue. + * + * @param tag + * tag of the message that we want to resend + * @param stateMachine + * {@link StateMachine} for the currenr connection. + * @param sessionId + * ID of the current session. + * @return sequence number of the retried message (should be the same as original message tag) or -1 if no message was + * found in the queue. + * @throws ConnectionException when could not send message due to some problems with connection + */ + public int retryMessage(int tag, StateMachine stateMachine, int sessionId) throws ConnectionException { + validateSessionState(stateMachine); + + PayloadCoder payloadCoder = messageQueue.getMessageFromQueue(tag); + + if (payloadCoder == null) { + return -1; + } + + stateMachine + .doTransition(new Sendv20Message(payloadCoder, sessionId, tag, connection.getNextSessionSequenceNumber())); + + return tag; + } + + private void validateSessionState(StateMachine stateMachine) throws ConnectionException { + if (stateMachine.getCurrent().getClass() != SessionValid.class) { + throw new ConnectionException( + "Illegal connection state: " + stateMachine.getCurrent().getClass().getSimpleName()); + } + } + + /** + * Checks if received message is inside "sliding window range", and if it is, + * further processes the message in a cimplementation-specific way. + * + * @param message + */ + public void handleIncomingMessage(Ipmiv20Message message) { + + int seq = message.getSessionSequenceNumber(); + + if (seq != 0 && (seq > lastReceivedSequenceNumber + 15 || seq < lastReceivedSequenceNumber - 16)) { + LOGGER.debug("Dropping message " + seq); + return; // if the message's sequence number gets out of the sliding + // window range we need to drop it + } + + if (seq != 0) { + lastReceivedSequenceNumber = (seq > lastReceivedSequenceNumber ? seq : lastReceivedSequenceNumber); + } + + handleIncomingMessageInternal(message); + } + + public void setTimeout(int timeout) { + messageQueue.setTimeout(timeout); + } + + public void tearDown() { + messageQueue.tearDown(); + } + + public int getSequenceNumber() { + return messageQueue.getSequenceNumber(); + } + + /** + * Abstract method for implementation-specific logic for handling incomming IPMI message. + * + * @param message + * IPMI message received from BMC + */ + protected abstract void handleIncomingMessageInternal(Ipmiv20Message message); } diff --git a/src/main/java/org/metricshub/ipmi/core/connection/Session.java b/src/main/java/org/metricshub/ipmi/core/connection/Session.java index f275aeb..6de8c34 100644 --- a/src/main/java/org/metricshub/ipmi/core/connection/Session.java +++ b/src/main/java/org/metricshub/ipmi/core/connection/Session.java @@ -29,20 +29,20 @@ */ public class Session { - private final int sessionId; - private final ConnectionHandle connectionHandle; + private final int sessionId; + private final ConnectionHandle connectionHandle; - public Session(int sessionId, ConnectionHandle connectionHandle) { - this.sessionId = sessionId; - this.connectionHandle = connectionHandle; - } + public Session(int sessionId, ConnectionHandle connectionHandle) { + this.sessionId = sessionId; + this.connectionHandle = connectionHandle; + } - public int getSessionId() { - return sessionId; - } + public int getSessionId() { + return sessionId; + } - public ConnectionHandle getConnectionHandle() { - return connectionHandle; - } + public ConnectionHandle getConnectionHandle() { + return connectionHandle; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/connection/SessionException.java b/src/main/java/org/metricshub/ipmi/core/connection/SessionException.java index 8d6f7ae..663c815 100644 --- a/src/main/java/org/metricshub/ipmi/core/connection/SessionException.java +++ b/src/main/java/org/metricshub/ipmi/core/connection/SessionException.java @@ -27,7 +27,7 @@ */ public class SessionException extends Exception { - public SessionException(String message, Throwable cause) { - super(message, cause); - } + public SessionException(String message, Throwable cause) { + super(message, cause); + } } diff --git a/src/main/java/org/metricshub/ipmi/core/connection/SessionManager.java b/src/main/java/org/metricshub/ipmi/core/connection/SessionManager.java index f99614d..d076eb2 100644 --- a/src/main/java/org/metricshub/ipmi/core/connection/SessionManager.java +++ b/src/main/java/org/metricshub/ipmi/core/connection/SessionManager.java @@ -40,111 +40,117 @@ */ public class SessionManager { - private static final Logger logger = LoggerFactory.getLogger(SessionManager.class); - - private static Integer sessionId = 100; - - /** - * The session ID generated by the {@link SessionManager}. - * Auto-incremented. - */ - public static synchronized int generateSessionId() { - sessionId %= (Integer.MAX_VALUE / 4); - return sessionId++; - } - - public static Session establishSession(IpmiConnector connector, String remoteHost, int remotePort, String user, String password, - CipherSuiteSelectionHandler cipherSuiteSelectionHandler) throws SessionException { - ConnectionHandle handle = null; - - try { - handle = connector.createConnection(InetAddress.getByName(remoteHost), remotePort); - - List availableCipherSuites = connector.getAvailableCipherSuites(handle); - CipherSuite cipherSuite = cipherSuiteSelectionHandler.choose(availableCipherSuites); - - if (cipherSuite == null) { - cipherSuite = CipherSuite.getEmpty(); - } - - connector.getChannelAuthenticationCapabilities(handle, cipherSuite, PrivilegeLevel.Administrator); - - return connector.openSession(handle, user, password, null); - } catch (Exception e) { - closeConnection(connector, handle); - - throw new SessionException("Cannot create new session due to exception", e); - } - } - - private static void closeConnection(IpmiConnector connector, ConnectionHandle handle) { - try { - if (connector != null && handle != null) { - connector.closeSession(handle); - connector.tearDown(); - } - } catch (Exception e) { - logger.error("Cannot close connection after exception thrown during session establishment.", e); - } - } - - private final ConcurrentHashMap sessionsPerConnectionHandle; - - public SessionManager() { - this.sessionsPerConnectionHandle = new ConcurrentHashMap(); - } - - /** - * Either returns the {@link Session} registered for given connection, or creates new IPMI {@link Session} - * and registers it for the given connection handle, if no session was found for the connection. - * - * @param connectionHandle - * handle of the connection, for which this session should be registered. - * @return newly created session object or session already registered for the connection - */ - public Session registerSession(int sessionId, ConnectionHandle connectionHandle) { - if (connectionHandle.getUser() == null || connectionHandle.getRemoteAddress() == null) { - throw new IllegalArgumentException("Given connection handle is incomplete (lacks user or remote address)"); - } - - Session newSession = new Session(sessionId, connectionHandle); - Session currentSession = sessionsPerConnectionHandle.putIfAbsent(connectionHandle.getHandle(), newSession); - - return currentSession != null ? currentSession : newSession; - } - - /** - * Unregisters session for given connection handle. - * - * @param connectionHandle - * handle of the connection, for which the session should be unregistered. - */ - public void unregisterSession(ConnectionHandle connectionHandle) { - sessionsPerConnectionHandle.remove(connectionHandle.getHandle()); - } - - /** - * Returns session already bound to given connection handle fulfilling given criteria. - * - * @param remoteAddress - * IP addres of the managed system - * @param remotePort - * UDP port of the managed system - * @param user - * IPMI user for whom the connection is established - * @return session object fulfilling given criteria, or null if no session was registered for such connection. - */ - public Session getSessionForCriteria(InetAddress remoteAddress, int remotePort, String user) { - for (Session session : sessionsPerConnectionHandle.values()) { - ConnectionHandle sessionConnectionHandle = session.getConnectionHandle(); - - if (sessionConnectionHandle.getUser().equals(user) - && sessionConnectionHandle.getRemoteAddress().equals(remoteAddress) - && sessionConnectionHandle.getRemotePort() == remotePort) { - return session; - } - } - - return null; - } + private static final Logger LOGGER = LoggerFactory.getLogger(SessionManager.class); + + private static Integer sessionId = 100; + + /** + * The session ID generated by the {@link SessionManager}. + * Auto-incremented. + */ + public static synchronized int generateSessionId() { + sessionId %= (Integer.MAX_VALUE / 4); + return sessionId++; + } + + public static Session establishSession( + IpmiConnector connector, + String remoteHost, + int remotePort, + String user, + String password, + CipherSuiteSelectionHandler cipherSuiteSelectionHandler) + throws SessionException { + ConnectionHandle handle = null; + + try { + handle = connector.createConnection(InetAddress.getByName(remoteHost), remotePort); + + List availableCipherSuites = connector.getAvailableCipherSuites(handle); + CipherSuite cipherSuite = cipherSuiteSelectionHandler.choose(availableCipherSuites); + + if (cipherSuite == null) { + cipherSuite = CipherSuite.getEmpty(); + } + + connector.getChannelAuthenticationCapabilities(handle, cipherSuite, PrivilegeLevel.Administrator); + + return connector.openSession(handle, user, password, null); + } catch (Exception e) { + closeConnection(connector, handle); + + throw new SessionException("Cannot create new session due to exception", e); + } + } + + private static void closeConnection(IpmiConnector connector, ConnectionHandle handle) { + try { + if (connector != null && handle != null) { + connector.closeSession(handle); + connector.tearDown(); + } + } catch (Exception e) { + LOGGER.error("Cannot close connection after exception thrown during session establishment.", e); + } + } + + private final ConcurrentHashMap sessionsPerConnectionHandle; + + public SessionManager() { + this.sessionsPerConnectionHandle = new ConcurrentHashMap(); + } + + /** + * Either returns the {@link Session} registered for given connection, or creates new IPMI {@link Session} + * and registers it for the given connection handle, if no session was found for the connection. + * + * @param connectionHandle + * handle of the connection, for which this session should be registered. + * @return newly created session object or session already registered for the connection + */ + public Session registerSession(int newSessionId, ConnectionHandle connectionHandle) { + if (connectionHandle.getUser() == null || connectionHandle.getRemoteAddress() == null) { + throw new IllegalArgumentException("Given connection handle is incomplete (lacks user or remote address)"); + } + + Session newSession = new Session(newSessionId, connectionHandle); + Session currentSession = sessionsPerConnectionHandle.putIfAbsent(connectionHandle.getHandle(), newSession); + + return currentSession != null ? currentSession : newSession; + } + + /** + * Unregisters session for given connection handle. + * + * @param connectionHandle + * handle of the connection, for which the session should be unregistered. + */ + public void unregisterSession(ConnectionHandle connectionHandle) { + sessionsPerConnectionHandle.remove(connectionHandle.getHandle()); + } + + /** + * Returns session already bound to given connection handle fulfilling given criteria. + * + * @param remoteAddress + * IP addres of the managed system + * @param remotePort + * UDP port of the managed system + * @param user + * IPMI user for whom the connection is established + * @return session object fulfilling given criteria, or null if no session was registered for such connection. + */ + public Session getSessionForCriteria(InetAddress remoteAddress, int remotePort, String user) { + for (Session session : sessionsPerConnectionHandle.values()) { + ConnectionHandle sessionConnectionHandle = session.getConnectionHandle(); + + if (sessionConnectionHandle.getUser().equals(user) + && sessionConnectionHandle.getRemoteAddress().equals(remoteAddress) + && sessionConnectionHandle.getRemotePort() == remotePort) { + return session; + } + } + + return null; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/connection/SolMessageHandler.java b/src/main/java/org/metricshub/ipmi/core/connection/SolMessageHandler.java index e329be1..def4655 100644 --- a/src/main/java/org/metricshub/ipmi/core/connection/SolMessageHandler.java +++ b/src/main/java/org/metricshub/ipmi/core/connection/SolMessageHandler.java @@ -39,58 +39,59 @@ */ public class SolMessageHandler extends MessageHandler { - private static final Logger logger = LoggerFactory.getLogger(SolMessageHandler.class); - - public SolMessageHandler(Connection connection, int timeout) throws IOException { - super(connection, timeout, SolMessage.MIN_SEQUENCE_NUMBER, SolMessage.MAX_SEQUENCE_NUMBER); - } - - /** - * Assuming that given message is SOL message, reads both data and acknowledge information from it, - * notifying registered listeners about incoming data. - * - * @param message - * received IPMI message. - */ - @Override - protected void handleIncomingMessageInternal(Ipmiv20Message message) { - SolInboundMessage payload = (SolInboundMessage) message.getPayload(); - - if (payload.isAcknowledgeMessage()) { - handleIncomingAcknowledgeMessage(message, payload); - } - - if (payload.isDataCarrier()) { - handleIncomingDataMessage(payload); - } - } - - private void handleIncomingAcknowledgeMessage(Ipmiv20Message message, SolInboundMessage payload) { - PayloadCoder coder = messageQueue.getMessageFromQueue(payload.getAckNackSequenceNumber()); - int tag = payload.getAckNackSequenceNumber(); - - logger.debug("Received message with tag " + tag); - - if (coder == null) { - logger.debug("No message tagged with " + tag + " in queue. Dropping orphan message."); - return; - } - - try { - ResponseData responseData = coder.getResponseData(message); - connection.notifyResponseListeners(connection.getHandle(), tag, responseData, null); - } catch (Exception e) { - connection.notifyResponseListeners(connection.getHandle(), tag, null, e); - } - - // Remove message from queue only when it was fully or partially acknowledged. Otherwise, we want to keep it in queue for further retries - if (payload.getStatusField().getAckState() == SolAckState.ACK || payload.getAcceptedCharacterCount() > 0) { - messageQueue.remove(payload.getAckNackSequenceNumber()); - } - } - - private void handleIncomingDataMessage(SolInboundMessage payload) { - connection.notifyRequestListeners(payload); - } + private static final Logger LOGGER = LoggerFactory.getLogger(SolMessageHandler.class); + + public SolMessageHandler(Connection connection, int timeout) throws IOException { + super(connection, timeout, SolMessage.MIN_SEQUENCE_NUMBER, SolMessage.MAX_SEQUENCE_NUMBER); + } + + /** + * Assuming that given message is SOL message, reads both data and acknowledge information from it, + * notifying registered listeners about incoming data. + * + * @param message + * received IPMI message. + */ + @Override + protected void handleIncomingMessageInternal(Ipmiv20Message message) { + SolInboundMessage payload = (SolInboundMessage) message.getPayload(); + + if (payload.isAcknowledgeMessage()) { + handleIncomingAcknowledgeMessage(message, payload); + } + + if (payload.isDataCarrier()) { + handleIncomingDataMessage(payload); + } + } + + private void handleIncomingAcknowledgeMessage(Ipmiv20Message message, SolInboundMessage payload) { + PayloadCoder coder = getMessageQueue().getMessageFromQueue(payload.getAckNackSequenceNumber()); + int tag = payload.getAckNackSequenceNumber(); + + LOGGER.debug("Received message with tag " + tag); + + if (coder == null) { + LOGGER.debug("No message tagged with " + tag + " in queue. Dropping orphan message."); + return; + } + + try { + ResponseData responseData = coder.getResponseData(message); + getConnection().notifyResponseListeners(getConnection().getHandle(), tag, responseData, null); + } catch (Exception e) { + getConnection().notifyResponseListeners(getConnection().getHandle(), tag, null, e); + } + + // Remove message from queue only when it was fully or partially acknowledged. Otherwise, we want to keep it in + // queue for further retries + if (payload.getStatusField().getAckState() == SolAckState.ACK || payload.getAcceptedCharacterCount() > 0) { + getMessageQueue().remove(payload.getAckNackSequenceNumber()); + } + } + + private void handleIncomingDataMessage(SolInboundMessage payload) { + getConnection().notifyRequestListeners(payload); + } } diff --git a/src/main/java/org/metricshub/ipmi/core/connection/queue/MessageQueue.java b/src/main/java/org/metricshub/ipmi/core/connection/queue/MessageQueue.java index 9ad6288..73eb7c7 100644 --- a/src/main/java/org/metricshub/ipmi/core/connection/queue/MessageQueue.java +++ b/src/main/java/org/metricshub/ipmi/core/connection/queue/MessageQueue.java @@ -40,328 +40,333 @@ */ public class MessageQueue extends TimerTask { - private List queue; - private int timeout; - private Timer timer; - private Connection connection; - private int lastSequenceNumber; - private Object lastSequenceNumberLock = new Object(); - private int minSequenceNumber = 1; - private int sequenceNumberUpperBound = 64; - - private static Logger logger = LoggerFactory.getLogger(MessageQueue.class); - - /** - * Frequency of checking messages for timeouts in ms. - */ - private static int cleaningFrequency = 500; - - /** - * Size of the queue determined by IPMI sliding window algorithm - * specification.
- * When queue size is 16, BMC drops some of the messages under heavy load. - */ - private static final int QUEUE_SIZE = 8; - - public int getTimeout() { - return timeout; - } - - public void setTimeout(int timeout) { - this.timeout = timeout; - } - - public MessageQueue(Connection connection, int timeout, int minSequenceNumber, int maxSequenceNumber) { - this.minSequenceNumber = minSequenceNumber; - sequenceNumberUpperBound = maxSequenceNumber + 1; - reservedTags = new ArrayList(); - lastSequenceNumber = minSequenceNumber - 1; - this.connection = connection; - queue = new ArrayList(); - setTimeout(timeout); - timer = new Timer(); - timer.schedule(this, cleaningFrequency, cleaningFrequency); - } - - private int incrementSequenceNumber(int currentSequenceNumber) { - int newSequenceNumber = (currentSequenceNumber + 1) % sequenceNumberUpperBound; - - if (newSequenceNumber == 0) { - newSequenceNumber = minSequenceNumber; - } - - return newSequenceNumber; - } - - /** - * Stops the MessageQueue - */ - public void tearDown() { - timer.cancel(); - } - - private List reservedTags; - - /** - * Check if the tag is reserved. - */ - private synchronized boolean isReserved(int tag) { - return reservedTags.contains(tag); - } - - /** - * Reserves given tag for the use of the invoker. - * - * @param tag - * - tag to reserve - * @return true if tag was reserved successfully, false otherwise - */ - private synchronized boolean reserveTag(int tag) { - if (isReserved(tag)) { - reservedTags.add(tag); - return true; - } - return false; - } - - private synchronized void releaseTag(int tag) { - reservedTags.remove((Integer) tag); - } - - /** - * Adds request to the queue and generates the tag. - * - * @return Sequence number of the message if it was added to the - * queue, -1 otherwise. The tag used to identify message is equal to - * that value. - */ - public int add(PayloadCoder request) { - run(); - boolean first = true; - synchronized (queue) { - synchronized (lastSequenceNumberLock) { - if (queue.size() < QUEUE_SIZE) { - int sequenceNumber = incrementSequenceNumber(lastSequenceNumber); - - while (isReserved(sequenceNumber)) { - sequenceNumber = incrementSequenceNumber(sequenceNumber); - - if (!first) { - try { - lastSequenceNumberLock.wait(1); - } catch (InterruptedException e) { - // TODO log - } - } - - if (sequenceNumber == lastSequenceNumber) { - //we checked all available sequence numbers, so return -1 (no available sequence numbers) - return -1; - } - - first = false; - } - - reserveTag(sequenceNumber); - - lastSequenceNumber = sequenceNumber; - - QueueElement element = new QueueElement(sequenceNumber, request); - - queue.add(element); - return sequenceNumber; - } - } - } - return -1; - - } - - /** - * Removes message with the given tag from the queue. - */ - public void remove(int tag) { - run(); - synchronized (queue) { - int i = 0; - int index = -1; - for (QueueElement element : queue) { - if (element.getId() == tag) { - index = i; - break; - } - ++i; - } - if (index == 0) { - queue.remove(0); - releaseTag(tag); - while (!queue.isEmpty() && queue.get(0).getRequest() == null) { - int additionalTag = queue.get(0).getId(); - queue.remove(0); - releaseTag(additionalTag); - } - } else if (index > 0) { - queue.get(index).setRequest(null); - } - - } - } - - /** - * Removes message from queue at given index. - * - * @param index - */ - public void removeAt(int index) { - if (index >= queue.size()) { - throw new IndexOutOfBoundsException("Index out of bounds : " - + index); - } - - remove(queue.get(index).getId()); - } - - /** - * Checks if queue contains message with the given sequence number. - */ - public boolean containsId(int sequenceNumber) { - synchronized (queue) { - - for (QueueElement element : queue) { - if (element.getId() == sequenceNumber - && element.getRequest() != null) { - return true; - } - } - - } - return false; - } - - /** - * Returns valid session sequence number that cannot be used as a tag though - */ - public int getSequenceNumber() { - synchronized (lastSequenceNumberLock) { - int sequenceNumber = incrementSequenceNumber(lastSequenceNumber); - - lastSequenceNumber = sequenceNumber; - - return sequenceNumber; - } - } - - /** - * Returns message with the given sequence number from the queue or null if - * no message with the given tag is currently in the queue. - */ - public PayloadCoder getMessageFromQueue(int tag) { - synchronized (queue) { - for (QueueElement element : queue) { - if (element.getId() == tag && element.getRequest() != null) { - return element.getRequest(); - } - } - } - return null; - } - - /** - * Returns index of the message with the given sequence number from the - * queue or -1 if no message with the given tag is currently in the queue. - */ - public int getMessageIndexFromQueue(int tag) { - synchronized (queue) { - int i = 0; - for (QueueElement element : queue) { - if (element.getId() == tag && element.getRequest() != null) { - return i; - } - ++i; - } - } - return -1; - } - - /** - * Returns number of retries that were performed on message tagged with tag - * or -1 if no such message can be found in the queue. - * - * @deprecated retries are no longer supported on the message level - */ - @Deprecated - public int getMessageRetries(int tag) { - synchronized (queue) { - for (QueueElement element : queue) { - if (element.getId() == tag && element.getRequest() != null) { - return element.getRetries(); - } - } - } - return -1; - } - - /** - * Returns the ID of the {@link QueueElement} in the queue with the given - * tag. - * - * @param tag - * Tag of the message to find - */ - public int getMessageSequenceNumber(int tag) { - synchronized (queue) { - for (QueueElement element : queue) { - if (element.getId() == tag && element.getRequest() != null) { - return element.getId(); - } - } - } - return -1; - } - - /** - * {@link TimerTask} runner - periodically checks queue for timed out - * messages. - */ - @Override - public void run() { - if (queue != null) { - synchronized (queue) { - boolean process = true; - while (process && !queue.isEmpty()) { - QueueElement oldestQueueElement = queue.get(0); - boolean done = oldestQueueElement.getRequest() == null; - - if (messageJustTimedOut(oldestQueueElement) || done) { - processObsoleteMessage(oldestQueueElement, done); - } else { - process = false; - } - } - } - } - } - - private boolean messageJustTimedOut(QueueElement oldestQueueElement) { - Date now = new Date(); - - return now.getTime() - oldestQueueElement.getTimestamp().getTime() > (long) timeout; - } - - private void processObsoleteMessage(QueueElement message, boolean done) { - int tag = message.getId(); - boolean previouslyTimedOut = message.isTimedOut(); - - if (previouslyTimedOut || done) { - queue.remove(0); - logger.info("Removing message after timeout, tag: " + tag); - releaseTag(tag); - } else { - message.makeTimedOut(); - message.refreshTimestamp(); - connection.notifyResponseListeners(connection.getHandle(), tag, null, - new ConnectionException("Message timed out")); - } - } + private List queue; + private int timeout; + private Timer timer; + private Connection connection; + private int lastSequenceNumber; + private Object lastSequenceNumberLock = new Object(); + private int minSequenceNumber = 1; + private int sequenceNumberUpperBound = 64; + + private static Logger logger = LoggerFactory.getLogger(MessageQueue.class); + + /** + * Frequency of checking messages for timeouts in ms. + */ + private static int cleaningFrequency = 500; + + /** + * Size of the queue determined by IPMI sliding window algorithm + * specification.
+ * When queue size is 16, BMC drops some of the messages under heavy load. + */ + private static final int QUEUE_SIZE = 8; + + public int getTimeout() { + return timeout; + } + + public void setTimeout(int timeout) { + this.timeout = timeout; + } + + public MessageQueue(Connection connection, int timeout, int minSequenceNumber, int maxSequenceNumber) { + this.minSequenceNumber = minSequenceNumber; + sequenceNumberUpperBound = maxSequenceNumber + 1; + reservedTags = new ArrayList(); + lastSequenceNumber = minSequenceNumber - 1; + this.connection = connection; + queue = new ArrayList(); + setTimeout(timeout); + timer = new Timer(); + timer.schedule(this, cleaningFrequency, cleaningFrequency); + } + + private int incrementSequenceNumber(int currentSequenceNumber) { + int newSequenceNumber = (currentSequenceNumber + 1) % sequenceNumberUpperBound; + + if (newSequenceNumber == 0) { + newSequenceNumber = minSequenceNumber; + } + + return newSequenceNumber; + } + + /** + * Stops the MessageQueue + */ + public void tearDown() { + timer.cancel(); + } + + private List reservedTags; + + /** + * Check if the tag is reserved. + */ + private synchronized boolean isReserved(int tag) { + return reservedTags.contains(tag); + } + + /** + * Reserves given tag for the use of the invoker. + * + * @param tag + * - tag to reserve + * @return true if tag was reserved successfully, false otherwise + */ + private synchronized boolean reserveTag(int tag) { + if (isReserved(tag)) { + reservedTags.add(tag); + return true; + } + return false; + } + + private synchronized void releaseTag(int tag) { + reservedTags.remove((Integer) tag); + } + + /** + * Adds request to the queue and generates the tag. + * + * @return Sequence number of the message if it was added to the + * queue, -1 otherwise. The tag used to identify message is equal to + * that value. + */ + public int add(PayloadCoder request) { + run(); + boolean first = true; + synchronized (queue) { + synchronized (lastSequenceNumberLock) { + if (queue.size() < QUEUE_SIZE) { + int sequenceNumber = incrementSequenceNumber(lastSequenceNumber); + + while (isReserved(sequenceNumber)) { + sequenceNumber = incrementSequenceNumber(sequenceNumber); + + if (!first) { + try { + lastSequenceNumberLock.wait(1); + } catch (InterruptedException e) { + // TODO log + } + } + + if (sequenceNumber == lastSequenceNumber) { + // we checked all available sequence numbers, so return -1 (no available sequence numbers) + return -1; + } + + first = false; + } + + reserveTag(sequenceNumber); + + lastSequenceNumber = sequenceNumber; + + QueueElement element = new QueueElement(sequenceNumber, request); + + queue.add(element); + return sequenceNumber; + } + } + } + return -1; + + } + + /** + * Removes message with the given tag from the queue. + */ + public void remove(int tag) { + run(); + synchronized (queue) { + int i = 0; + int index = -1; + for (QueueElement element : queue) { + if (element.getId() == tag) { + index = i; + break; + } + ++i; + } + if (index == 0) { + queue.remove(0); + releaseTag(tag); + while (!queue.isEmpty() && queue.get(0).getRequest() == null) { + int additionalTag = queue.get(0).getId(); + queue.remove(0); + releaseTag(additionalTag); + } + } else if (index > 0) { + queue.get(index).setRequest(null); + } + + } + } + + /** + * Removes message from queue at given index. + * + * @param index + */ + public void removeAt(int index) { + if (index >= queue.size()) { + throw new IndexOutOfBoundsException( + "Index out of bounds : " + + index); + } + + remove(queue.get(index).getId()); + } + + /** + * Checks if queue contains message with the given sequence number. + */ + public boolean containsId(int sequenceNumber) { + synchronized (queue) { + + for (QueueElement element : queue) { + if (element.getId() == sequenceNumber + && element.getRequest() != null) { + return true; + } + } + + } + return false; + } + + /** + * Returns valid session sequence number that cannot be used as a tag though + */ + public int getSequenceNumber() { + synchronized (lastSequenceNumberLock) { + int sequenceNumber = incrementSequenceNumber(lastSequenceNumber); + + lastSequenceNumber = sequenceNumber; + + return sequenceNumber; + } + } + + /** + * Returns message with the given sequence number from the queue or null if + * no message with the given tag is currently in the queue. + */ + public PayloadCoder getMessageFromQueue(int tag) { + synchronized (queue) { + for (QueueElement element : queue) { + if (element.getId() == tag && element.getRequest() != null) { + return element.getRequest(); + } + } + } + return null; + } + + /** + * Returns index of the message with the given sequence number from the + * queue or -1 if no message with the given tag is currently in the queue. + */ + public int getMessageIndexFromQueue(int tag) { + synchronized (queue) { + int i = 0; + for (QueueElement element : queue) { + if (element.getId() == tag && element.getRequest() != null) { + return i; + } + ++i; + } + } + return -1; + } + + /** + * Returns number of retries that were performed on message tagged with tag + * or -1 if no such message can be found in the queue. + * + * @deprecated retries are no longer supported on the message level + */ + @Deprecated + public int getMessageRetries(int tag) { + synchronized (queue) { + for (QueueElement element : queue) { + if (element.getId() == tag && element.getRequest() != null) { + return element.getRetries(); + } + } + } + return -1; + } + + /** + * Returns the ID of the {@link QueueElement} in the queue with the given + * tag. + * + * @param tag + * Tag of the message to find + */ + public int getMessageSequenceNumber(int tag) { + synchronized (queue) { + for (QueueElement element : queue) { + if (element.getId() == tag && element.getRequest() != null) { + return element.getId(); + } + } + } + return -1; + } + + /** + * {@link TimerTask} runner - periodically checks queue for timed out + * messages. + */ + @Override + public void run() { + if (queue != null) { + synchronized (queue) { + boolean process = true; + while (process && !queue.isEmpty()) { + QueueElement oldestQueueElement = queue.get(0); + boolean done = oldestQueueElement.getRequest() == null; + + if (messageJustTimedOut(oldestQueueElement) || done) { + processObsoleteMessage(oldestQueueElement, done); + } else { + process = false; + } + } + } + } + } + + private boolean messageJustTimedOut(QueueElement oldestQueueElement) { + Date now = new Date(); + + return now.getTime() - oldestQueueElement.getTimestamp().getTime() > (long) timeout; + } + + private void processObsoleteMessage(QueueElement message, boolean done) { + int tag = message.getId(); + boolean previouslyTimedOut = message.isTimedOut(); + + if (previouslyTimedOut || done) { + queue.remove(0); + logger.info("Removing message after timeout, tag: " + tag); + releaseTag(tag); + } else { + message.makeTimedOut(); + message.refreshTimestamp(); + connection + .notifyResponseListeners( + connection.getHandle(), + tag, + null, + new ConnectionException("Message timed out")); + } + } } diff --git a/src/main/java/org/metricshub/ipmi/core/connection/queue/QueueElement.java b/src/main/java/org/metricshub/ipmi/core/connection/queue/QueueElement.java index e6ebeaf..504d7c9 100644 --- a/src/main/java/org/metricshub/ipmi/core/connection/queue/QueueElement.java +++ b/src/main/java/org/metricshub/ipmi/core/connection/queue/QueueElement.java @@ -28,79 +28,79 @@ import java.util.Date; public class QueueElement { - private int id; - /** - * @deprecated retries on message level are deprecated - */ - @Deprecated - private int retries; - private boolean timedOut; - - private PayloadCoder request; - private ResponseData response; - private Date timestamp; - - public QueueElement(int id, PayloadCoder request) { - this.id = id; - this.request = request; - timestamp = new Date(); - retries = 0; - this.timedOut = false; - } - - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } - - /** - * @deprecated retries on message level are deprecated - */ - @Deprecated - public int getRetries() { - return retries; - } - - /** - * @deprecated retries on message level are deprecated - */ - @Deprecated - public void setRetries(int retries) { - this.retries = retries; - } - - public PayloadCoder getRequest() { - return request; - } - - public void setRequest(PayloadCoder request) { - this.request = request; - } - - public ResponseData getResponse() { - return response; - } - - public void setResponse(ResponseData response) { - this.response = response; - } - - public Date getTimestamp() { - return timestamp; - } - - public void refreshTimestamp() { - timestamp = new Date(); - } - - public boolean isTimedOut() { - return timedOut; - } - - public void makeTimedOut() { - this.timedOut = true; - } + private int id; + /** + * @deprecated retries on message level are deprecated + */ + @Deprecated + private int retries; + private boolean timedOut; + + private PayloadCoder request; + private ResponseData response; + private Date timestamp; + + public QueueElement(int id, PayloadCoder request) { + this.id = id; + this.request = request; + timestamp = new Date(); + retries = 0; + this.timedOut = false; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + /** + * @deprecated retries on message level are deprecated + */ + @Deprecated + public int getRetries() { + return retries; + } + + /** + * @deprecated retries on message level are deprecated + */ + @Deprecated + public void setRetries(int retries) { + this.retries = retries; + } + + public PayloadCoder getRequest() { + return request; + } + + public void setRequest(PayloadCoder request) { + this.request = request; + } + + public ResponseData getResponse() { + return response; + } + + public void setResponse(ResponseData response) { + this.response = response; + } + + public Date getTimestamp() { + return timestamp; + } + + public void refreshTimestamp() { + timestamp = new Date(); + } + + public boolean isTimedOut() { + return timedOut; + } + + public void makeTimedOut() { + this.timedOut = true; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/package-info.java b/src/main/java/org/metricshub/ipmi/core/package-info.java index 774c184..b985ed2 100644 --- a/src/main/java/org/metricshub/ipmi/core/package-info.java +++ b/src/main/java/org/metricshub/ipmi/core/package-info.java @@ -1,6 +1,7 @@ /** * The library for communicating with server via IPMI protocol.
* The API is included in {@link org.metricshub.ipmi.core.api} + * * @see org.metricshub.ipmi.core.api */ package org.metricshub.ipmi.core; diff --git a/src/main/java/org/metricshub/ipmi/core/sm/MachineObserver.java b/src/main/java/org/metricshub/ipmi/core/sm/MachineObserver.java index 506ca3f..b015e86 100644 --- a/src/main/java/org/metricshub/ipmi/core/sm/MachineObserver.java +++ b/src/main/java/org/metricshub/ipmi/core/sm/MachineObserver.java @@ -26,15 +26,15 @@ /** * An interface for listener of the {@link StateMachine} - * + * * @see StateMachine#register(MachineObserver) */ public interface MachineObserver { - /** - * Notifies observer of action performed by the State Machine. - * - * @param action - * - action performed - */ - void notify(StateMachineAction action); + /** + * Notifies observer of action performed by the State Machine. + * + * @param action + * - action performed + */ + void notify(StateMachineAction action); } diff --git a/src/main/java/org/metricshub/ipmi/core/sm/StateMachine.java b/src/main/java/org/metricshub/ipmi/core/sm/StateMachine.java index f2aa689..e5e3a4a 100644 --- a/src/main/java/org/metricshub/ipmi/core/sm/StateMachine.java +++ b/src/main/java/org/metricshub/ipmi/core/sm/StateMachine.java @@ -44,153 +44,153 @@ */ public class StateMachine implements UdpListener { - private List observers; - - private State current; - - private Messenger messenger; - private InetAddress remoteMachineAddress; - private int remoteMachinePort; - - private boolean initialized; - - public State getCurrent() { - return current; - } - - public void setCurrent(State current) { - this.current = current; - current.onEnter(this); - } - - /** - * Initializes the State Machine - * - * @param messenger - * - {@link Messenger} connected to the - * {@link Constants#IPMI_PORT} - */ - public StateMachine(Messenger messenger) { - this.messenger = messenger; - observers = new ArrayList(); - initialized = false; - } - - /** - * Sends message via {@link #messenger} to the managed system. - * - * @param message - * - the encoded message - * @throws IOException - * - when sending of the message fails - */ - public void sendMessage(byte[] message) throws IOException { - UdpMessage udpMessage = new UdpMessage(); - udpMessage.setAddress(getRemoteMachineAddress()); - udpMessage.setPort(getRemoteMachinePort()); - udpMessage.setMessage(message); - messenger.send(udpMessage); - } - - public InetAddress getRemoteMachineAddress() { - return remoteMachineAddress; - } - - public int getRemoteMachinePort() { - return remoteMachinePort; - } - - /** - * Sends a notification of an action to all {@link MachineObserver}s - * - * @param action - * - a {@link StateMachineAction} to perform - */ - public void doExternalAction(StateMachineAction action) { - for (MachineObserver observer : observers) { - if (observer != null) { - observer.notify(action); - } - } - } - - /** - * Sets the State Machine in the initial state. - * - * @param address - * - IP address of the remote machine. - * @param port - * - UDP remoteMachinePort of the remote machine - * @see #stop() - */ - public void start(InetAddress address, int port) { - messenger.register(this); - remoteMachineAddress = address; - this.remoteMachinePort = port; - setCurrent(new Uninitialized()); - initialized = true; - } - - /** - * Cleans up the machine resources. - * - * @see #start(InetAddress, int) - */ - public void stop() { - messenger.unregister(this); - initialized = false; - } - - /** - * @return true if {@link StateMachine} is initialized, false otherwise. - * @see #start(InetAddress, int) - * @see #stop() - */ - public boolean isActive() { - return initialized; - } - - /** - * Performs a {@link State} transition according to the event and - * {@link #current} state - * - * @param event - * - {@link StateMachineEvent} invoking the transition - * @throws NullPointerException - * - when machine was not yet started - * @see #start(InetAddress, int) - */ - public void doTransition(StateMachineEvent event) { - if (!initialized) { - throw new NullPointerException("State machine not started"); - } - current.doTransition(this, event); - } - - @Override - public void notifyMessage(UdpMessage message) { - if (message.getAddress().equals(getRemoteMachineAddress()) && message.getPort() == getRemoteMachinePort()) { - current.doAction(this, RmcpDecoder.decode(message.getMessage())); - } - } - - /** - * Registers the listener in the {@link StateMachine} so it will be notified - * of the {@link StateMachineAction}s performed via - * {@link #doExternalAction(StateMachineAction)} - * - * @param observer - * - {@link MachineObserver} to register - */ - public void register(MachineObserver observer) { - observers.add(observer); - } - - /** - * @return true if {@link StateMachine} is at the point when it acquires - * session and will send sessionless messages - */ - public boolean isSessionChallenging() { - return !initialized || getCurrent().getClass() == SessionValid.class; - } + private List observers; + + private State current; + + private Messenger messenger; + private InetAddress remoteMachineAddress; + private int remoteMachinePort; + + private boolean initialized; + + public State getCurrent() { + return current; + } + + public void setCurrent(State current) { + this.current = current; + current.onEnter(this); + } + + /** + * Initializes the State Machine + * + * @param messenger + * - {@link Messenger} connected to the + * {@link Constants#IPMI_PORT} + */ + public StateMachine(Messenger messenger) { + this.messenger = messenger; + observers = new ArrayList(); + initialized = false; + } + + /** + * Sends message via {@link #messenger} to the managed system. + * + * @param message + * - the encoded message + * @throws IOException + * - when sending of the message fails + */ + public void sendMessage(byte[] message) throws IOException { + UdpMessage udpMessage = new UdpMessage(); + udpMessage.setAddress(getRemoteMachineAddress()); + udpMessage.setPort(getRemoteMachinePort()); + udpMessage.setMessage(message); + messenger.send(udpMessage); + } + + public InetAddress getRemoteMachineAddress() { + return remoteMachineAddress; + } + + public int getRemoteMachinePort() { + return remoteMachinePort; + } + + /** + * Sends a notification of an action to all {@link MachineObserver}s + * + * @param action + * - a {@link StateMachineAction} to perform + */ + public void doExternalAction(StateMachineAction action) { + for (MachineObserver observer : observers) { + if (observer != null) { + observer.notify(action); + } + } + } + + /** + * Sets the State Machine in the initial state. + * + * @param address + * - IP address of the remote machine. + * @param port + * - UDP remoteMachinePort of the remote machine + * @see #stop() + */ + public void start(InetAddress address, int port) { + messenger.register(this); + remoteMachineAddress = address; + this.remoteMachinePort = port; + setCurrent(new Uninitialized()); + initialized = true; + } + + /** + * Cleans up the machine resources. + * + * @see #start(InetAddress, int) + */ + public void stop() { + messenger.unregister(this); + initialized = false; + } + + /** + * @return true if {@link StateMachine} is initialized, false otherwise. + * @see #start(InetAddress, int) + * @see #stop() + */ + public boolean isActive() { + return initialized; + } + + /** + * Performs a {@link State} transition according to the event and + * {@link #current} state + * + * @param event + * - {@link StateMachineEvent} invoking the transition + * @throws NullPointerException + * - when machine was not yet started + * @see #start(InetAddress, int) + */ + public void doTransition(StateMachineEvent event) { + if (!initialized) { + throw new NullPointerException("State machine not started"); + } + current.doTransition(this, event); + } + + @Override + public void notifyMessage(UdpMessage message) { + if (message.getAddress().equals(getRemoteMachineAddress()) && message.getPort() == getRemoteMachinePort()) { + current.doAction(this, RmcpDecoder.decode(message.getMessage())); + } + } + + /** + * Registers the listener in the {@link StateMachine} so it will be notified + * of the {@link StateMachineAction}s performed via + * {@link #doExternalAction(StateMachineAction)} + * + * @param observer + * - {@link MachineObserver} to register + */ + public void register(MachineObserver observer) { + observers.add(observer); + } + + /** + * @return true if {@link StateMachine} is at the point when it acquires + * session and will send sessionless messages + */ + public boolean isSessionChallenging() { + return !initialized || getCurrent().getClass() == SessionValid.class; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/sm/actions/ErrorAction.java b/src/main/java/org/metricshub/ipmi/core/sm/actions/ErrorAction.java index 67aa344..050e0a8 100644 --- a/src/main/java/org/metricshub/ipmi/core/sm/actions/ErrorAction.java +++ b/src/main/java/org/metricshub/ipmi/core/sm/actions/ErrorAction.java @@ -27,13 +27,13 @@ */ public class ErrorAction extends StateMachineAction { - private Exception exception; + private Exception exception; - public ErrorAction(Exception e) { - exception = e; - } + public ErrorAction(Exception e) { + exception = e; + } - public Exception getException() { - return exception; - } + public Exception getException() { + return exception; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/sm/actions/GetSikAction.java b/src/main/java/org/metricshub/ipmi/core/sm/actions/GetSikAction.java index afaf876..a76a407 100644 --- a/src/main/java/org/metricshub/ipmi/core/sm/actions/GetSikAction.java +++ b/src/main/java/org/metricshub/ipmi/core/sm/actions/GetSikAction.java @@ -26,13 +26,13 @@ * Returns the Session Integrity Key calculated after receiving RAKP Message 2. */ public class GetSikAction extends StateMachineAction { - private byte[] sik; + private byte[] sik; - public GetSikAction(byte[] sik) { - this.sik = sik; - } + public GetSikAction(byte[] sik) { + this.sik = sik; + } - public byte[] getSik() { - return sik; - } + public byte[] getSik() { + return sik; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/sm/actions/MessageAction.java b/src/main/java/org/metricshub/ipmi/core/sm/actions/MessageAction.java index b75dc05..74ced32 100644 --- a/src/main/java/org/metricshub/ipmi/core/sm/actions/MessageAction.java +++ b/src/main/java/org/metricshub/ipmi/core/sm/actions/MessageAction.java @@ -30,13 +30,13 @@ * levels of the architecture) received in the {@link SessionValid} state. */ public class MessageAction extends StateMachineAction { - public MessageAction(Ipmiv20Message message) { - ipmiResponseData = message; - } + public MessageAction(Ipmiv20Message message) { + ipmiResponseData = message; + } - private Ipmiv20Message ipmiResponseData; + private Ipmiv20Message ipmiResponseData; - public Ipmiv20Message getIpmiv20Message() { - return ipmiResponseData; - } + public Ipmiv20Message getIpmiv20Message() { + return ipmiResponseData; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/sm/actions/ResponseAction.java b/src/main/java/org/metricshub/ipmi/core/sm/actions/ResponseAction.java index 1634741..e661f53 100644 --- a/src/main/java/org/metricshub/ipmi/core/sm/actions/ResponseAction.java +++ b/src/main/java/org/metricshub/ipmi/core/sm/actions/ResponseAction.java @@ -30,17 +30,17 @@ */ public class ResponseAction extends StateMachineAction { - public ResponseAction(ResponseData ipmiResponseData) { - setIpmiResponseData(ipmiResponseData); - } + public ResponseAction(ResponseData ipmiResponseData) { + setIpmiResponseData(ipmiResponseData); + } - private ResponseData ipmiResponseData; + private ResponseData ipmiResponseData; - public void setIpmiResponseData(ResponseData ipmiResponseData) { - this.ipmiResponseData = ipmiResponseData; - } + public void setIpmiResponseData(ResponseData ipmiResponseData) { + this.ipmiResponseData = ipmiResponseData; + } - public ResponseData getIpmiResponseData() { - return ipmiResponseData; - } + public ResponseData getIpmiResponseData() { + return ipmiResponseData; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/sm/actions/StateMachineAction.java b/src/main/java/org/metricshub/ipmi/core/sm/actions/StateMachineAction.java index 3eba860..61bb81f 100644 --- a/src/main/java/org/metricshub/ipmi/core/sm/actions/StateMachineAction.java +++ b/src/main/java/org/metricshub/ipmi/core/sm/actions/StateMachineAction.java @@ -25,7 +25,7 @@ import org.metricshub.ipmi.core.sm.StateMachine; /** - * Abstract for external action of the {@link StateMachine} + * Abstract for external action of the {@link StateMachine} */ public abstract class StateMachineAction { diff --git a/src/main/java/org/metricshub/ipmi/core/sm/events/AuthenticationCapabilitiesReceived.java b/src/main/java/org/metricshub/ipmi/core/sm/events/AuthenticationCapabilitiesReceived.java index f125078..b489e0a 100644 --- a/src/main/java/org/metricshub/ipmi/core/sm/events/AuthenticationCapabilitiesReceived.java +++ b/src/main/java/org/metricshub/ipmi/core/sm/events/AuthenticationCapabilitiesReceived.java @@ -29,24 +29,24 @@ /** * Performs transition from {@link AuthcapWaiting} to {@link Authcap}. - * + * * @see StateMachine */ public class AuthenticationCapabilitiesReceived extends StateMachineEvent { - private int sessionId; - private PrivilegeLevel privilegeLevel; + private int sessionId; + private PrivilegeLevel privilegeLevel; - public AuthenticationCapabilitiesReceived(int sessionId, PrivilegeLevel privilegeLevel) { - this.sessionId = sessionId; - this.privilegeLevel = privilegeLevel; - } + public AuthenticationCapabilitiesReceived(int sessionId, PrivilegeLevel privilegeLevel) { + this.sessionId = sessionId; + this.privilegeLevel = privilegeLevel; + } - public int getSessionId() { - return sessionId; - } - public PrivilegeLevel getPrivilegeLevel() { - return privilegeLevel; - } + public int getSessionId() { + return sessionId; + } + public PrivilegeLevel getPrivilegeLevel() { + return privilegeLevel; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/sm/events/Authorize.java b/src/main/java/org/metricshub/ipmi/core/sm/events/Authorize.java index 80f58b5..266f195 100644 --- a/src/main/java/org/metricshub/ipmi/core/sm/events/Authorize.java +++ b/src/main/java/org/metricshub/ipmi/core/sm/events/Authorize.java @@ -30,21 +30,21 @@ /** * Performs transition from {@link Authcap} to {@link OpenSessionWaiting}. - * + * * @see StateMachine */ public class Authorize extends Default { - private int sessionId; + private int sessionId; - public int getSessionId() { - return sessionId; - } + public int getSessionId() { + return sessionId; + } - public Authorize(CipherSuite cipherSuite, int sequenceNumber, - PrivilegeLevel privilegeLevel, int sessionId) { - super(cipherSuite, sequenceNumber, privilegeLevel); - this.sessionId = sessionId; - } + public Authorize(CipherSuite cipherSuite, int sequenceNumber, + PrivilegeLevel privilegeLevel, int sessionId) { + super(cipherSuite, sequenceNumber, privilegeLevel); + this.sessionId = sessionId; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/sm/events/CloseSession.java b/src/main/java/org/metricshub/ipmi/core/sm/events/CloseSession.java index 0638500..35d7f8a 100644 --- a/src/main/java/org/metricshub/ipmi/core/sm/events/CloseSession.java +++ b/src/main/java/org/metricshub/ipmi/core/sm/events/CloseSession.java @@ -34,34 +34,33 @@ * transit to {@link Authcap} {@link State} the session. */ public class CloseSession extends StateMachineEvent { - private int sessionId; - private int messageSequenceNumber; - private int sessionSequenceNumber; + private int sessionId; + private int messageSequenceNumber; + private int sessionSequenceNumber; - /** - * Prepares {@link CloseSession} - * - * @param sessionId - * - managed system session ID - * - * @param messageSequenceNumber - * - generated sequence number for the message to send - */ - public CloseSession(int sessionId, int messageSequenceNumber, int sessionSequenceNumber) { - this.messageSequenceNumber = messageSequenceNumber; - this.sessionSequenceNumber = sessionSequenceNumber; - this.sessionId = sessionId; - } + /** + * Prepares {@link CloseSession} + * + * @param sessionId + * - managed system session ID + * @param messageSequenceNumber + * - generated sequence number for the message to send + */ + public CloseSession(int sessionId, int messageSequenceNumber, int sessionSequenceNumber) { + this.messageSequenceNumber = messageSequenceNumber; + this.sessionSequenceNumber = sessionSequenceNumber; + this.sessionId = sessionId; + } - public int getSessionId() { - return sessionId; - } + public int getSessionId() { + return sessionId; + } - public int getMessageSequenceNumber() { - return messageSequenceNumber; - } + public int getMessageSequenceNumber() { + return messageSequenceNumber; + } - public int getSessionSequenceNumber() { - return sessionSequenceNumber; - } + public int getSessionSequenceNumber() { + return sessionSequenceNumber; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/sm/events/Default.java b/src/main/java/org/metricshub/ipmi/core/sm/events/Default.java index 67cc5c7..91b1799 100644 --- a/src/main/java/org/metricshub/ipmi/core/sm/events/Default.java +++ b/src/main/java/org/metricshub/ipmi/core/sm/events/Default.java @@ -28,28 +28,30 @@ /** * Generic event that is used in a few transitions. + * * @see StateMachine */ public class Default extends StateMachineEvent { - private CipherSuite cipherSuite; - private int sequenceNumber; - private PrivilegeLevel privilegeLevel; - - public Default(CipherSuite cipherSuite, int sequenceNumber, PrivilegeLevel privilegeLevel) { - this.cipherSuite = cipherSuite; - this.sequenceNumber = sequenceNumber; - this.privilegeLevel = privilegeLevel; - } - - public CipherSuite getCipherSuite() { - return cipherSuite; - } - public int getSequenceNumber() { - return sequenceNumber; - } - public PrivilegeLevel getPrivilegeLevel() { - return privilegeLevel; - } + private CipherSuite cipherSuite; + private int sequenceNumber; + private PrivilegeLevel privilegeLevel; + + public Default(CipherSuite cipherSuite, int sequenceNumber, PrivilegeLevel privilegeLevel) { + this.cipherSuite = cipherSuite; + this.sequenceNumber = sequenceNumber; + this.privilegeLevel = privilegeLevel; + } + + public CipherSuite getCipherSuite() { + return cipherSuite; + } + + public int getSequenceNumber() { + return sequenceNumber; + } + public PrivilegeLevel getPrivilegeLevel() { + return privilegeLevel; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/sm/events/DefaultAck.java b/src/main/java/org/metricshub/ipmi/core/sm/events/DefaultAck.java index 421bfdf..aaa7d4b 100644 --- a/src/main/java/org/metricshub/ipmi/core/sm/events/DefaultAck.java +++ b/src/main/java/org/metricshub/ipmi/core/sm/events/DefaultAck.java @@ -27,7 +27,7 @@ /** * Default message for acknowledging received IPMI responses. Performs a few {@link State} transitions. - * + * * @see StateMachine */ public class DefaultAck extends StateMachineEvent { diff --git a/src/main/java/org/metricshub/ipmi/core/sm/events/GetChannelCipherSuitesPending.java b/src/main/java/org/metricshub/ipmi/core/sm/events/GetChannelCipherSuitesPending.java index 081dc08..e31d436 100644 --- a/src/main/java/org/metricshub/ipmi/core/sm/events/GetChannelCipherSuitesPending.java +++ b/src/main/java/org/metricshub/ipmi/core/sm/events/GetChannelCipherSuitesPending.java @@ -33,14 +33,16 @@ * Performed in {@link CiphersWaiting} {@link State} indcates that not all * available {@link CipherSuite}s were received from the remote system and more * {@link GetChannelCipherSuites} commands are needed. - * + * * @see StateMachine */ public class GetChannelCipherSuitesPending extends Default { - public GetChannelCipherSuitesPending(int sequenceNumber) { - super(CipherSuite.getEmpty(), sequenceNumber, - PrivilegeLevel.MaximumAvailable); - } + public GetChannelCipherSuitesPending(int sequenceNumber) { + super( + CipherSuite.getEmpty(), + sequenceNumber, + PrivilegeLevel.MaximumAvailable); + } } diff --git a/src/main/java/org/metricshub/ipmi/core/sm/events/OpenSessionAck.java b/src/main/java/org/metricshub/ipmi/core/sm/events/OpenSessionAck.java index 8c06daf..21ce3ee 100644 --- a/src/main/java/org/metricshub/ipmi/core/sm/events/OpenSessionAck.java +++ b/src/main/java/org/metricshub/ipmi/core/sm/events/OpenSessionAck.java @@ -31,67 +31,67 @@ /** * Performs transition from {@link OpenSessionComplete} to {@link Rakp1Waiting}. - * + * * @see StateMachine */ public class OpenSessionAck extends Default { - private int managedSystemSessionId; - private String username; - private String password; - private byte[] bmcKey; + private int managedSystemSessionId; + private String username; + private String password; + private byte[] bmcKey; - /** - * Provides data required to send RAKP Message 1. - * - * @param cipherSuite - * - {@link CipherSuite} containing authentication, - * confidentiality and integrity algorithms for this session. - * @param sequenceNumber - * - a sequence number for the message - * @param managedSystemSessionId - * - The Managed System's Session ID for this session. Must be as - * returned by the Managed System in the Open Session Response - * message. - * @param privilegeLevel - * - Requested Maximum {@link PrivilegeLevel} - * @param username - * - ASCII character Name that the user at the Remote Console - * wishes to assume for this session. It's length cannot exceed - * 16. - * @param password - * - password matching username - * @param bmcKey - * - BMC specific key. Should be null if Get Channel - * Authentication Capabilities Response indicated that Kg is - * disabled which means that 'one-key' logins are being used ( - * {@link GetChannelAuthenticationCapabilitiesResponseData#isKgEnabled()} - * == false) - */ - public OpenSessionAck(CipherSuite cipherSuite, - PrivilegeLevel privilegeLevel, int sequenceNumber, - int managedSystemSessionId, String username, String password, - byte[] bmcKey) { - super(cipherSuite, sequenceNumber, privilegeLevel); - this.managedSystemSessionId = managedSystemSessionId; - this.username = username; - this.password = password; - this.bmcKey = bmcKey; - } + /** + * Provides data required to send RAKP Message 1. + * + * @param cipherSuite + * - {@link CipherSuite} containing authentication, + * confidentiality and integrity algorithms for this session. + * @param sequenceNumber + * - a sequence number for the message + * @param managedSystemSessionId + * - The Managed System's Session ID for this session. Must be as + * returned by the Managed System in the Open Session Response + * message. + * @param privilegeLevel + * - Requested Maximum {@link PrivilegeLevel} + * @param username + * - ASCII character Name that the user at the Remote Console + * wishes to assume for this session. It's length cannot exceed + * 16. + * @param password + * - password matching username + * @param bmcKey + * - BMC specific key. Should be null if Get Channel + * Authentication Capabilities Response indicated that Kg is + * disabled which means that 'one-key' logins are being used ( + * {@link GetChannelAuthenticationCapabilitiesResponseData#isKgEnabled()} + * == false) + */ + public OpenSessionAck(CipherSuite cipherSuite, + PrivilegeLevel privilegeLevel, int sequenceNumber, + int managedSystemSessionId, String username, String password, + byte[] bmcKey) { + super(cipherSuite, sequenceNumber, privilegeLevel); + this.managedSystemSessionId = managedSystemSessionId; + this.username = username; + this.password = password; + this.bmcKey = bmcKey; + } - public int getManagedSystemSessionId() { - return managedSystemSessionId; - } + public int getManagedSystemSessionId() { + return managedSystemSessionId; + } - public String getUsername() { - return username; - } + public String getUsername() { + return username; + } - public String getPassword() { - return password; - } + public String getPassword() { + return password; + } - public byte[] getBmcKey() { - return bmcKey; - } + public byte[] getBmcKey() { + return bmcKey; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/sm/events/Rakp2Ack.java b/src/main/java/org/metricshub/ipmi/core/sm/events/Rakp2Ack.java index d159ea0..b78a12b 100644 --- a/src/main/java/org/metricshub/ipmi/core/sm/events/Rakp2Ack.java +++ b/src/main/java/org/metricshub/ipmi/core/sm/events/Rakp2Ack.java @@ -30,63 +30,62 @@ /** * Performs transition from {@link Rakp1Complete} to {@link Rakp3Waiting}. - * + * * @see StateMachine */ public class Rakp2Ack extends StateMachineEvent { - private byte statusCode; - private CipherSuite cipherSuite; - private int sequenceNumber; - private int managedSystemSessionId; - private Rakp1ResponseData rakp1ResponseData; + private byte statusCode; + private CipherSuite cipherSuite; + private int sequenceNumber; + private int managedSystemSessionId; + private Rakp1ResponseData rakp1ResponseData; - /** - * Prepares {@link Rakp2Ack}. - * - * @param cipherSuite - * - {@link CipherSuite} containing authentication, - * confidentiality and integrity algorithms for this session. - * Only authentication algorithm is used at this point of - * creating a session. - * @param statusCode - * - Status of the previous message. - * @param sequenceNumber - * - * @param managedSystemSessionId - * - The Managed System's Session ID for this session. Must be as - * returned by the Managed System in the Open Session Response - * message. - * @param rakp1ResponseData - * - RAKP Message 2 received earlier in the authentification - * process - */ - public Rakp2Ack(CipherSuite cipherSuite, int sequenceNumber, - byte statusCode, int managedSystemSessionId, - Rakp1ResponseData rakp1ResponseData) { - this.statusCode = statusCode; - this.cipherSuite = cipherSuite; - this.sequenceNumber = sequenceNumber; - this.managedSystemSessionId = managedSystemSessionId; - this.rakp1ResponseData = rakp1ResponseData; - } + /** + * Prepares {@link Rakp2Ack}. + * + * @param cipherSuite + * - {@link CipherSuite} containing authentication, + * confidentiality and integrity algorithms for this session. + * Only authentication algorithm is used at this point of + * creating a session. + * @param statusCode + * - Status of the previous message. + * @param sequenceNumber + * @param managedSystemSessionId + * - The Managed System's Session ID for this session. Must be as + * returned by the Managed System in the Open Session Response + * message. + * @param rakp1ResponseData + * - RAKP Message 2 received earlier in the authentification + * process + */ + public Rakp2Ack(CipherSuite cipherSuite, int sequenceNumber, + byte statusCode, int managedSystemSessionId, + Rakp1ResponseData rakp1ResponseData) { + this.statusCode = statusCode; + this.cipherSuite = cipherSuite; + this.sequenceNumber = sequenceNumber; + this.managedSystemSessionId = managedSystemSessionId; + this.rakp1ResponseData = rakp1ResponseData; + } - public byte getStatusCode() { - return statusCode; - } + public byte getStatusCode() { + return statusCode; + } - public CipherSuite getCipherSuite() { - return cipherSuite; - } + public CipherSuite getCipherSuite() { + return cipherSuite; + } - public int getSequenceNumber() { - return sequenceNumber; - } + public int getSequenceNumber() { + return sequenceNumber; + } - public int getManagedSystemSessionId() { - return managedSystemSessionId; - } + public int getManagedSystemSessionId() { + return managedSystemSessionId; + } - public Rakp1ResponseData getRakp1ResponseData() { - return rakp1ResponseData; - } + public Rakp1ResponseData getRakp1ResponseData() { + return rakp1ResponseData; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/sm/events/Sendv20Message.java b/src/main/java/org/metricshub/ipmi/core/sm/events/Sendv20Message.java index 4f6d856..63b9807 100644 --- a/src/main/java/org/metricshub/ipmi/core/sm/events/Sendv20Message.java +++ b/src/main/java/org/metricshub/ipmi/core/sm/events/Sendv20Message.java @@ -30,71 +30,81 @@ /** * Performed in {@link SessionValid} {@link State} will cause {@link #message} * to be sent. - * + * * @see StateMachine */ public class Sendv20Message extends StateMachineEvent { - private PayloadCoder message; - private int sessionId; - private int messageSequenceNumber; - private int sessionSequenceNumber; + private PayloadCoder message; + private int sessionId; + private int messageSequenceNumber; + private int sessionSequenceNumber; - /** - * Prepares an event for {@link StateMachine} that will perform sending an - * IPMI command in v2.0 format. Only possible in {@link SessionValid} - * {@link State} - * - * @param payloadCoder - * - The payload to send. - * @param sessionId - * - managed system session ID - * @param messageSequenceNumber - * - generated sequence number for the message to send - */ - public Sendv20Message(PayloadCoder payloadCoder, int sessionId, - int messageSequenceNumber, int sessionSequenceNumber) { - message = payloadCoder; - this.sessionId = sessionId; - this.messageSequenceNumber = messageSequenceNumber; - this.sessionSequenceNumber = sessionSequenceNumber; - } + /** + * Prepares an event for {@link StateMachine} that will perform sending an + * IPMI command in v2.0 format. Only possible in {@link SessionValid} + * {@link State} + * + * @param payloadCoder + * - The payload to send. + * @param sessionId + * - managed system session ID + * @param messageSequenceNumber + * - generated sequence number for the message to send + */ + public Sendv20Message(PayloadCoder payloadCoder, int sessionId, + int messageSequenceNumber, int sessionSequenceNumber) { + message = payloadCoder; + this.sessionId = sessionId; + this.messageSequenceNumber = messageSequenceNumber; + this.sessionSequenceNumber = sessionSequenceNumber; + } - public int getSessionId() { - return sessionId; - } + public int getSessionId() { + return sessionId; + } - public int getMessageSequenceNumber() { - return messageSequenceNumber; - } + public int getMessageSequenceNumber() { + return messageSequenceNumber; + } - public int getSessionSequenceNumber() { - return sessionSequenceNumber; - } + public int getSessionSequenceNumber() { + return sessionSequenceNumber; + } - public PayloadCoder getPayloadCoder() { - return message; - } + public PayloadCoder getPayloadCoder() { + return message; + } - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } - Sendv20Message that = (Sendv20Message) o; + Sendv20Message that = (Sendv20Message) o; - if (sessionId != that.sessionId) return false; - if (messageSequenceNumber != that.messageSequenceNumber) return false; - if (sessionSequenceNumber != that.sessionSequenceNumber) return false; + if (sessionId != that.sessionId) { + return false; + } + if (messageSequenceNumber != that.messageSequenceNumber) { + return false; + } + if (sessionSequenceNumber != that.sessionSequenceNumber) { + return false; + } - return message != null ? message.equals(that.message) : that.message == null; - } + return message != null ? message.equals(that.message) : that.message == null; + } - @Override - public int hashCode() { - int result = message != null ? message.hashCode() : 0; - result = 31 * result + sessionId; - result = 31 * result + messageSequenceNumber; - result = 31 * result + sessionSequenceNumber; - return result; - } + @Override + public int hashCode() { + int result = message != null ? message.hashCode() : 0; + result = 31 * result + sessionId; + result = 31 * result + messageSequenceNumber; + result = 31 * result + sessionSequenceNumber; + return result; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/sm/events/SessionUpkeep.java b/src/main/java/org/metricshub/ipmi/core/sm/events/SessionUpkeep.java index 9f8c2c2..58a6ce0 100644 --- a/src/main/java/org/metricshub/ipmi/core/sm/events/SessionUpkeep.java +++ b/src/main/java/org/metricshub/ipmi/core/sm/events/SessionUpkeep.java @@ -32,41 +32,39 @@ * {@link SessionValid} {@link State} to send * {@link GetChannelAuthenticationCapabilities} to the BMC in order to keep up * the session. - * + * * @see StateMachine */ public class SessionUpkeep extends StateMachineEvent { - private int sessionId; - private int messageSequenceNumber; - private int sessionSequenceNumber; + private int sessionId; + private int messageSequenceNumber; + private int sessionSequenceNumber; - /** - * Prepares {@link SessionUpkeep} - * - * @param sessionId - * - managed system session ID - * - * @param messageSequenceNumber - * - generated payload sequence number for the message to send - * - * @param sessionSequenceNumber - * - generated session sequence number for the message to send. - */ - public SessionUpkeep(int sessionId, int messageSequenceNumber, int sessionSequenceNumber) { - this.messageSequenceNumber = messageSequenceNumber; - this.sessionSequenceNumber = sessionSequenceNumber; - this.sessionId = sessionId; - } + /** + * Prepares {@link SessionUpkeep} + * + * @param sessionId + * - managed system session ID + * @param messageSequenceNumber + * - generated payload sequence number for the message to send + * @param sessionSequenceNumber + * - generated session sequence number for the message to send. + */ + public SessionUpkeep(int sessionId, int messageSequenceNumber, int sessionSequenceNumber) { + this.messageSequenceNumber = messageSequenceNumber; + this.sessionSequenceNumber = sessionSequenceNumber; + this.sessionId = sessionId; + } - public int getSessionId() { - return sessionId; - } + public int getSessionId() { + return sessionId; + } - public int getMessageSequenceNumber() { - return messageSequenceNumber; - } + public int getMessageSequenceNumber() { + return messageSequenceNumber; + } - public int getSessionSequenceNumber() { - return sessionSequenceNumber; - } + public int getSessionSequenceNumber() { + return sessionSequenceNumber; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/sm/events/StartSession.java b/src/main/java/org/metricshub/ipmi/core/sm/events/StartSession.java index a58750d..bde6e8c 100644 --- a/src/main/java/org/metricshub/ipmi/core/sm/events/StartSession.java +++ b/src/main/java/org/metricshub/ipmi/core/sm/events/StartSession.java @@ -31,23 +31,23 @@ * Acknowledges starting the session after receiving RAKP Message 4 ( * {@link StateMachine} transits from {@link Rakp3Complete} to * {@link SessionValid}) - * + * * @see StateMachine */ public class StartSession extends StateMachineEvent { - private CipherSuite cipherSuite; - private int sessionId; + private CipherSuite cipherSuite; + private int sessionId; - public StartSession(CipherSuite cipherSuite, int sessionId) { - this.cipherSuite = cipherSuite; - this.sessionId = sessionId; - } + public StartSession(CipherSuite cipherSuite, int sessionId) { + this.cipherSuite = cipherSuite; + this.sessionId = sessionId; + } - public CipherSuite getCipherSuite() { - return cipherSuite; - } + public CipherSuite getCipherSuite() { + return cipherSuite; + } - public int getSessionId() { - return sessionId; - } + public int getSessionId() { + return sessionId; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/sm/events/StateMachineEvent.java b/src/main/java/org/metricshub/ipmi/core/sm/events/StateMachineEvent.java index 0a90a44..17e5f25 100644 --- a/src/main/java/org/metricshub/ipmi/core/sm/events/StateMachineEvent.java +++ b/src/main/java/org/metricshub/ipmi/core/sm/events/StateMachineEvent.java @@ -27,5 +27,4 @@ /** * Abstract for an event of the {@link StateMachine}. */ -public abstract class StateMachineEvent { -} +public abstract class StateMachineEvent {} diff --git a/src/main/java/org/metricshub/ipmi/core/sm/package-info.java b/src/main/java/org/metricshub/ipmi/core/sm/package-info.java index b667a0f..ce65a6f 100644 --- a/src/main/java/org/metricshub/ipmi/core/sm/package-info.java +++ b/src/main/java/org/metricshub/ipmi/core/sm/package-info.java @@ -26,4 +26,4 @@ /** * IPMI Library for Java - */ \ No newline at end of file + */ diff --git a/src/main/java/org/metricshub/ipmi/core/sm/states/Authcap.java b/src/main/java/org/metricshub/ipmi/core/sm/states/Authcap.java index 4393bd6..56ab548 100644 --- a/src/main/java/org/metricshub/ipmi/core/sm/states/Authcap.java +++ b/src/main/java/org/metricshub/ipmi/core/sm/states/Authcap.java @@ -39,35 +39,47 @@ */ public class Authcap extends State { - @Override - public void doTransition(StateMachine stateMachine, - StateMachineEvent machineEvent) { - if (machineEvent instanceof Authorize) { - Authorize event = (Authorize) machineEvent; + @Override + public void doTransition( + StateMachine stateMachine, + StateMachineEvent machineEvent) { + if (machineEvent instanceof Authorize) { + Authorize event = (Authorize) machineEvent; - OpenSession openSession = new OpenSession(event.getSessionId(), - event.getPrivilegeLevel(), event.getCipherSuite()); + OpenSession openSession = new OpenSession( + event.getSessionId(), + event.getPrivilegeLevel(), + event.getCipherSuite()); - try { - stateMachine.setCurrent(new OpenSessionWaiting(event.getSequenceNumber())); - stateMachine.sendMessage(Encoder.encode( - new Protocolv20Encoder(), openSession, - event.getSequenceNumber(), 0, 0)); - } catch (Exception e) { - stateMachine.setCurrent(this); - stateMachine.doExternalAction(new ErrorAction(e)); - } - } else { - stateMachine.doExternalAction(new ErrorAction( - new IllegalArgumentException("Invalid transition: " - + machineEvent.getClass().getSimpleName()))); - } + try { + stateMachine.setCurrent(new OpenSessionWaiting(event.getSequenceNumber())); + stateMachine + .sendMessage( + Encoder + .encode( + new Protocolv20Encoder(), + openSession, + event.getSequenceNumber(), + 0, + 0)); + } catch (Exception e) { + stateMachine.setCurrent(this); + stateMachine.doExternalAction(new ErrorAction(e)); + } + } else { + stateMachine + .doExternalAction( + new ErrorAction( + new IllegalArgumentException( + "Invalid transition: " + + machineEvent.getClass().getSimpleName()))); + } - } + } - @Override - public void doAction(StateMachine stateMachine, RmcpMessage message) { - // No action needed - } + @Override + public void doAction(StateMachine stateMachine, RmcpMessage message) { + // No action needed + } } diff --git a/src/main/java/org/metricshub/ipmi/core/sm/states/AuthcapWaiting.java b/src/main/java/org/metricshub/ipmi/core/sm/states/AuthcapWaiting.java index a97aa5a..e7b21a6 100644 --- a/src/main/java/org/metricshub/ipmi/core/sm/states/AuthcapWaiting.java +++ b/src/main/java/org/metricshub/ipmi/core/sm/states/AuthcapWaiting.java @@ -39,54 +39,67 @@ /** * Waiting for the {@link GetChannelAuthenticationCapabilities} response.
- * - * Transition to:
  • {@link Ciphers} on {@link Timeout}
  • {@link Authcap} on - * {@link AuthenticationCapabilitiesReceived}
. + * Transition to: + *
    + *
  • {@link Ciphers} on {@link Timeout}
  • + *
  • {@link Authcap} on + * {@link AuthenticationCapabilitiesReceived}
  • + *
+ * . */ public class AuthcapWaiting extends State { - private int tag; + private int tag; - /** - * Instantiates a new {@link AuthcapWaiting} using the given tag - * @param tag int value representing the authentication capabilities - */ - public AuthcapWaiting(int tag) { - this.tag = tag; - } + /** + * Instantiates a new {@link AuthcapWaiting} using the given tag + * + * @param tag int value representing the authentication capabilities + */ + public AuthcapWaiting(int tag) { + this.tag = tag; + } - @Override - public void doTransition(StateMachine stateMachine, - StateMachineEvent machineEvent) { - if (machineEvent instanceof Timeout) { - stateMachine.setCurrent(new Ciphers()); - } else if (machineEvent instanceof AuthenticationCapabilitiesReceived) { - stateMachine.setCurrent(new Authcap()); - } else { - stateMachine.doExternalAction(new ErrorAction( - new IllegalArgumentException("Invalid transition"))); - } - } + @Override + public void doTransition( + StateMachine stateMachine, + StateMachineEvent machineEvent) { + if (machineEvent instanceof Timeout) { + stateMachine.setCurrent(new Ciphers()); + } else if (machineEvent instanceof AuthenticationCapabilitiesReceived) { + stateMachine.setCurrent(new Authcap()); + } else { + stateMachine + .doExternalAction( + new ErrorAction( + new IllegalArgumentException("Invalid transition"))); + } + } - @Override - public void doAction(StateMachine stateMachine, RmcpMessage message) { - if (ProtocolDecoder.decodeAuthenticationType(message) == AuthenticationType.RMCPPlus) { - return; // this isn't IPMI v1.5 message so we ignore it - } - Protocolv15Decoder decoder = new Protocolv15Decoder(); - IpmiMessage ipmiMessage = null; - try { - ipmiMessage = decoder.decode(message); - GetChannelAuthenticationCapabilities capabilities = new GetChannelAuthenticationCapabilities(); - if (capabilities.isCommandResponse(ipmiMessage) - && TypeConverter.byteToInt(((IpmiLanResponse) ipmiMessage - .getPayload()).getSequenceNumber()) == tag) { - stateMachine.doExternalAction(new ResponseAction(capabilities - .getResponseData(ipmiMessage))); - } - } catch (Exception e) { - stateMachine.doExternalAction(new ErrorAction(e)); - } - } + @Override + public void doAction(StateMachine stateMachine, RmcpMessage message) { + if (ProtocolDecoder.decodeAuthenticationType(message) == AuthenticationType.RMCPPlus) { + return; // this isn't IPMI v1.5 message so we ignore it + } + Protocolv15Decoder decoder = new Protocolv15Decoder(); + IpmiMessage ipmiMessage = null; + try { + ipmiMessage = decoder.decode(message); + GetChannelAuthenticationCapabilities capabilities = new GetChannelAuthenticationCapabilities(); + if (capabilities.isCommandResponse(ipmiMessage) + && TypeConverter + .byteToInt( + ((IpmiLanResponse) ipmiMessage + .getPayload()).getSequenceNumber()) == tag) { + stateMachine + .doExternalAction( + new ResponseAction( + capabilities + .getResponseData(ipmiMessage))); + } + } catch (Exception e) { + stateMachine.doExternalAction(new ErrorAction(e)); + } + } } diff --git a/src/main/java/org/metricshub/ipmi/core/sm/states/Ciphers.java b/src/main/java/org/metricshub/ipmi/core/sm/states/Ciphers.java index 21bae57..7959e45 100644 --- a/src/main/java/org/metricshub/ipmi/core/sm/states/Ciphers.java +++ b/src/main/java/org/metricshub/ipmi/core/sm/states/Ciphers.java @@ -41,31 +41,44 @@ */ public class Ciphers extends State { - @Override - public void doTransition(StateMachine stateMachine, - StateMachineEvent machineEvent) { - if (machineEvent instanceof Default) { - Default event = (Default) machineEvent; - GetChannelAuthenticationCapabilities authCap = new GetChannelAuthenticationCapabilities( - IpmiVersion.V15, IpmiVersion.V20, event.getCipherSuite(), - event.getPrivilegeLevel(), TypeConverter.intToByte(0xe)); - try { - stateMachine.setCurrent(new AuthcapWaiting(event.getSequenceNumber())); - stateMachine.sendMessage(Encoder.encode( - new Protocolv15Encoder(), authCap, event.getSequenceNumber(),0,0)); - } catch (Exception e) { - stateMachine.setCurrent(this); - stateMachine.doExternalAction(new ErrorAction(e)); - } - } else { - stateMachine.doExternalAction(new ErrorAction( - new IllegalArgumentException("Invalid transition"))); - } - } + @Override + public void doTransition( + StateMachine stateMachine, + StateMachineEvent machineEvent) { + if (machineEvent instanceof Default) { + Default event = (Default) machineEvent; + GetChannelAuthenticationCapabilities authCap = new GetChannelAuthenticationCapabilities( + IpmiVersion.V15, + IpmiVersion.V20, + event.getCipherSuite(), + event.getPrivilegeLevel(), + TypeConverter.intToByte(0xe)); + try { + stateMachine.setCurrent(new AuthcapWaiting(event.getSequenceNumber())); + stateMachine + .sendMessage( + Encoder + .encode( + new Protocolv15Encoder(), + authCap, + event.getSequenceNumber(), + 0, + 0)); + } catch (Exception e) { + stateMachine.setCurrent(this); + stateMachine.doExternalAction(new ErrorAction(e)); + } + } else { + stateMachine + .doExternalAction( + new ErrorAction( + new IllegalArgumentException("Invalid transition"))); + } + } - @Override - public void doAction(StateMachine stateMachine, RmcpMessage message) { - // No action is needed - } + @Override + public void doAction(StateMachine stateMachine, RmcpMessage message) { + // No action is needed + } } diff --git a/src/main/java/org/metricshub/ipmi/core/sm/states/CiphersWaiting.java b/src/main/java/org/metricshub/ipmi/core/sm/states/CiphersWaiting.java index 07e02af..7b62c17 100644 --- a/src/main/java/org/metricshub/ipmi/core/sm/states/CiphersWaiting.java +++ b/src/main/java/org/metricshub/ipmi/core/sm/states/CiphersWaiting.java @@ -50,79 +50,93 @@ */ public class CiphersWaiting extends State { - private int index; + private int index; - private int tag; + private int tag; - /** - * Initializes state. - * - * @param index - * - Index of the channel cipher suite package to get - * @param tag - * - Tag of the message - */ - public CiphersWaiting(int index, int tag) { - this.index = index; - this.tag = tag; - } + /** + * Initializes state. + * + * @param index + * - Index of the channel cipher suite package to get + * @param tag + * - Tag of the message + */ + public CiphersWaiting(int index, int tag) { + this.index = index; + this.tag = tag; + } - @Override - public void doTransition(StateMachine stateMachine, - StateMachineEvent machineEvent) { - if (machineEvent instanceof Timeout) { - stateMachine.setCurrent(new Uninitialized()); - } else if (machineEvent instanceof GetChannelCipherSuitesPending) { - GetChannelCipherSuitesPending event = (GetChannelCipherSuitesPending) machineEvent; - GetChannelCipherSuites cipherSuites = new GetChannelCipherSuites( - TypeConverter.intToByte(0xE), - TypeConverter.intToByte(index + 1)); - try { - tag = event.getSequenceNumber(); - stateMachine.sendMessage(Encoder.encode( - new Protocolv20Encoder(), cipherSuites, - event.getSequenceNumber(), 0, 0)); - ++index; - } catch (Exception e) { - stateMachine.doExternalAction(new ErrorAction(e)); - } - } else if (machineEvent instanceof DefaultAck) { - stateMachine.setCurrent(new Ciphers()); - } else { - stateMachine.doExternalAction(new ErrorAction( - new IllegalArgumentException("Invalid transition"))); - } - } + @Override + public void doTransition( + StateMachine stateMachine, + StateMachineEvent machineEvent) { + if (machineEvent instanceof Timeout) { + stateMachine.setCurrent(new Uninitialized()); + } else if (machineEvent instanceof GetChannelCipherSuitesPending) { + GetChannelCipherSuitesPending event = (GetChannelCipherSuitesPending) machineEvent; + GetChannelCipherSuites cipherSuites = new GetChannelCipherSuites( + TypeConverter.intToByte(0xE), + TypeConverter.intToByte(index + 1)); + try { + tag = event.getSequenceNumber(); + stateMachine + .sendMessage( + Encoder + .encode( + new Protocolv20Encoder(), + cipherSuites, + event.getSequenceNumber(), + 0, + 0)); + ++index; + } catch (Exception e) { + stateMachine.doExternalAction(new ErrorAction(e)); + } + } else if (machineEvent instanceof DefaultAck) { + stateMachine.setCurrent(new Ciphers()); + } else { + stateMachine + .doExternalAction( + new ErrorAction( + new IllegalArgumentException("Invalid transition"))); + } + } - @Override - public void doAction(StateMachine stateMachine, RmcpMessage message) { - if(ProtocolDecoder.decodeAuthenticationType(message) != AuthenticationType.RMCPPlus) { - return; //this isn't IPMI v2.0 message so we ignore it - } - if(Protocolv20Decoder.decodeSessionID(message) != 0){ - return; //this isn't sessionless message so we drop it - } - if (Protocolv20Decoder.decodePayloadType(message.getData()[1]) != PayloadType.Ipmi) { - return; - } - Protocolv20Decoder decoder = new Protocolv20Decoder( - CipherSuite.getEmpty()); - if(decoder.decodeAuthentication(message.getData()[1])) { - return; //message is authenticated so it does belong to the other session - } - IpmiMessage ipmiMessage = null; - try { - ipmiMessage = decoder.decode(message); - GetChannelCipherSuites suites = new GetChannelCipherSuites(); - if (suites.isCommandResponse(ipmiMessage) - && TypeConverter.byteToInt(((IpmiLanResponse) ipmiMessage - .getPayload()).getSequenceNumber()) == tag) { - stateMachine.doExternalAction(new ResponseAction(suites - .getResponseData(ipmiMessage))); - } - } catch (Exception e) { - stateMachine.doExternalAction(new ErrorAction(e)); - } - } + @Override + public void doAction(StateMachine stateMachine, RmcpMessage message) { + if (ProtocolDecoder.decodeAuthenticationType(message) != AuthenticationType.RMCPPlus) { + return; // this isn't IPMI v2.0 message so we ignore it + } + if (Protocolv20Decoder.decodeSessionID(message) != 0) { + return; // this isn't sessionless message so we drop it + } + if (Protocolv20Decoder.decodePayloadType(message.getData()[1]) != PayloadType.Ipmi) { + return; + } + Protocolv20Decoder decoder = new Protocolv20Decoder( + CipherSuite.getEmpty()); + if (decoder.decodeAuthentication(message.getData()[1])) { + return; // message is authenticated so it does belong to the other session + } + IpmiMessage ipmiMessage = null; + try { + ipmiMessage = decoder.decode(message); + GetChannelCipherSuites suites = new GetChannelCipherSuites(); + if (suites.isCommandResponse(ipmiMessage) + && TypeConverter + .byteToInt( + ((IpmiLanResponse) ipmiMessage + .getPayload()).getSequenceNumber()) == tag) { + stateMachine + .doExternalAction( + new ResponseAction( + suites + .getResponseData(ipmiMessage))); + } + } catch (Exception e) { + stateMachine.doExternalAction(new ErrorAction(e)); + } + } } diff --git a/src/main/java/org/metricshub/ipmi/core/sm/states/OpenSessionComplete.java b/src/main/java/org/metricshub/ipmi/core/sm/states/OpenSessionComplete.java index dae1510..9a1a9a9 100644 --- a/src/main/java/org/metricshub/ipmi/core/sm/states/OpenSessionComplete.java +++ b/src/main/java/org/metricshub/ipmi/core/sm/states/OpenSessionComplete.java @@ -38,36 +38,48 @@ */ public class OpenSessionComplete extends State { - @Override - public void doTransition(StateMachine stateMachine, - StateMachineEvent machineEvent) { - if (machineEvent instanceof OpenSessionAck) { - OpenSessionAck event = (OpenSessionAck) machineEvent; + @Override + public void doTransition( + StateMachine stateMachine, + StateMachineEvent machineEvent) { + if (machineEvent instanceof OpenSessionAck) { + OpenSessionAck event = (OpenSessionAck) machineEvent; - Rakp1 rakp1 = new Rakp1(event.getManagedSystemSessionId(), - event.getPrivilegeLevel(), event.getUsername(), - event.getPassword(), event.getBmcKey(), - event.getCipherSuite()); + Rakp1 rakp1 = new Rakp1( + event.getManagedSystemSessionId(), + event.getPrivilegeLevel(), + event.getUsername(), + event.getPassword(), + event.getBmcKey(), + event.getCipherSuite()); - try { - stateMachine.setCurrent(new Rakp1Waiting(event.getSequenceNumber(), rakp1)); - stateMachine.sendMessage(Encoder.encode( - new Protocolv20Encoder(), rakp1, - event.getSequenceNumber(), 0, 0)); - } catch (Exception e) { - stateMachine.setCurrent(this); - stateMachine.doExternalAction(new ErrorAction(e)); - } - } else { - stateMachine.doExternalAction(new ErrorAction( - new IllegalArgumentException("Invalid transition"))); - } + try { + stateMachine.setCurrent(new Rakp1Waiting(event.getSequenceNumber(), rakp1)); + stateMachine + .sendMessage( + Encoder + .encode( + new Protocolv20Encoder(), + rakp1, + event.getSequenceNumber(), + 0, + 0)); + } catch (Exception e) { + stateMachine.setCurrent(this); + stateMachine.doExternalAction(new ErrorAction(e)); + } + } else { + stateMachine + .doExternalAction( + new ErrorAction( + new IllegalArgumentException("Invalid transition"))); + } - } + } - @Override - public void doAction(StateMachine stateMachine, RmcpMessage message) { - // No action is needed - } + @Override + public void doAction(StateMachine stateMachine, RmcpMessage message) { + // No action is needed + } } diff --git a/src/main/java/org/metricshub/ipmi/core/sm/states/OpenSessionWaiting.java b/src/main/java/org/metricshub/ipmi/core/sm/states/OpenSessionWaiting.java index a43bb4e..1fe6763 100644 --- a/src/main/java/org/metricshub/ipmi/core/sm/states/OpenSessionWaiting.java +++ b/src/main/java/org/metricshub/ipmi/core/sm/states/OpenSessionWaiting.java @@ -44,52 +44,60 @@ * Waiting for the {@link OpenSession} response.
*
    *
  • Transition to {@link OpenSessionComplete} on {@link DefaultAck}
  • - *
  • Transition to {@link Authcap} on {@link Timeout}
  • + *
  • Transition to {@link Authcap} on {@link Timeout}
  • *
*/ public class OpenSessionWaiting extends State { - private int tag; + private int tag; - public OpenSessionWaiting(int tag) { - this.tag = tag; - } + public OpenSessionWaiting(int tag) { + this.tag = tag; + } - @Override - public void doTransition(StateMachine stateMachine, - StateMachineEvent machineEvent) { - if (machineEvent instanceof DefaultAck) { - stateMachine.setCurrent(new OpenSessionComplete()); - } else if (machineEvent instanceof Timeout) { - stateMachine.setCurrent(new Authcap()); - } else { - stateMachine.doExternalAction(new ErrorAction( - new IllegalArgumentException("Invalid transition"))); - } - } + @Override + public void doTransition( + StateMachine stateMachine, + StateMachineEvent machineEvent) { + if (machineEvent instanceof DefaultAck) { + stateMachine.setCurrent(new OpenSessionComplete()); + } else if (machineEvent instanceof Timeout) { + stateMachine.setCurrent(new Authcap()); + } else { + stateMachine + .doExternalAction( + new ErrorAction( + new IllegalArgumentException("Invalid transition"))); + } + } - @Override - public void doAction(StateMachine stateMachine, RmcpMessage message) { - if (ProtocolDecoder.decodeAuthenticationType(message) != AuthenticationType.RMCPPlus) { - return; // this isn't IPMI v2.0 message so we ignore it - } - PlainCommandv20Decoder decoder = new PlainCommandv20Decoder( - CipherSuite.getEmpty()); - if (Protocolv20Decoder.decodePayloadType(message.getData()[1]) != PayloadType.RmcpOpenSessionResponse) { - return; - } - IpmiMessage ipmiMessage = null; - try { - ipmiMessage = decoder.decode(message); - OpenSession openSession = new OpenSession(CipherSuite.getEmpty()); - if (openSession.isCommandResponse(ipmiMessage) - && TypeConverter.byteToInt(((PlainMessage) ipmiMessage - .getPayload()).getPayloadData()[0]) == tag) { - stateMachine.doExternalAction(new ResponseAction(openSession - .getResponseData(ipmiMessage))); - } - } catch (Exception e) { - stateMachine.doExternalAction(new ErrorAction(e)); - } - } + @Override + public void doAction(StateMachine stateMachine, RmcpMessage message) { + if (ProtocolDecoder.decodeAuthenticationType(message) != AuthenticationType.RMCPPlus) { + return; // this isn't IPMI v2.0 message so we ignore it + } + PlainCommandv20Decoder decoder = new PlainCommandv20Decoder( + CipherSuite.getEmpty()); + if (Protocolv20Decoder.decodePayloadType(message.getData()[1]) != PayloadType.RmcpOpenSessionResponse) { + return; + } + IpmiMessage ipmiMessage = null; + try { + ipmiMessage = decoder.decode(message); + OpenSession openSession = new OpenSession(CipherSuite.getEmpty()); + if (openSession.isCommandResponse(ipmiMessage) + && TypeConverter + .byteToInt( + ((PlainMessage) ipmiMessage + .getPayload()).getPayloadData()[0]) == tag) { + stateMachine + .doExternalAction( + new ResponseAction( + openSession + .getResponseData(ipmiMessage))); + } + } catch (Exception e) { + stateMachine.doExternalAction(new ErrorAction(e)); + } + } } diff --git a/src/main/java/org/metricshub/ipmi/core/sm/states/Rakp1Complete.java b/src/main/java/org/metricshub/ipmi/core/sm/states/Rakp1Complete.java index 2d137d2..25a0f80 100644 --- a/src/main/java/org/metricshub/ipmi/core/sm/states/Rakp1Complete.java +++ b/src/main/java/org/metricshub/ipmi/core/sm/states/Rakp1Complete.java @@ -39,52 +39,73 @@ */ public class Rakp1Complete extends State { - private Rakp1 rakp1; + private Rakp1 rakp1; - /** - * Initiates state. - * - * @param rakp1 - * - the {@link Rakp1} message that was sent earlier in the - * authentification process. - */ - public Rakp1Complete(Rakp1 rakp1) { - this.rakp1 = rakp1; - } + /** + * Initiates state. + * + * @param rakp1 + * - the {@link Rakp1} message that was sent earlier in the + * authentification process. + */ + public Rakp1Complete(Rakp1 rakp1) { + this.rakp1 = rakp1; + } - @Override - public void doTransition(StateMachine stateMachine, - StateMachineEvent machineEvent) { - if (machineEvent instanceof Rakp2Ack) { - Rakp2Ack event = (Rakp2Ack) machineEvent; + @Override + public void doTransition( + StateMachine stateMachine, + StateMachineEvent machineEvent) { + if (machineEvent instanceof Rakp2Ack) { + Rakp2Ack event = (Rakp2Ack) machineEvent; - Rakp3 rakp3 = new Rakp3(event.getStatusCode(), - event.getManagedSystemSessionId(), event.getCipherSuite(), - rakp1, event.getRakp1ResponseData()); + Rakp3 rakp3 = new Rakp3( + event.getStatusCode(), + event.getManagedSystemSessionId(), + event.getCipherSuite(), + rakp1, + event.getRakp1ResponseData()); - try { - stateMachine.setCurrent(new Rakp3Waiting(event - .getSequenceNumber(), rakp1, event - .getRakp1ResponseData(), event.getCipherSuite())); - stateMachine.sendMessage(Encoder.encode( - new Protocolv20Encoder(), rakp3, - event.getSequenceNumber(), 0, 0)); - stateMachine.doExternalAction(new GetSikAction(rakp1 - .calculateSik(event.getRakp1ResponseData()))); - } catch (Exception e) { - stateMachine.setCurrent(this); - stateMachine.doExternalAction(new ErrorAction(e)); - } - } else { - stateMachine.doExternalAction(new ErrorAction( - new IllegalArgumentException("Invalid transition"))); - } + try { + stateMachine + .setCurrent( + new Rakp3Waiting( + event + .getSequenceNumber(), + rakp1, + event + .getRakp1ResponseData(), + event.getCipherSuite())); + stateMachine + .sendMessage( + Encoder + .encode( + new Protocolv20Encoder(), + rakp3, + event.getSequenceNumber(), + 0, + 0)); + stateMachine + .doExternalAction( + new GetSikAction( + rakp1 + .calculateSik(event.getRakp1ResponseData()))); + } catch (Exception e) { + stateMachine.setCurrent(this); + stateMachine.doExternalAction(new ErrorAction(e)); + } + } else { + stateMachine + .doExternalAction( + new ErrorAction( + new IllegalArgumentException("Invalid transition"))); + } - } + } - @Override - public void doAction(StateMachine stateMachine, RmcpMessage message) { - // No action is needed - } + @Override + public void doAction(StateMachine stateMachine, RmcpMessage message) { + // No action is needed + } } diff --git a/src/main/java/org/metricshub/ipmi/core/sm/states/Rakp1Waiting.java b/src/main/java/org/metricshub/ipmi/core/sm/states/Rakp1Waiting.java index 657f517..cedd152 100644 --- a/src/main/java/org/metricshub/ipmi/core/sm/states/Rakp1Waiting.java +++ b/src/main/java/org/metricshub/ipmi/core/sm/states/Rakp1Waiting.java @@ -41,65 +41,73 @@ import org.metricshub.ipmi.core.sm.events.Timeout; /** - * Waiting for RAKP Message 2. Transition to: + * Waiting for RAKP Message 2. Transition to: *
    - *
  • {@link Rakp1Complete} on {@link DefaultAck}
  • - *
  • {@link Authcap} on {@link Timeout}
  • + *
  • {@link Rakp1Complete} on {@link DefaultAck}
  • + *
  • {@link Authcap} on {@link Timeout}
  • *
*/ public class Rakp1Waiting extends State { - private Rakp1 rakp1; + private Rakp1 rakp1; - private int tag; + private int tag; - /** - * Initiates state. - * - * @param rakp1 - * - the {@link Rakp1} message that was sent earlier in the - * authentification process. - */ - public Rakp1Waiting(int tag, Rakp1 rakp1) { - this.tag = tag; - this.rakp1 = rakp1; - } + /** + * Initiates state. + * + * @param rakp1 + * - the {@link Rakp1} message that was sent earlier in the + * authentification process. + */ + public Rakp1Waiting(int tag, Rakp1 rakp1) { + this.tag = tag; + this.rakp1 = rakp1; + } - @Override - public void doTransition(StateMachine stateMachine, - StateMachineEvent machineEvent) { - if (machineEvent instanceof DefaultAck) { - stateMachine.setCurrent(new Rakp1Complete(rakp1)); - } else if (machineEvent instanceof Timeout) { - stateMachine.setCurrent(new Authcap()); - } else { - stateMachine.doExternalAction(new ErrorAction( - new IllegalArgumentException("Invalid transition"))); - } + @Override + public void doTransition( + StateMachine stateMachine, + StateMachineEvent machineEvent) { + if (machineEvent instanceof DefaultAck) { + stateMachine.setCurrent(new Rakp1Complete(rakp1)); + } else if (machineEvent instanceof Timeout) { + stateMachine.setCurrent(new Authcap()); + } else { + stateMachine + .doExternalAction( + new ErrorAction( + new IllegalArgumentException("Invalid transition"))); + } - } + } - @Override - public void doAction(StateMachine stateMachine, RmcpMessage message) { - if (ProtocolDecoder.decodeAuthenticationType(message) != AuthenticationType.RMCPPlus) { - return; // this isn't IPMI v2.0 message so we ignore it - } - PlainCommandv20Decoder decoder = new PlainCommandv20Decoder( - CipherSuite.getEmpty()); - if (Protocolv20Decoder.decodePayloadType(message.getData()[1]) != PayloadType.Rakp2) { - return; - } - IpmiMessage ipmiMessage = null; - try { - ipmiMessage = decoder.decode(message); - if (rakp1.isCommandResponse(ipmiMessage) - && TypeConverter.byteToInt(((PlainMessage) ipmiMessage - .getPayload()).getPayloadData()[0]) == tag) { - stateMachine.doExternalAction(new ResponseAction(rakp1 - .getResponseData(ipmiMessage))); - } - } catch (Exception e) { - stateMachine.doExternalAction(new ErrorAction(e)); - } - } + @Override + public void doAction(StateMachine stateMachine, RmcpMessage message) { + if (ProtocolDecoder.decodeAuthenticationType(message) != AuthenticationType.RMCPPlus) { + return; // this isn't IPMI v2.0 message so we ignore it + } + PlainCommandv20Decoder decoder = new PlainCommandv20Decoder( + CipherSuite.getEmpty()); + if (Protocolv20Decoder.decodePayloadType(message.getData()[1]) != PayloadType.Rakp2) { + return; + } + IpmiMessage ipmiMessage = null; + try { + ipmiMessage = decoder.decode(message); + if (rakp1.isCommandResponse(ipmiMessage) + && TypeConverter + .byteToInt( + ((PlainMessage) ipmiMessage + .getPayload()).getPayloadData()[0]) == tag) { + stateMachine + .doExternalAction( + new ResponseAction( + rakp1 + .getResponseData(ipmiMessage))); + } + } catch (Exception e) { + stateMachine.doExternalAction(new ErrorAction(e)); + } + } } diff --git a/src/main/java/org/metricshub/ipmi/core/sm/states/Rakp3Complete.java b/src/main/java/org/metricshub/ipmi/core/sm/states/Rakp3Complete.java index c5a6445..4ee782b 100644 --- a/src/main/java/org/metricshub/ipmi/core/sm/states/Rakp3Complete.java +++ b/src/main/java/org/metricshub/ipmi/core/sm/states/Rakp3Complete.java @@ -36,23 +36,29 @@ */ public class Rakp3Complete extends State { - @Override - public void doTransition(StateMachine stateMachine, - StateMachineEvent machineEvent) { - if (machineEvent instanceof StartSession) { - StartSession event = (StartSession) machineEvent; - stateMachine.setCurrent(new SessionValid( - event.getCipherSuite(), event.getSessionId())); + @Override + public void doTransition( + StateMachine stateMachine, + StateMachineEvent machineEvent) { + if (machineEvent instanceof StartSession) { + StartSession event = (StartSession) machineEvent; + stateMachine + .setCurrent( + new SessionValid( + event.getCipherSuite(), + event.getSessionId())); - } else { - stateMachine.doExternalAction(new ErrorAction( - new IllegalArgumentException("Invalid transition"))); - } - } + } else { + stateMachine + .doExternalAction( + new ErrorAction( + new IllegalArgumentException("Invalid transition"))); + } + } - @Override - public void doAction(StateMachine stateMachine, RmcpMessage message) { - // No action is needed - } + @Override + public void doAction(StateMachine stateMachine, RmcpMessage message) { + // No action is needed + } } diff --git a/src/main/java/org/metricshub/ipmi/core/sm/states/Rakp3Waiting.java b/src/main/java/org/metricshub/ipmi/core/sm/states/Rakp3Waiting.java index 4ebef78..c5f2c8e 100644 --- a/src/main/java/org/metricshub/ipmi/core/sm/states/Rakp3Waiting.java +++ b/src/main/java/org/metricshub/ipmi/core/sm/states/Rakp3Waiting.java @@ -53,68 +53,76 @@ */ public class Rakp3Waiting extends State { - private Rakp1 rakp1; - private Rakp1ResponseData rakp1ResponseData; - private CipherSuite cipherSuite; - private int tag; + private Rakp1 rakp1; + private Rakp1ResponseData rakp1ResponseData; + private CipherSuite cipherSuite; + private int tag; - /** - * Initiates state. - * - * @param rakp1 - * - the {@link Rakp1} message that was sent earlier in the - * authentification process. - * @param rakp1ResponseData - * - the {@link Rakp1ResponseData} that was received earlier in - * the authentification process. - * @param cipherSuite - * - the {@link CipherSuite} used during this session. - */ - public Rakp3Waiting(int tag, Rakp1 rakp1, - Rakp1ResponseData rakp1ResponseData, CipherSuite cipherSuite) { - this.rakp1 = rakp1; - this.rakp1ResponseData = rakp1ResponseData; - this.cipherSuite = cipherSuite; - this.tag = tag; - } + /** + * Initiates state. + * + * @param rakp1 + * - the {@link Rakp1} message that was sent earlier in the + * authentification process. + * @param rakp1ResponseData + * - the {@link Rakp1ResponseData} that was received earlier in + * the authentification process. + * @param cipherSuite + * - the {@link CipherSuite} used during this session. + */ + public Rakp3Waiting(int tag, Rakp1 rakp1, + Rakp1ResponseData rakp1ResponseData, CipherSuite cipherSuite) { + this.rakp1 = rakp1; + this.rakp1ResponseData = rakp1ResponseData; + this.cipherSuite = cipherSuite; + this.tag = tag; + } - @Override - public void doTransition(StateMachine stateMachine, - StateMachineEvent machineEvent) { - if (machineEvent instanceof DefaultAck) { - stateMachine.setCurrent(new Rakp3Complete()); - } else if (machineEvent instanceof Timeout) { - stateMachine.setCurrent(new Authcap()); - } else { - stateMachine.doExternalAction(new ErrorAction( - new IllegalArgumentException("Invalid transition"))); - } - } + @Override + public void doTransition( + StateMachine stateMachine, + StateMachineEvent machineEvent) { + if (machineEvent instanceof DefaultAck) { + stateMachine.setCurrent(new Rakp3Complete()); + } else if (machineEvent instanceof Timeout) { + stateMachine.setCurrent(new Authcap()); + } else { + stateMachine + .doExternalAction( + new ErrorAction( + new IllegalArgumentException("Invalid transition"))); + } + } - @Override - public void doAction(StateMachine stateMachine, RmcpMessage message) { - if (ProtocolDecoder.decodeAuthenticationType(message) != AuthenticationType.RMCPPlus) { - return; // this isn't IPMI v2.0 message so we ignore it - } - PlainCommandv20Decoder decoder = new PlainCommandv20Decoder( - CipherSuite.getEmpty()); - if (Protocolv20Decoder.decodePayloadType(message.getData()[1]) != PayloadType.Rakp4) { - return; - } + @Override + public void doAction(StateMachine stateMachine, RmcpMessage message) { + if (ProtocolDecoder.decodeAuthenticationType(message) != AuthenticationType.RMCPPlus) { + return; // this isn't IPMI v2.0 message so we ignore it + } + PlainCommandv20Decoder decoder = new PlainCommandv20Decoder( + CipherSuite.getEmpty()); + if (Protocolv20Decoder.decodePayloadType(message.getData()[1]) != PayloadType.Rakp4) { + return; + } - IpmiMessage ipmiMessage = null; - Rakp3 rakp3 = new Rakp3(cipherSuite, rakp1, rakp1ResponseData); - try { - ipmiMessage = decoder.decode(message); - if (rakp3.isCommandResponse(ipmiMessage) - && TypeConverter.byteToInt(((PlainMessage) ipmiMessage - .getPayload()).getPayloadData()[0]) == tag) { - stateMachine.doExternalAction(new ResponseAction(rakp3 - .getResponseData(ipmiMessage))); - } - } catch (Exception e) { - stateMachine.doExternalAction(new ErrorAction(e)); - } - } + IpmiMessage ipmiMessage = null; + Rakp3 rakp3 = new Rakp3(cipherSuite, rakp1, rakp1ResponseData); + try { + ipmiMessage = decoder.decode(message); + if (rakp3.isCommandResponse(ipmiMessage) + && TypeConverter + .byteToInt( + ((PlainMessage) ipmiMessage + .getPayload()).getPayloadData()[0]) == tag) { + stateMachine + .doExternalAction( + new ResponseAction( + rakp3 + .getResponseData(ipmiMessage))); + } + } catch (Exception e) { + stateMachine.doExternalAction(new ErrorAction(e)); + } + } } diff --git a/src/main/java/org/metricshub/ipmi/core/sm/states/SessionValid.java b/src/main/java/org/metricshub/ipmi/core/sm/states/SessionValid.java index b804748..e8ab711 100644 --- a/src/main/java/org/metricshub/ipmi/core/sm/states/SessionValid.java +++ b/src/main/java/org/metricshub/ipmi/core/sm/states/SessionValid.java @@ -46,107 +46,135 @@ /** * {@link State} in which the session is valid and sending IPMI commands to the - * remote machine is enabled. + * remote machine is enabled. *
    *
  • Sends an IPMI v2.0 message on - * {@link Sendv20Message}
  • Sends {@link GetChannelAuthenticationCapabilities} + * {@link Sendv20Message} + *
  • Sends {@link GetChannelAuthenticationCapabilities} * message to keep the session form timing out on {@link SessionUpkeep}
  • - *
  • Transits to {@link Authcap} on {@link Timeout}
  • Sends {@link CloseSession} + *
  • Transits to {@link Authcap} on {@link Timeout} + *
  • Sends {@link CloseSession} * and transits to {@link Authcap} on {@link org.metricshub.ipmi.core.coding.commands.session.CloseSession}
  • *
*/ public class SessionValid extends State { - private CipherSuite cipherSuite; + private CipherSuite cipherSuite; - private int sessionId; + private int sessionId; - public CipherSuite getCipherSuite() { - return cipherSuite; - } + public CipherSuite getCipherSuite() { + return cipherSuite; + } - /** - * Initiates the state. - * - * @param cipherSuite - * - {@link CipherSuite} used during the session. - */ - public SessionValid(CipherSuite cipherSuite, int sessionId) { - this.cipherSuite = cipherSuite; - this.sessionId = sessionId; - } + /** + * Initiates the state. + * + * @param cipherSuite + * - {@link CipherSuite} used during the session. + */ + public SessionValid(CipherSuite cipherSuite, int sessionId) { + this.cipherSuite = cipherSuite; + this.sessionId = sessionId; + } - @Override - public void doTransition(StateMachine stateMachine, - StateMachineEvent machineEvent) { - if (machineEvent instanceof Sendv20Message) { - Sendv20Message event = (Sendv20Message) machineEvent; - try { - stateMachine.sendMessage(Encoder.encode( - new Protocolv20Encoder(), event.getPayloadCoder(), event.getMessageSequenceNumber(), - event.getSessionSequenceNumber(), event.getSessionId())); - } catch (Exception e) { - stateMachine.doExternalAction(new ErrorAction(e)); - } - } else if (machineEvent instanceof SessionUpkeep) { - SessionUpkeep event = (SessionUpkeep) machineEvent; - try { - stateMachine.sendMessage(Encoder.encode( - new Protocolv20Encoder(), - new GetChannelAuthenticationCapabilities( - IpmiVersion.V20, IpmiVersion.V20, cipherSuite, - PrivilegeLevel.Callback, TypeConverter.intToByte(0xe)), - event.getMessageSequenceNumber(), event.getSessionSequenceNumber(), event.getSessionId())); - } catch (Exception e) { - stateMachine.doExternalAction(new ErrorAction(e)); - } - } else if (machineEvent instanceof Timeout) { - stateMachine.setCurrent(new Authcap()); - } else if (machineEvent instanceof org.metricshub.ipmi.core.sm.events.CloseSession) { - org.metricshub.ipmi.core.sm.events.CloseSession event = (org.metricshub.ipmi.core.sm.events.CloseSession) machineEvent; + @Override + public void doTransition( + StateMachine stateMachine, + StateMachineEvent machineEvent) { + if (machineEvent instanceof Sendv20Message) { + Sendv20Message event = (Sendv20Message) machineEvent; + try { + stateMachine + .sendMessage( + Encoder + .encode( + new Protocolv20Encoder(), + event.getPayloadCoder(), + event.getMessageSequenceNumber(), + event.getSessionSequenceNumber(), + event.getSessionId())); + } catch (Exception e) { + stateMachine.doExternalAction(new ErrorAction(e)); + } + } else if (machineEvent instanceof SessionUpkeep) { + SessionUpkeep event = (SessionUpkeep) machineEvent; + try { + stateMachine + .sendMessage( + Encoder + .encode( + new Protocolv20Encoder(), + new GetChannelAuthenticationCapabilities( + IpmiVersion.V20, + IpmiVersion.V20, + cipherSuite, + PrivilegeLevel.Callback, + TypeConverter.intToByte(0xe)), + event.getMessageSequenceNumber(), + event.getSessionSequenceNumber(), + event.getSessionId())); + } catch (Exception e) { + stateMachine.doExternalAction(new ErrorAction(e)); + } + } else if (machineEvent instanceof Timeout) { + stateMachine.setCurrent(new Authcap()); + } else if (machineEvent instanceof org.metricshub.ipmi.core.sm.events.CloseSession) { + org.metricshub.ipmi.core.sm.events.CloseSession event = (org.metricshub.ipmi.core.sm.events.CloseSession) machineEvent; - try { - stateMachine.setCurrent(new Authcap()); - stateMachine.sendMessage(Encoder.encode( - new Protocolv20Encoder(), - new CloseSession(IpmiVersion.V20, cipherSuite, AuthenticationType.RMCPPlus, event.getSessionId()), - event.getMessageSequenceNumber(), event.getSessionSequenceNumber(), event.getSessionId())); - } catch (Exception e) { - stateMachine.setCurrent(this); - stateMachine.doExternalAction(new ErrorAction(e)); - } - } else { - stateMachine.doExternalAction(new ErrorAction( - new IllegalArgumentException("Invalid transition"))); - } + try { + stateMachine.setCurrent(new Authcap()); + stateMachine + .sendMessage( + Encoder + .encode( + new Protocolv20Encoder(), + new CloseSession( + IpmiVersion.V20, + cipherSuite, + AuthenticationType.RMCPPlus, + event.getSessionId()), + event.getMessageSequenceNumber(), + event.getSessionSequenceNumber(), + event.getSessionId())); + } catch (Exception e) { + stateMachine.setCurrent(this); + stateMachine.doExternalAction(new ErrorAction(e)); + } + } else { + stateMachine + .doExternalAction( + new ErrorAction( + new IllegalArgumentException("Invalid transition"))); + } - } + } - @Override - public void doAction(StateMachine stateMachine, RmcpMessage message) { - if (ProtocolDecoder.decodeAuthenticationType(message) != AuthenticationType.RMCPPlus) { - return; // this isn't IPMI v2.0 message so we ignore it - } - if (Protocolv20Decoder.decodeSessionID(message) == 0) { - return; // this is a sessionless message so we drop it - } - Protocolv20Decoder decoder = new Protocolv20Decoder(cipherSuite); - PayloadType payloadType = Protocolv20Decoder.decodePayloadType(message.getData()[1]); + @Override + public void doAction(StateMachine stateMachine, RmcpMessage message) { + if (ProtocolDecoder.decodeAuthenticationType(message) != AuthenticationType.RMCPPlus) { + return; // this isn't IPMI v2.0 message so we ignore it + } + if (Protocolv20Decoder.decodeSessionID(message) == 0) { + return; // this is a sessionless message so we drop it + } + Protocolv20Decoder decoder = new Protocolv20Decoder(cipherSuite); + PayloadType payloadType = Protocolv20Decoder.decodePayloadType(message.getData()[1]); - if (payloadType != PayloadType.Ipmi && payloadType != PayloadType.Sol) { - return; - } - if (Protocolv20Decoder.decodeSessionID(message) != sessionId) { - return; // this message belongs to other session so we ignore it - } - try { - Ipmiv20Message message20 = (Ipmiv20Message) decoder.decode(message); - if (message20.getSessionID() == sessionId) { - stateMachine.doExternalAction(new MessageAction(message20)); - } - } catch (Exception e) { - stateMachine.doExternalAction(new ErrorAction(e)); - } - } + if (payloadType != PayloadType.Ipmi && payloadType != PayloadType.Sol) { + return; + } + if (Protocolv20Decoder.decodeSessionID(message) != sessionId) { + return; // this message belongs to other session so we ignore it + } + try { + Ipmiv20Message message20 = (Ipmiv20Message) decoder.decode(message); + if (message20.getSessionID() == sessionId) { + stateMachine.doExternalAction(new MessageAction(message20)); + } + } catch (Exception e) { + stateMachine.doExternalAction(new ErrorAction(e)); + } + } } diff --git a/src/main/java/org/metricshub/ipmi/core/sm/states/State.java b/src/main/java/org/metricshub/ipmi/core/sm/states/State.java index f5fe3ab..774b20b 100644 --- a/src/main/java/org/metricshub/ipmi/core/sm/states/State.java +++ b/src/main/java/org/metricshub/ipmi/core/sm/states/State.java @@ -30,35 +30,35 @@ * The abstract for state of the {@link StateMachine}. */ public abstract class State { - /** - * Defines the action performed when the state is entered. - * - * @param stateMachine - * - the context - */ - public void onEnter(StateMachine stateMachine) { - } + /** + * Defines the action performed when the state is entered. + * + * @param stateMachine + * - the context + */ + public void onEnter(StateMachine stateMachine) {} - /** - * Performs the state transition - * - * @param stateMachine - * - the context - * @param machineEvent - * - the {@link StateMachineEvent} that was the cause of the - * transition - */ - public abstract void doTransition(StateMachine stateMachine, - StateMachineEvent machineEvent); + /** + * Performs the state transition + * + * @param stateMachine + * - the context + * @param machineEvent + * - the {@link StateMachineEvent} that was the cause of the + * transition + */ + public abstract void doTransition( + StateMachine stateMachine, + StateMachineEvent machineEvent); - /** - * Defines the action that should be performed when a response form the - * remote system arrives in the current state. - * - * @param stateMachine - * - the context - * @param message - * - the message that appeared - */ - public abstract void doAction(StateMachine stateMachine, RmcpMessage message); + /** + * Defines the action that should be performed when a response form the + * remote system arrives in the current state. + * + * @param stateMachine + * - the context + * @param message + * - the message that appeared + */ + public abstract void doAction(StateMachine stateMachine, RmcpMessage message); } diff --git a/src/main/java/org/metricshub/ipmi/core/sm/states/Uninitialized.java b/src/main/java/org/metricshub/ipmi/core/sm/states/Uninitialized.java index 822b88e..0415d89 100644 --- a/src/main/java/org/metricshub/ipmi/core/sm/states/Uninitialized.java +++ b/src/main/java/org/metricshub/ipmi/core/sm/states/Uninitialized.java @@ -39,33 +39,47 @@ */ public class Uninitialized extends State { - @Override - public void doTransition(StateMachine stateMachine, - StateMachineEvent machineEvent) { - if (machineEvent instanceof GetChannelCipherSuitesPending) { - Default event = (GetChannelCipherSuitesPending) machineEvent; - GetChannelCipherSuites cipherSuites = new GetChannelCipherSuites( - TypeConverter.intToByte(0xE), (byte) 0); - try { - stateMachine.setCurrent(new CiphersWaiting(0, event - .getSequenceNumber())); + @Override + public void doTransition( + StateMachine stateMachine, + StateMachineEvent machineEvent) { + if (machineEvent instanceof GetChannelCipherSuitesPending) { + Default event = (GetChannelCipherSuitesPending) machineEvent; + GetChannelCipherSuites cipherSuites = new GetChannelCipherSuites( + TypeConverter.intToByte(0xE), + (byte) 0); + try { + stateMachine + .setCurrent( + new CiphersWaiting( + 0, + event + .getSequenceNumber())); - stateMachine.sendMessage(Encoder.encode( - new Protocolv20Encoder(), cipherSuites, - event.getSequenceNumber(), 0,0)); - } catch (Exception e) { - stateMachine.setCurrent(this); - stateMachine.doExternalAction(new ErrorAction(e)); - } - } else { - stateMachine.doExternalAction(new ErrorAction( - new IllegalArgumentException("Invalid transition"))); - } - } + stateMachine + .sendMessage( + Encoder + .encode( + new Protocolv20Encoder(), + cipherSuites, + event.getSequenceNumber(), + 0, + 0)); + } catch (Exception e) { + stateMachine.setCurrent(this); + stateMachine.doExternalAction(new ErrorAction(e)); + } + } else { + stateMachine + .doExternalAction( + new ErrorAction( + new IllegalArgumentException("Invalid transition"))); + } + } - @Override - public void doAction(StateMachine stateMachine, RmcpMessage message) { - // No action is needed - } + @Override + public void doAction(StateMachine stateMachine, RmcpMessage message) { + // No action is needed + } } diff --git a/src/main/java/org/metricshub/ipmi/core/transport/Messenger.java b/src/main/java/org/metricshub/ipmi/core/transport/Messenger.java index 3ec3458..f98ae28 100644 --- a/src/main/java/org/metricshub/ipmi/core/transport/Messenger.java +++ b/src/main/java/org/metricshub/ipmi/core/transport/Messenger.java @@ -26,39 +26,38 @@ /** * Low level connection handler. - * */ public interface Messenger { - /** - * Sends {@link UdpMessage}. - * - * @param message - * - {@link UdpMessage} to send. - * @throws IOException - * when sending of the message fails - */ - void send(UdpMessage message) throws IOException; + /** + * Sends {@link UdpMessage}. + * + * @param message + * - {@link UdpMessage} to send. + * @throws IOException + * when sending of the message fails + */ + void send(UdpMessage message) throws IOException; - /** - * Registers listener in the {@link Messenger} so it will be notified via - * {@link UdpListener#notifyMessage(UdpMessage)} when new message arrives. - * - * @param listener - * - {@link UdpListener} to register. - */ - void register(UdpListener listener); + /** + * Registers listener in the {@link Messenger} so it will be notified via + * {@link UdpListener#notifyMessage(UdpMessage)} when new message arrives. + * + * @param listener + * - {@link UdpListener} to register. + */ + void register(UdpListener listener); - /** - * Unregisters listener from {@link Messenger} so it no longer will be - * notified. - * - * @param listener - * - {@link UdpListener} to unregister - */ - void unregister(UdpListener listener); + /** + * Unregisters listener from {@link Messenger} so it no longer will be + * notified. + * + * @param listener + * - {@link UdpListener} to unregister + */ + void unregister(UdpListener listener); - /** - * Closes the connection. - */ - void closeConnection(); + /** + * Closes the connection. + */ + void closeConnection(); } diff --git a/src/main/java/org/metricshub/ipmi/core/transport/UdpListener.java b/src/main/java/org/metricshub/ipmi/core/transport/UdpListener.java index 2ebb0f2..8999d4e 100644 --- a/src/main/java/org/metricshub/ipmi/core/transport/UdpListener.java +++ b/src/main/java/org/metricshub/ipmi/core/transport/UdpListener.java @@ -26,11 +26,11 @@ * An interface for {@link UdpMessenger} listener. */ public interface UdpListener { - /** - * Notifies listener of the UDP message that was received. - * - * @param message - * - message received - */ - void notifyMessage(UdpMessage message); + /** + * Notifies listener of the UDP message that was received. + * + * @param message + * - message received + */ + void notifyMessage(UdpMessage message); } diff --git a/src/main/java/org/metricshub/ipmi/core/transport/UdpMessage.java b/src/main/java/org/metricshub/ipmi/core/transport/UdpMessage.java index eab22be..b2711a1 100644 --- a/src/main/java/org/metricshub/ipmi/core/transport/UdpMessage.java +++ b/src/main/java/org/metricshub/ipmi/core/transport/UdpMessage.java @@ -28,57 +28,57 @@ * Container for UDP message. */ public class UdpMessage { - /** - * Target port when sending message. Sender port when receiving - * message. - */ - private int port; + /** + * Target port when sending message. Sender port when receiving + * message. + */ + private int port; - /** - * Target address when sending message. Sender address when receiving - * message. - */ - private InetAddress address; + /** + * Target address when sending message. Sender address when receiving + * message. + */ + private InetAddress address; - private byte[] message; + private byte[] message; - /** - * Target port when sending message. Sender port when receiving - * message. - */ - public void setPort(int port) { - this.port = port; - } + /** + * Target port when sending message. Sender port when receiving + * message. + */ + public void setPort(int port) { + this.port = port; + } - /** - * Target port when sending message. Sender port when receiving - * message. - */ - public int getPort() { - return port; - } + /** + * Target port when sending message. Sender port when receiving + * message. + */ + public int getPort() { + return port; + } - /** - * Target address when sending message. Sender address when receiving - * message. - */ - public InetAddress getAddress() { - return address; - } + /** + * Target address when sending message. Sender address when receiving + * message. + */ + public InetAddress getAddress() { + return address; + } - /** - * Target address when sending message. Sender address when receiving - * message. - */ - public void setAddress(InetAddress address) { - this.address = address; - } + /** + * Target address when sending message. Sender address when receiving + * message. + */ + public void setAddress(InetAddress address) { + this.address = address; + } - public byte[] getMessage() { - return message; - } + public byte[] getMessage() { + return message; + } - public void setMessage(byte[] message) { - this.message = message; - } + public void setMessage(byte[] message) { + this.message = message; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/transport/UdpMessenger.java b/src/main/java/org/metricshub/ipmi/core/transport/UdpMessenger.java index 51f57a8..4af8d19 100644 --- a/src/main/java/org/metricshub/ipmi/core/transport/UdpMessenger.java +++ b/src/main/java/org/metricshub/ipmi/core/transport/UdpMessenger.java @@ -39,189 +39,196 @@ */ public class UdpMessenger extends Thread implements Messenger { - private int port; - - private DatagramSocket socket; - - private List listeners; - - private boolean closing = false; - - private static final String DEFAULT_ADDRESS = "0.0.0.0"; - - /** - * Size of the message data buffer. Default - * {@link UdpMessenger#DEFAULTBUFFERSIZE}. - */ - private int bufferSize; - - private static final int DEFAULTBUFFERSIZE = 512; - - private static Logger logger = LoggerFactory.getLogger(UdpMessenger.class); - - public int getPort() { - return port; - } - - /** - * Initiates UdpMessenger, binds it to the specified port and starts - * listening. Wildcard IP address will be used. - * - * @param port - * - port to bind socket to. - * @throws SocketException - * if the socket could not be opened, or the socket could not - * bind to the specified local port. - * @throws UnknownHostException - */ - public UdpMessenger(int port) throws SocketException, UnknownHostException { - this(port, InetAddress.getByName(DEFAULT_ADDRESS)); - } - - /** - * Initiates UdpMessenger, binds it to the specified port and IP address and - * starts listening. - * - * @param port - * - port to bind socket to. - * @param address - * - IP address to bind socket to. - * @throws SocketException - * if the socket could not be opened, or the socket could not - * bind to the specified local port. - */ - public UdpMessenger(int port, InetAddress address) throws SocketException { - sentPackets = 0; - this.port = port; - listeners = new ArrayList(); - bufferSize = DEFAULTBUFFERSIZE; - socket = new DatagramSocket(this.port, address); - socket.setSoTimeout(0); - this.start(); - } - - /** - * Sets message data buffer size to bufferSize. - */ - public void setBufferSize(int bufferSize) { - this.bufferSize = bufferSize; - } - - /** - * @return Size of the message data buffer - */ - public int getBufferSize() { - return bufferSize; - } - - @Override - public void run() { - super.run(); - - boolean run = true; - - while (run) { - DatagramPacket response = new DatagramPacket(new byte[512], 512); - - try { - socket.receive(response); - UdpMessage message = new UdpMessage(); - message.setAddress(response.getAddress()); - message.setPort(response.getPort()); - byte[] buffer = new byte[response.getLength()]; - System.arraycopy(response.getData(), 0, buffer, 0, - buffer.length); - message.setMessage(buffer); - - notifyListeners(message); - - } catch (SocketException se) { - if (closing) { - run = false; - } else { - logger.error(se.getMessage(), se); - } - } catch (Exception e) { - logger.error(e.getMessage(), e); - } finally { - if (socket.isClosed()) { - run = false; - } - } - } - } - - private void notifyListeners(UdpMessage message) { - synchronized (listeners) { - for (UdpListener listener : listeners) { - if (listener != null) { - listener.notifyMessage(message); - } - } - } - } - - /** - * Closes the socket and releases port. - */ - public void closeConnection() { - closing = true; - socket.close(); - } - - /** - * Registers listener in the UdpMessenger so it will be notified via - * {@link UdpListener#notifyMessage(UdpMessage)} when new message arrives. - * - * @param listener - * - {@link UdpListener} to register. - */ - public void register(UdpListener listener) { - synchronized (listeners) { - listeners.add(listener); - } - } - - /** - * Unregisters listener from UdpMessenger so it no longer will be notified. - * - * @param listener - * - {@link UdpListener} to unregister - */ - public void unregister(UdpListener listener) { - synchronized (listeners) { - listeners.remove(listener); - } - } - - private static int sentPackets = 0; - - /** - * Returns number of packets sent since last creation of the instance of - * {@link UdpMessenger}. For debug/testing purposes only. - */ - public static int getSentPackets() { - return sentPackets; - } - - /** - * Sends {@link UdpMessage}. - * - * @param message - * - {@link UdpMessage} to send. - * @throws IOException - * when sending of the message fails - */ - public synchronized void send(UdpMessage message) throws IOException { - DatagramPacket packet = new DatagramPacket(message.getMessage(), - message.getMessage().length, message.getAddress(), - message.getPort()); - socket.send(packet); - try { - Thread.sleep(1); - } catch (InterruptedException e) { - // TODO: log - } - ++sentPackets; - } + private int port; + + private DatagramSocket socket; + + private List listeners; + + private boolean closing = false; + + private static final String DEFAULT_ADDRESS = "0.0.0.0"; + + /** + * Size of the message data buffer. Default + * {@link UdpMessenger#DEFAULTBUFFERSIZE}. + */ + private int bufferSize; + + private static final int DEFAULTBUFFERSIZE = 512; + + private static Logger logger = LoggerFactory.getLogger(UdpMessenger.class); + + public int getPort() { + return port; + } + + /** + * Initiates UdpMessenger, binds it to the specified port and starts + * listening. Wildcard IP address will be used. + * + * @param port + * - port to bind socket to. + * @throws SocketException + * if the socket could not be opened, or the socket could not + * bind to the specified local port. + * @throws UnknownHostException + */ + public UdpMessenger(int port) throws SocketException, UnknownHostException { + this(port, InetAddress.getByName(DEFAULT_ADDRESS)); + } + + /** + * Initiates UdpMessenger, binds it to the specified port and IP address and + * starts listening. + * + * @param port + * - port to bind socket to. + * @param address + * - IP address to bind socket to. + * @throws SocketException + * if the socket could not be opened, or the socket could not + * bind to the specified local port. + */ + public UdpMessenger(int port, InetAddress address) throws SocketException { + sentPackets = 0; + this.port = port; + listeners = new ArrayList(); + bufferSize = DEFAULTBUFFERSIZE; + socket = new DatagramSocket(this.port, address); + socket.setSoTimeout(0); + this.start(); + } + + /** + * Sets message data buffer size to bufferSize. + */ + public void setBufferSize(int bufferSize) { + this.bufferSize = bufferSize; + } + + /** + * @return Size of the message data buffer + */ + public int getBufferSize() { + return bufferSize; + } + + @Override + public void run() { + super.run(); + + boolean run = true; + + while (run) { + DatagramPacket response = new DatagramPacket(new byte[512], 512); + + try { + socket.receive(response); + UdpMessage message = new UdpMessage(); + message.setAddress(response.getAddress()); + message.setPort(response.getPort()); + byte[] buffer = new byte[response.getLength()]; + System + .arraycopy( + response.getData(), + 0, + buffer, + 0, + buffer.length); + message.setMessage(buffer); + + notifyListeners(message); + + } catch (SocketException se) { + if (closing) { + run = false; + } else { + logger.error(se.getMessage(), se); + } + } catch (Exception e) { + logger.error(e.getMessage(), e); + } finally { + if (socket.isClosed()) { + run = false; + } + } + } + } + + private void notifyListeners(UdpMessage message) { + synchronized (listeners) { + for (UdpListener listener : listeners) { + if (listener != null) { + listener.notifyMessage(message); + } + } + } + } + + /** + * Closes the socket and releases port. + */ + public void closeConnection() { + closing = true; + socket.close(); + } + + /** + * Registers listener in the UdpMessenger so it will be notified via + * {@link UdpListener#notifyMessage(UdpMessage)} when new message arrives. + * + * @param listener + * - {@link UdpListener} to register. + */ + public void register(UdpListener listener) { + synchronized (listeners) { + listeners.add(listener); + } + } + + /** + * Unregisters listener from UdpMessenger so it no longer will be notified. + * + * @param listener + * - {@link UdpListener} to unregister + */ + public void unregister(UdpListener listener) { + synchronized (listeners) { + listeners.remove(listener); + } + } + + private static int sentPackets = 0; + + /** + * Returns number of packets sent since last creation of the instance of + * {@link UdpMessenger}. For debug/testing purposes only. + */ + public static int getSentPackets() { + return sentPackets; + } + + /** + * Sends {@link UdpMessage}. + * + * @param message + * - {@link UdpMessage} to send. + * @throws IOException + * when sending of the message fails + */ + public synchronized void send(UdpMessage message) throws IOException { + DatagramPacket packet = new DatagramPacket( + message.getMessage(), + message.getMessage().length, + message.getAddress(), + message.getPort()); + socket.send(packet); + try { + Thread.sleep(1); + } catch (InterruptedException e) { + // TODO: log + } + ++sentPackets; + } } diff --git a/src/main/java/org/metricshub/ipmi/core/transport/UdpNotifier.java b/src/main/java/org/metricshub/ipmi/core/transport/UdpNotifier.java index 1e83289..731a582 100644 --- a/src/main/java/org/metricshub/ipmi/core/transport/UdpNotifier.java +++ b/src/main/java/org/metricshub/ipmi/core/transport/UdpNotifier.java @@ -26,23 +26,23 @@ public class UdpNotifier extends Thread { - private List listeners; - private UdpMessage message; + private List listeners; + private UdpMessage message; - public UdpNotifier(UdpMessage message, List listeners) { - this.message = message; - this.listeners = listeners; - } + public UdpNotifier(UdpMessage message, List listeners) { + this.message = message; + this.listeners = listeners; + } - @Override - public void run() { + @Override + public void run() { - for (UdpListener listener : listeners) { - if (listener != null) { - listener.notifyMessage(message); - } - } + for (UdpListener listener : listeners) { + if (listener != null) { + listener.notifyMessage(message); + } + } - super.run(); - } + super.run(); + } } diff --git a/src/main/java/org/metricshub/ipmi/core/transport/package-info.java b/src/main/java/org/metricshub/ipmi/core/transport/package-info.java index 12b2fbd..88e4d50 100644 --- a/src/main/java/org/metricshub/ipmi/core/transport/package-info.java +++ b/src/main/java/org/metricshub/ipmi/core/transport/package-info.java @@ -1,6 +1,6 @@ /** * The UDP transport layer. - * + * * @see org.metricshub.ipmi.core.transport.UdpMessenger */ package org.metricshub.ipmi.core.transport; diff --git a/src/main/java/org/metricshub/ipmi/package-info.java b/src/main/java/org/metricshub/ipmi/package-info.java index b0b2e25..726ae37 100644 --- a/src/main/java/org/metricshub/ipmi/package-info.java +++ b/src/main/java/org/metricshub/ipmi/package-info.java @@ -1,5 +1,5 @@ /** - * Base package of the IPMI client library for Java + * Base package of the IPMI client library for Java */ package org.metricshub.ipmi; /*- diff --git a/src/main/resources/connection.properties b/src/main/resources/connection.properties index 91c47a8..3f64be6 100644 --- a/src/main/resources/connection.properties +++ b/src/main/resources/connection.properties @@ -3,4 +3,4 @@ pingPeriod=30000 #Time in ms after which a message times out. timeout=300000 #Frequency of checking messages for timeouts in ms. -cleaningFrequency=500 \ No newline at end of file +cleaningFrequency=500 diff --git a/src/main/resources/vxipmi.properties b/src/main/resources/vxipmi.properties index 1c90c74..7bda221 100644 --- a/src/main/resources/vxipmi.properties +++ b/src/main/resources/vxipmi.properties @@ -1,4 +1,4 @@ #Indicates how many times the message will be retried on a failure retries=3 #Idle time in ms before resending a message that didn't receive answer. -idleTime=4000 \ No newline at end of file +idleTime=4000 diff --git a/src/site/markdown/index.md b/src/site/markdown/index.md index 1af5aa7..3b3f187 100644 --- a/src/site/markdown/index.md +++ b/src/site/markdown/index.md @@ -64,3 +64,21 @@ public class IpmiMain { ``` +## Upgrading from 1.2.02 + +The `IpmiClient` API is unchanged. Classes that **extend** the library's protocol classes must replace direct access to formerly `protected` fields, which are now `private`, with the new `protected` accessors: + +| Class | Former field | Accessor | +| --- | --- | --- | +| `AbstractIpmiRunner` | `ipmiConfiguration` | `getIpmiConfiguration()` | +| `AbstractIpmiRunner` | `connector` | `getConnector()` | +| `AbstractIpmiRunner` | `handle` | `getHandle()` | +| `AbstractIpmiRunner` | `nextRecId` | `getNextRecId()`, `setNextRecId(int)` | +| `MessageHandler` | `messageQueue` | `getMessageQueue()` | +| `MessageHandler` | `connection` | `getConnection()` | +| `MessageHandler` | `lastReceivedSequenceNumber` | `getLastReceivedSequenceNumber()`, `setLastReceivedSequenceNumber(int)` | +| `IpmiLanMessage` | `networkFunction` | `getNetworkFunctionCode()`, `setNetworkFunctionCode(byte)` | +| `ConfidentialityAlgorithm` | `sik` | `getSik()` | +| `IntegrityAlgorithm` | `sik` | `getSik()`, `setSik(byte[])` | + +`IpmiClient`, `IpmiResultConverter`, `Utils`, `DeviceDescription`, `ReadingTypeDescription` and `MessageComposer` are now `final` (they only had private constructors, so they could not be subclassed anyway). diff --git a/src/test/java/org/metricshub/ipmi/client/IpmiResultConverterTest.java b/src/test/java/org/metricshub/ipmi/client/IpmiResultConverterTest.java index f94d455..f62dd43 100644 --- a/src/test/java/org/metricshub/ipmi/client/IpmiResultConverterTest.java +++ b/src/test/java/org/metricshub/ipmi/client/IpmiResultConverterTest.java @@ -22,27 +22,597 @@ class IpmiResultConverterTest { - public static final byte[] BASE_BOARD_PRODUCT_INFO = { 1, 0, 1, 8, 45, 0, 0, -55, 1, 7, 1, 0, -34, 75, 68, 57, 48, 57, 56, 67, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 102, 82, -95, -100, -109, -120, 57, 41, -72, -89, -42, -49, 55, -119, -77, -61, - -63, 0, 0, -16, 1, 37, 0, 32, -66, 108, -34, 32, 73, 66, 77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -32, 83, 121, 115, 116, 101, 109, 32, 66, 111, 97, 114, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -34, 89, 75, 49, - 53, 57, 48, 57, 55, 90, 48, 57, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -34, 52, 57, 89, 54, 52, 57, 56, 32, 32, 32, 32, - 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -51, 52, 51, 86, 55, 48, 55, 50, 32, 32, 32, 32, 32, 0, 2, 0, 2, 2, 0, 0, 2, - 0, 80, -34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 1, 6, 60, 1, 0, 48, 0, 33, 94, - -37, 23, -112, 0, 33, 94, -37, 23, -110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 16, 102, 82, -95, -100, -109, -120, 57, 41, -72, -89, -42, -49, 55, -119, -77, -61, 1, 2, 16, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 44, 2, 0, 0, -63, 0, -71, 1, 21, 0, -34, 32, 73, 66, 77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -32, 83, 121, 115, 116, 101, 109, 32, 120, 51, 54, 53, 48, 32, 77, 50, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -34, 55, 57, 52, 55, 50, 50, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -34, 75, 68, 57, 48, 57, 56, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -31, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 0, 0, -63, 0, 26 }; + public static final byte[] BASE_BOARD_PRODUCT_INFO = { + 1, + 0, + 1, + 8, + 45, + 0, + 0, + -55, + 1, + 7, + 1, + 0, + -34, + 75, + 68, + 57, + 48, + 57, + 56, + 67, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 16, + 102, + 82, + -95, + -100, + -109, + -120, + 57, + 41, + -72, + -89, + -42, + -49, + 55, + -119, + -77, + -61, + -63, + 0, + 0, + -16, + 1, + 37, + 0, + 32, + -66, + 108, + -34, + 32, + 73, + 66, + 77, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + -32, + 83, + 121, + 115, + 116, + 101, + 109, + 32, + 66, + 111, + 97, + 114, + 100, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + -34, + 89, + 75, + 49, + 53, + 57, + 48, + 57, + 55, + 90, + 48, + 57, + 89, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + -34, + 52, + 57, + 89, + 54, + 52, + 57, + 56, + 32, + 32, + 32, + 32, + 32, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + -51, + 52, + 51, + 86, + 55, + 48, + 55, + 50, + 32, + 32, + 32, + 32, + 32, + 0, + 2, + 0, + 2, + 2, + 0, + 0, + 2, + 0, + 80, + -34, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 5, + 1, + 6, + 60, + 1, + 0, + 48, + 0, + 33, + 94, + -37, + 23, + -112, + 0, + 33, + 94, + -37, + 23, + -110, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 16, + 102, + 82, + -95, + -100, + -109, + -120, + 57, + 41, + -72, + -89, + -42, + -49, + 55, + -119, + -77, + -61, + 1, + 2, + 16, + 17, + 17, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 8, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2, + 1, + 44, + 2, + 0, + 0, + -63, + 0, + -71, + 1, + 21, + 0, + -34, + 32, + 73, + 66, + 77, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + -32, + 83, + 121, + 115, + 116, + 101, + 109, + 32, + 120, + 51, + 54, + 53, + 48, + 32, + 77, + 50, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + -34, + 55, + 57, + 52, + 55, + 50, + 50, + 71, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + -34, + 75, + 68, + 57, + 48, + 57, + 56, + 67, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + -31, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 0, + 0, + -63, + 0, + 26 }; public static final byte[] FRONT_PANEL_FULL_RECORD = { - 1, 0, 81, 1, 55, 32, 0, 50, 12, 1, 127, 104, 1, - 1, -128, 10, -128, 122, 56, 0, 0, 1, 0, 0, 1, - 0, 124, -64, 0, 0, 1, -103, -78, -120, -1, 0, - -79, -83, -86, 0, 0, 0, 4, 0, 0, 0, 0, -52, 65, - 109, 98, 105, 101, 110, 116, 32, 84, 101, 109, 112 }; + 1, + 0, + 81, + 1, + 55, + 32, + 0, + 50, + 12, + 1, + 127, + 104, + 1, + 1, + -128, + 10, + -128, + 122, + 56, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 124, + -64, + 0, + 0, + 1, + -103, + -78, + -120, + -1, + 0, + -79, + -83, + -86, + 0, + 0, + 0, + 4, + 0, + 0, + 0, + 0, + -52, + 65, + 109, + 98, + 105, + 101, + 110, + 116, + 32, + 84, + 101, + 109, + 112 }; @Test void testConvertResultListOfFruListOfSensor() { @@ -102,10 +672,12 @@ public static List buildSensors() { // And sorry... data.setSensorReading((byte) -102); - return Arrays.asList(new Sensor(compact1, new GetSensorReadingResponseData(), "Base board=Device Present"), - new Sensor(compact2, new GetSensorReadingResponseData(), "Battery 1=Transition to OK"), - new Sensor(compact3, new GetSensorReadingResponseData(), "Video USB=Connected"), - new Sensor(full, data, "Front Panel=Device Present")); + return Arrays + .asList( + new Sensor(compact1, new GetSensorReadingResponseData(), "Base board=Device Present"), + new Sensor(compact2, new GetSensorReadingResponseData(), "Battery 1=Transition to OK"), + new Sensor(compact3, new GetSensorReadingResponseData(), "Video USB=Connected"), + new Sensor(full, data, "Front Panel=Device Present")); } @Test diff --git a/src/test/java/org/metricshub/ipmi/client/model/DeviceDescriptionTest.java b/src/test/java/org/metricshub/ipmi/client/model/DeviceDescriptionTest.java index a6ff403..f1900fc 100644 --- a/src/test/java/org/metricshub/ipmi/client/model/DeviceDescriptionTest.java +++ b/src/test/java/org/metricshub/ipmi/client/model/DeviceDescriptionTest.java @@ -9,7 +9,7 @@ class DeviceDescriptionTest { @Test void testGetDeviceType() { - for (EntityId entityId: EntityId.values()) { + for (EntityId entityId : EntityId.values()) { assertNotNull(DeviceDescription.getDeviceType(entityId)); } } diff --git a/src/test/java/org/metricshub/ipmi/client/model/SensorTest.java b/src/test/java/org/metricshub/ipmi/client/model/SensorTest.java index 1254fda..a624ad4 100644 --- a/src/test/java/org/metricshub/ipmi/client/model/SensorTest.java +++ b/src/test/java/org/metricshub/ipmi/client/model/SensorTest.java @@ -17,8 +17,8 @@ void testIsCompact() { CompactSensorRecord record = new CompactSensorRecord(); GetSensorReadingResponseData data = new GetSensorReadingResponseData(); String states = "power supply 1=Transition to OK"; - assertTrue(new Sensor(record, data , states).isCompact()); - assertFalse(new Sensor(record, data , states).isFull()); + assertTrue(new Sensor(record, data, states).isCompact()); + assertFalse(new Sensor(record, data, states).isFull()); } @Test @@ -26,8 +26,8 @@ void testIsFull() { FullSensorRecord record = new FullSensorRecord(); GetSensorReadingResponseData data = new GetSensorReadingResponseData(); String states = "power supply 1=Transition to OK"; - assertFalse(new Sensor(record, data , states).isCompact()); - assertTrue(new Sensor(record, data , states).isFull()); + assertFalse(new Sensor(record, data, states).isCompact()); + assertTrue(new Sensor(record, data, states).isFull()); } @Test diff --git a/src/test/java/org/metricshub/ipmi/client/runner/AbstractIpmiRunnerTest.java b/src/test/java/org/metricshub/ipmi/client/runner/AbstractIpmiRunnerTest.java index acd1099..f7d8e07 100644 --- a/src/test/java/org/metricshub/ipmi/client/runner/AbstractIpmiRunnerTest.java +++ b/src/test/java/org/metricshub/ipmi/client/runner/AbstractIpmiRunnerTest.java @@ -34,17 +34,17 @@ private static byte[] record(int type, byte[] payload) { @Test void decodeRecordReturnsOemRecordForVendorDefinedType() { - assertInstanceOf(OemRecord.class, RUNNER.decodeRecord(record(0xd0, new byte[] {1, 2, 3}))); + assertInstanceOf(OemRecord.class, RUNNER.decodeRecord(record(0xd0, new byte[] { 1, 2, 3 }))); } @Test void decodeRecordSkipsRecordsItCannotDecodeInsteadOfThrowing() { // reserved (non-OEM) record type - assertNull(RUNNER.decodeRecord(record(0x05, new byte[] {1}))); + assertNull(RUNNER.decodeRecord(record(0x05, new byte[] { 1 }))); // shorter than the SDR header - assertNull(RUNNER.decodeRecord(new byte[] {0x00})); + assertNull(RUNNER.decodeRecord(new byte[] { 0x00 })); // full sensor record whose body is missing: decoder runs out of bytes - assertNull(RUNNER.decodeRecord(record(0x01, new byte[] {1, 2, 3}))); + assertNull(RUNNER.decodeRecord(record(0x01, new byte[] { 1, 2, 3 }))); } @Test @@ -61,14 +61,14 @@ void decodeRecordStillDecodesValidRecords() { @Test void isTruncatedDetectsWholeRecordResponsesShorterThanDeclared() { - byte[] complete = record(0xd0, new byte[] {1, 2, 3, 4, 5}); + byte[] complete = record(0xd0, new byte[] { 1, 2, 3, 4, 5 }); assertFalse(AbstractIpmiRunner.isTruncated(complete)); byte[] truncated = new byte[complete.length - 2]; System.arraycopy(complete, 0, truncated, 0, truncated.length); assertTrue(AbstractIpmiRunner.isTruncated(truncated), "declared length 5 but only 3 payload bytes returned"); - assertTrue(AbstractIpmiRunner.isTruncated(new byte[] {0x00, 0x00, 0x51}), "header itself is incomplete"); + assertTrue(AbstractIpmiRunner.isTruncated(new byte[] { 0x00, 0x00, 0x51 }), "header itself is incomplete"); assertTrue(AbstractIpmiRunner.isTruncated(null)); } } diff --git a/src/test/java/org/metricshub/ipmi/client/runner/GetSensorsRunnerTest.java b/src/test/java/org/metricshub/ipmi/client/runner/GetSensorsRunnerTest.java index 87e5385..e62cf5b 100644 --- a/src/test/java/org/metricshub/ipmi/client/runner/GetSensorsRunnerTest.java +++ b/src/test/java/org/metricshub/ipmi/client/runner/GetSensorsRunnerTest.java @@ -25,19 +25,19 @@ void testBuildStates() { // check CompactSensorRecord oem type { - final byte[] raw = {1, 2, 3, 127}; + final byte[] raw = { 1, 2, 3, 127 }; final GetSensorReadingResponseData data = new GetSensorReadingResponseData(); data.setRaw(raw); final CompactSensorRecord record = new CompactSensorRecord(); record.setName(DEVICE_NAME); record.setEventReadingType(OEM_EVENT_READING_TYPE); - assertEquals("name=0x7f03", GetSensorsRunner.buildStates(data, record)); + assertEquals("name=0x7f03", GetSensorsRunner.buildStates(data, record)); } // check CompactSensorRecord { - final boolean[] statesAsserted = {true, false}; + final boolean[] statesAsserted = { true, false }; final GetSensorReadingResponseData data = new GetSensorReadingResponseData(); data.setStatesAsserted(statesAsserted); @@ -46,24 +46,24 @@ void testBuildStates() { record.setSensorType(SensorType.PowerUnit); record.setEventReadingType(7535); - assertEquals("name=Power up", GetSensorsRunner.buildStates(data, record)); + assertEquals("name=Power up", GetSensorsRunner.buildStates(data, record)); } // check FullSensorRecord oem { - final byte[] raw = {1, 2, 3, 127}; + final byte[] raw = { 1, 2, 3, 127 }; final GetSensorReadingResponseData data = new GetSensorReadingResponseData(); data.setRaw(raw); final FullSensorRecord record = new FullSensorRecord(); record.setName(DEVICE_NAME); record.setEventReadingType(OEM_EVENT_READING_TYPE); - assertEquals("name=0x7f03", GetSensorsRunner.buildStates(data, record)); + assertEquals("name=0x7f03", GetSensorsRunner.buildStates(data, record)); } // check FullSensorRecord { - final boolean[] statesAsserted = {true, true}; + final boolean[] statesAsserted = { true, true }; final GetSensorReadingResponseData data = new GetSensorReadingResponseData(); data.setStatesAsserted(statesAsserted); @@ -72,7 +72,7 @@ void testBuildStates() { record.setSensorType(SensorType.PowerUnit); record.setEventReadingType(7535); - assertEquals("name=Power up|name=Hard reset", GetSensorsRunner.buildStates(data, record)); + assertEquals("name=Power up|name=Hard reset", GetSensorsRunner.buildStates(data, record)); } } @@ -101,7 +101,7 @@ void testBuildOemState() { // check raw length < 4 { - final byte[] raw = {1, 2, 3}; + final byte[] raw = { 1, 2, 3 }; final Exception exception = assertThrows( IllegalArgumentException.class, @@ -112,7 +112,7 @@ void testBuildOemState() { // check ok { - final byte[] raw = {1, 2, 3, 127}; + final byte[] raw = { 1, 2, 3, 127 }; assertEquals("name=0x7f03", GetSensorsRunner.buildOemState(raw, DEVICE_NAME)); } } diff --git a/src/test/java/org/metricshub/ipmi/core/coding/commands/sdr/record/SensorRecordTest.java b/src/test/java/org/metricshub/ipmi/core/coding/commands/sdr/record/SensorRecordTest.java index 7d513f3..eab5fa5 100644 --- a/src/test/java/org/metricshub/ipmi/core/coding/commands/sdr/record/SensorRecordTest.java +++ b/src/test/java/org/metricshub/ipmi/core/coding/commands/sdr/record/SensorRecordTest.java @@ -26,7 +26,7 @@ private static byte[] record(int id, int type, byte[] payload) { @Test void vendorDefinedRecordTypeIsDecodedAsOemRecordWithWholePayload() { // Record type D0h as emitted by GIGABYTE/NVIDIA BMCs: vendor-defined layout, no manufacturer ID field - byte[] payload = {0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}; + byte[] payload = { 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }; SensorRecord record = SensorRecord.populateSensorRecord(record(0x0004, 0xd0, payload)); @@ -38,7 +38,7 @@ void vendorDefinedRecordTypeIsDecodedAsOemRecordWithWholePayload() { @Test void lastOemRecordTypeIsAccepted() { - byte[] payload = {0x01, 0x02}; + byte[] payload = { 0x01, 0x02 }; OemRecord oem = assertInstanceOf(OemRecord.class, SensorRecord.populateSensorRecord(record(0x0010, 0xff, payload))); @@ -48,35 +48,46 @@ void lastOemRecordTypeIsAccepted() { @Test void standardOemRecordTypeC0ParsesManufacturerIdAndData() { // C0h layout: 3-byte manufacturer ID (LE, 0x000157 = 343) followed by OEM data - byte[] payload = {0x57, 0x01, 0x00, 0x21, 0x22}; + byte[] payload = { 0x57, 0x01, 0x00, 0x21, 0x22 }; OemRecord oem = assertInstanceOf(OemRecord.class, SensorRecord.populateSensorRecord(record(0x0020, 0xc0, payload))); assertEquals(343, oem.getManufacturerId()); - assertArrayEquals(new byte[] {0x21, 0x22}, oem.getOemData()); + assertArrayEquals(new byte[] { 0x21, 0x22 }, oem.getOemData()); } @Test void shortOemRecordDoesNotThrow() { // C0h record without even a complete manufacturer ID: no ID is fabricated and the bytes are kept as payload - OemRecord oem = assertInstanceOf(OemRecord.class, SensorRecord.populateSensorRecord(record(0x0030, 0xc0, new byte[] {0x57}))); + OemRecord oem = assertInstanceOf( + OemRecord.class, + SensorRecord.populateSensorRecord(record(0x0030, 0xc0, new byte[] + { 0x57 }))); assertEquals(0, oem.getManufacturerId()); - assertArrayEquals(new byte[] {0x57}, oem.getOemData()); + assertArrayEquals(new byte[] { 0x57 }, oem.getOemData()); // header only - OemRecord empty = assertInstanceOf(OemRecord.class, SensorRecord.populateSensorRecord(record(0x0031, 0xc0, new byte[0]))); + OemRecord empty = assertInstanceOf( + OemRecord.class, + SensorRecord.populateSensorRecord(record(0x0031, 0xc0, new byte[0]))); assertEquals(0, empty.getOemData().length); } @Test void unknownStandardRecordTypeIsRejected() { // 05h is reserved by IPMI 2.0 and not an OEM type: callers are expected to skip it - assertThrows(IllegalArgumentException.class, () -> SensorRecord.populateSensorRecord(record(0x0040, 0x05, new byte[] {0x00}))); + assertThrows( + IllegalArgumentException.class, + () -> SensorRecord.populateSensorRecord(record(0x0040, 0x05, new byte[] + { 0x00 }))); } @Test void recordShorterThanHeaderIsRejected() { - assertThrows(IllegalArgumentException.class, () -> SensorRecord.populateSensorRecord(new byte[] {0x00, 0x00, 0x51})); + assertThrows( + IllegalArgumentException.class, + () -> SensorRecord.populateSensorRecord(new byte[] + { 0x00, 0x00, 0x51 })); } }