Skip to content

Commit

Permalink
#340 Moving command execution into private method (safer)
Browse files Browse the repository at this point in the history
  • Loading branch information
Frank Delporte committed Apr 5, 2024
1 parent 264a5a9 commit 42d9649
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 83 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

import com.pi4j.boardinfo.definition.BoardModel;

public class DetectedBoard {
public class BoardInfo {

private final BoardModel boardModel;
private final OperatingSystem operatingSystem;
private final JavaInfo javaInfo;

public DetectedBoard(BoardModel boardModel, OperatingSystem operatingSystem, JavaInfo javaInfo) {
public BoardInfo(BoardModel boardModel, OperatingSystem operatingSystem, JavaInfo javaInfo) {
this.boardModel = boardModel;
this.operatingSystem = operatingSystem;
this.javaInfo = javaInfo;
Expand Down
114 changes: 101 additions & 13 deletions pi4j-core/src/main/java/com/pi4j/boardinfo/util/BoardModelDetection.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package com.pi4j.boardinfo.util;

import com.pi4j.boardinfo.definition.BoardModel;
import com.pi4j.boardinfo.model.DetectedBoard;
import com.pi4j.boardinfo.model.BoardInfo;
import com.pi4j.boardinfo.model.JavaInfo;
import com.pi4j.boardinfo.model.OperatingSystem;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.concurrent.TimeUnit;

public class BoardModelDetection {

private static final Logger logger = LoggerFactory.getLogger(BoardModelDetection.class);
Expand All @@ -15,7 +18,7 @@ private BoardModelDetection() {
// Hide constructor
}

public static DetectedBoard getDetectedBoard() {
public static BoardInfo current() {
var os = new OperatingSystem(System.getProperty("os.name"),
System.getProperty("os.version"),
System.getProperty("os.arch"));
Expand All @@ -28,33 +31,118 @@ public static DetectedBoard getDetectedBoard() {
logger.info("Detected Java: {}", java);

// Example output: c03111
var boardVersionCode = getCommandOutput("cat /proc/cpuinfo | grep 'Revision' | awk '{print $3}'");
var boardVersionCode = getBoardVersionCode();
var boardModelByBoardCode = BoardModel.getByBoardCode(boardVersionCode);
if (boardModelByBoardCode != BoardModel.UNKNOWN) {
logger.info("Detected board type {} by code: {}", boardModelByBoardCode.name(), boardVersionCode);
return new DetectedBoard(boardModelByBoardCode, os, java);
return new BoardInfo(boardModelByBoardCode, os, java);
}

// Example output: Raspberry Pi 4 Model B Rev 1.1
var boardName = getCommandOutput("cat /proc/device-tree/model");
var boardName = getBoardName();
boardModelByBoardCode = BoardModel.getByBoardName(boardName);
if (boardModelByBoardCode != BoardModel.UNKNOWN) {
logger.info("Detected board type {} by name: {}", boardModelByBoardCode.name(), boardName);
return new DetectedBoard(boardModelByBoardCode, os, java);
return new BoardInfo(boardModelByBoardCode, os, java);
}

// Maybe there are other ways how a board can be detected?
// If so, this method can be further extended...
logger.warn("Sorry, could not detect the board type");
return new DetectedBoard(BoardModel.UNKNOWN, os, java);
return new BoardInfo(BoardModel.UNKNOWN, os, java);
}

public static String getBoardVersionCode() {
var output = getCommandOutput("cat /proc/cpuinfo | grep 'Revision' | awk '{print $3}'");
if (output.isSuccess()) {
return output.getOutputMessage();
}
logger.error("Could not get the board version code: {}", output.getErrorMessage());
return "";
}

public static String getBoardName() {
var output = getCommandOutput("cat /proc/device-tree/model");
if (output.isSuccess()) {
return output.getOutputMessage();
}
logger.error("Could not get the board name: {}", output.getErrorMessage());
return "";
}

private static class CommandResult {
private final boolean success;
private final String outputMessage;
private final String errorMessage;

public CommandResult(boolean success, String outputMessage, String errorMessage) {
this.success = success;
this.outputMessage = outputMessage;
this.errorMessage = errorMessage;
}

public boolean isSuccess() {
return success;
}

public String getOutputMessage() {
return outputMessage;
}

public String getErrorMessage() {
return errorMessage;
}
}

private static CommandResult getCommandOutput(String command) {
boolean finished = false;
String outputMessage = "";
String errorMessage = "";

ProcessBuilder builder = new ProcessBuilder();
builder.command("sh", "-c", command);

try {
Process process = builder.start();

OutputStream outputStream = process.getOutputStream();
InputStream inputStream = process.getInputStream();
InputStream errorStream = process.getErrorStream();

outputMessage = readStream(inputStream);
errorMessage = readStream(errorStream);

finished = process.waitFor(30, TimeUnit.SECONDS);
outputStream.flush();
outputStream.close();

if (!finished) {
process.destroyForcibly();
}
} catch (IOException ex) {
errorMessage = "IOException: " + ex.getMessage();
} catch (InterruptedException ex) {
errorMessage = "InterruptedException: " + ex.getMessage();
}

if (!finished || !errorMessage.isEmpty()) {
logger.error("Could not execute '{}' to detect the board model: {}", command, errorMessage);
return new CommandResult(false, outputMessage, errorMessage);
}

return new CommandResult(true, outputMessage, errorMessage);
}

private static String getCommandOutput(String command) {
ExecUtil execUtil = new ExecUtil(command);
if (!execUtil.isFinished() || !execUtil.getErrorMessage().isEmpty()) {
logger.error("Could not execute '{}' to detect the board model: {}", command, execUtil.getErrorMessage());
return "";
private static String readStream(InputStream inputStream) {
StringBuilder rt = new StringBuilder();
try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream))) {
String line;
while ((line = bufferedReader.readLine()) != null) {
rt.append(line);
}
} catch (Exception ex) {
rt.append("ERROR: ").append(ex.getMessage());
}
return execUtil.getOutputMessage();
return rt.toString();
}
}
68 changes: 0 additions & 68 deletions pi4j-core/src/main/java/com/pi4j/boardinfo/util/ExecUtil.java

This file was deleted.

0 comments on commit 42d9649

Please sign in to comment.