ipmi: start implementing flashVerifyCheck
Change-Id: I811693d9e736d273d2df9e65f7c5de7efd1d884c
Signed-off-by: Patrick Venture <venture@google.com>
diff --git a/configure.ac b/configure.ac
index 12763e4..d565472 100644
--- a/configure.ac
+++ b/configure.ac
@@ -76,6 +76,10 @@
AS_IF([test "x$HASH_PATH" == "x"], [HASH_PATH="/tmp/bmc.sig"])
AC_DEFINE_UNQUOTED([HASH_PATH], ["$HASH_PATH"], [The path for the hash file.])
+AC_ARG_VAR(STATUS_PATH, [The path for the verification status file.])
+AS_IF([test "x$STATUS_PATH" == "x"], [STATUS_PATH="/tmp/bmc.verify"])
+AC_DEFINE_UNQUOTED([STATUS_PATH], ["$STATUS_PATH"], [The path for the verification status file.])
+
# Create configured output
AC_CONFIG_FILES([Makefile test/Makefile])
AC_OUTPUT
diff --git a/flash-ipmi.cpp b/flash-ipmi.cpp
index dda9580..00fa027 100644
--- a/flash-ipmi.cpp
+++ b/flash-ipmi.cpp
@@ -196,3 +196,9 @@
/* TODO: implement. */
return false;
}
+
+VerifyCheckResponse FlashUpdate::checkVerify()
+{
+ /* TODO: implement. */
+ return VerifyCheckResponse::other;
+}
diff --git a/flash-ipmi.hpp b/flash-ipmi.hpp
index 2d7dcaa..4a13edb 100644
--- a/flash-ipmi.hpp
+++ b/flash-ipmi.hpp
@@ -10,6 +10,18 @@
#define SUBCMD_SZ sizeof(uint8_t)
/*
+ * These are the codes we return over IPMI when the host checks for the status
+ * of the asynchronous verification call.
+ */
+enum VerifyCheckResponse
+{
+ running = 0x00,
+ success = 0x01,
+ failed = 0x02,
+ other = 0x03,
+};
+
+/*
* flashStartTransfer -- starts file upload.
* flashDataBlock -- adds data to image file.
* flashDataFinish -- closes the file.
@@ -145,14 +157,23 @@
* @return true if aborted, false if unable or failed.
*/
virtual bool abortUpdate() = 0;
+
+ /**
+ * Check if the verification result is available and return.
+ *
+ * @return the verification response.
+ */
+ virtual VerifyCheckResponse checkVerify() = 0;
};
class FlashUpdate : public UpdateInterface
{
public:
- FlashUpdate(const std::string& stagingPath, const std::string& hash = "") :
- flashLength(0), flashFd(nullptr), tmpPath(stagingPath), hashLength(0),
- hashFd(nullptr), hashPath(hash){};
+ FlashUpdate(const std::string& stagingPath, const std::string& verifyPath,
+ const std::string& hash = "") :
+ flashLength(0),
+ flashFd(nullptr), tmpPath(stagingPath), hashLength(0), hashFd(nullptr),
+ hashPath(hash), verifyPath(verifyPath){};
~FlashUpdate();
FlashUpdate(const FlashUpdate&) = default;
@@ -170,6 +191,7 @@
bool startDataVerification() override;
bool abortUpdate() override;
+ VerifyCheckResponse checkVerify() override;
private:
/**
@@ -219,4 +241,7 @@
* process uses a separate signature.
*/
const std::string hashPath;
+
+ /* The path to read the status of the signature verification. */
+ const std::string verifyPath;
};
diff --git a/ipmi.cpp b/ipmi.cpp
index 50269b0..3c43aa7 100644
--- a/ipmi.cpp
+++ b/ipmi.cpp
@@ -32,6 +32,7 @@
{FlashSubCmds::flashHashFinish, hashFinish},
{FlashSubCmds::flashDataVerify, dataVerify},
{FlashSubCmds::flashAbort, abortUpdate},
+ {FlashSubCmds::flashVerifyCheck, checkVerify},
};
auto results = subHandlers.find(command);
@@ -210,3 +211,12 @@
(*dataLen) = 1;
return IPMI_CC_OK;
}
+
+ipmi_ret_t checkVerify(UpdateInterface* updater, const uint8_t* reqBuf,
+ uint8_t* replyBuf, size_t* dataLen)
+{
+ auto value = updater->checkVerify();
+ replyBuf[0] = static_cast<uint8_t>(value);
+ (*dataLen) = 1;
+ return IPMI_CC_OK;
+}
diff --git a/ipmi.hpp b/ipmi.hpp
index 7fc27b4..bc457c0 100644
--- a/ipmi.hpp
+++ b/ipmi.hpp
@@ -130,3 +130,16 @@
*/
ipmi_ret_t abortUpdate(UpdateInterface* updater, const uint8_t* reqBuf,
uint8_t* replyBuf, size_t* dataLen);
+
+/**
+ * Check on the status of the verification process.
+ *
+ * @param[in] updater - Pointer to Updater object.
+ * @param[in] reqBuf - the IPMI packet.
+ * @param[in] replyBuf - Pointer to buffer for any response.
+ * @param[in,out] dataLen - Initially reqBuf length, set to replyBuf
+ * length when done.
+ * @return corresponding IPMI return code.
+ */
+ipmi_ret_t checkVerify(UpdateInterface* updater, const uint8_t* reqBuf,
+ uint8_t* replyBuf, size_t* dataLen);
diff --git a/main.cpp b/main.cpp
index 791cb22..5385348 100644
--- a/main.cpp
+++ b/main.cpp
@@ -25,6 +25,7 @@
static constexpr auto stagingPath = STAGING_PATH;
static constexpr auto hashPath = HASH_PATH;
+static constexpr auto statusPath = STATUS_PATH;
/* TODO: Once OEM IPMI number placement is settled, point to that. */
namespace oem
@@ -85,7 +86,8 @@
void setupGlobalOemFlashControl()
{
- flashUpdateSingleton = std::make_unique<FlashUpdate>(stagingPath, hashPath);
+ flashUpdateSingleton =
+ std::make_unique<FlashUpdate>(stagingPath, statusPath, hashPath);
#ifdef ENABLE_GOOGLE
oem::Router* router = oem::mutableRouter();
diff --git a/test/Makefile.am b/test/Makefile.am
index bed24e6..26f3439 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -20,6 +20,7 @@
ipmi_abort_unittest \
ipmi_validate_unittest \
ipmi_command_unittest \
+ ipmi_verifycheck_unittest \
flash_start_unittest \
flash_flashdata_unittest \
flash_flashfinish_unittest \
@@ -59,6 +60,9 @@
ipmi_command_unittest_SOURCES = ipmi_command_unittest.cpp
ipmi_command_unittest_LDADD = $(top_builddir)/ipmi.o
+ipmi_verifycheck_unittest_SOURCES = ipmi_verifycheck_unittest.cpp
+ipmi_verifycheck_unittest_LDADD = $(top_builddir)/ipmi.o
+
flash_start_unittest_SOURCES = flash_start_unittest.cpp
flash_start_unittest_LDADD = $(top_builddir)/flash-ipmi.o $(SDBUSPLUS_LIBS)
diff --git a/test/flash_flashdata_unittest.cpp b/test/flash_flashdata_unittest.cpp
index df561ec..112565a 100644
--- a/test/flash_flashdata_unittest.cpp
+++ b/test/flash_flashdata_unittest.cpp
@@ -30,7 +30,7 @@
// Verify that there is sanity checking.
std::vector<uint8_t> bytes = {0xaa, 0x55};
- FlashUpdate updater(name);
+ FlashUpdate updater(name, "");
EXPECT_FALSE(updater.flashData(0, bytes));
// Verify the file doesn't exist.
@@ -43,7 +43,7 @@
// Verify that under normal usage it writes the bytes.
std::vector<uint8_t> bytes = {0xaa, 0x55};
- FlashUpdate updater(name);
+ FlashUpdate updater(name, "");
updater.start(THIRTYTWO_MIB);
EXPECT_TRUE(updater.flashData(0, bytes));
@@ -65,7 +65,7 @@
std::vector<uint8_t> bytes = {0xaa, 0x55};
- FlashUpdate updater(name);
+ FlashUpdate updater(name, "");
updater.start(THIRTYTWO_MIB);
EXPECT_TRUE(updater.flashData(2, bytes));
diff --git a/test/flash_flashfinish_unittest.cpp b/test/flash_flashfinish_unittest.cpp
index bdddd5a..e160b29 100644
--- a/test/flash_flashfinish_unittest.cpp
+++ b/test/flash_flashfinish_unittest.cpp
@@ -30,7 +30,7 @@
// Verify that there is sanity checking
std::vector<uint8_t> bytes = {0xaa, 0x55};
- FlashUpdate updater(name);
+ FlashUpdate updater(name, "");
EXPECT_FALSE(updater.flashFinish());
// Verify the file doesn't exist.
@@ -43,7 +43,7 @@
// Verify that under normal usage it closes the file.
std::vector<uint8_t> bytes = {0xaa, 0x55};
- FlashUpdate updater(name);
+ FlashUpdate updater(name, "");
updater.start(THIRTYTWO_MIB);
EXPECT_TRUE(updater.flashFinish());
@@ -59,7 +59,7 @@
// be closed twice.
std::vector<uint8_t> bytes = {0xaa, 0x55};
- FlashUpdate updater(name);
+ FlashUpdate updater(name, "");
updater.start(THIRTYTWO_MIB);
EXPECT_TRUE(updater.flashFinish());
diff --git a/test/flash_hashdata_unittest.cpp b/test/flash_hashdata_unittest.cpp
index f9a3ffa..8d7be77 100644
--- a/test/flash_hashdata_unittest.cpp
+++ b/test/flash_hashdata_unittest.cpp
@@ -35,7 +35,7 @@
std::vector<uint8_t> bytes = {0xaa, 0x55};
- FlashUpdate updater(name, name2);
+ FlashUpdate updater(name, "", name2);
EXPECT_FALSE(updater.hashData(0, bytes));
}
@@ -44,7 +44,7 @@
// Verify the normal use case works.
std::vector<uint8_t> bytes = {0xaa, 0x55};
- FlashUpdate updater(name, name2);
+ FlashUpdate updater(name, "", name2);
EXPECT_TRUE(updater.start(THIRTYTWO_MIB));
EXPECT_TRUE(updater.startHash(THIRTYTWO_MIB));
EXPECT_TRUE(updater.hashData(0, bytes));
@@ -67,7 +67,7 @@
std::vector<uint8_t> bytes = {0xaa, 0x55};
- FlashUpdate updater(name, name2);
+ FlashUpdate updater(name, "", name2);
EXPECT_TRUE(updater.start(THIRTYTWO_MIB));
EXPECT_TRUE(updater.startHash(THIRTYTWO_MIB));
EXPECT_TRUE(updater.hashData(2, bytes));
diff --git a/test/flash_hashfinish_unittest.cpp b/test/flash_hashfinish_unittest.cpp
index de785ae..12ff7a8 100644
--- a/test/flash_hashfinish_unittest.cpp
+++ b/test/flash_hashfinish_unittest.cpp
@@ -33,7 +33,7 @@
// Verify that there is sanity checking
std::vector<uint8_t> bytes = {0xaa, 0x55};
- FlashUpdate updater(name, name2);
+ FlashUpdate updater(name, "", name2);
EXPECT_FALSE(updater.hashFinish());
// Verify the file doesn't exist.
@@ -46,7 +46,7 @@
// Verify that under normal usage it closes the file.
std::vector<uint8_t> bytes = {0xaa, 0x55};
- FlashUpdate updater(name, name2);
+ FlashUpdate updater(name, "", name2);
EXPECT_TRUE(updater.start(THIRTYTWO_MIB));
EXPECT_TRUE(updater.startHash(THIRTYTWO_MIB));
EXPECT_TRUE(updater.hashFinish());
@@ -63,7 +63,7 @@
// be closed twice.
std::vector<uint8_t> bytes = {0xaa, 0x55};
- FlashUpdate updater(name, name2);
+ FlashUpdate updater(name, "", name2);
EXPECT_TRUE(updater.start(THIRTYTWO_MIB));
EXPECT_TRUE(updater.startHash(THIRTYTWO_MIB));
EXPECT_TRUE(updater.hashFinish());
diff --git a/test/flash_hashstart_unittest.cpp b/test/flash_hashstart_unittest.cpp
index a3a1d9f..60f8df1 100644
--- a/test/flash_hashstart_unittest.cpp
+++ b/test/flash_hashstart_unittest.cpp
@@ -13,7 +13,7 @@
std::string name = std::tmpnam(nullptr);
std::string name2 = std::tmpnam(nullptr);
- FlashUpdate updater(name, name2);
+ FlashUpdate updater(name, "", name2);
EXPECT_FALSE(updater.startHash(THIRTYTWO_MIB));
(void)std::remove(name.c_str());
@@ -27,7 +27,7 @@
std::string name = std::tmpnam(nullptr);
std::string name2 = std::tmpnam(nullptr);
- FlashUpdate updater(name, name2);
+ FlashUpdate updater(name, "", name2);
EXPECT_TRUE(updater.start(THIRTYTWO_MIB));
EXPECT_TRUE(updater.startHash(THIRTYTWO_MIB));
diff --git a/test/flash_start_unittest.cpp b/test/flash_start_unittest.cpp
index b287561..81c2d45 100644
--- a/test/flash_start_unittest.cpp
+++ b/test/flash_start_unittest.cpp
@@ -13,7 +13,7 @@
std::string name = std::tmpnam(nullptr);
- FlashUpdate updater(name);
+ FlashUpdate updater(name, "");
updater.start(THIRTYTWO_MIB);
auto file = std::fopen(name.c_str(), "r");
diff --git a/test/ipmi_verifycheck_unittest.cpp b/test/ipmi_verifycheck_unittest.cpp
new file mode 100644
index 0000000..f71155f
--- /dev/null
+++ b/test/ipmi_verifycheck_unittest.cpp
@@ -0,0 +1,32 @@
+#include "ipmi.hpp"
+
+#include "updater_mock.hpp"
+
+#include <gtest/gtest.h>
+
+using ::testing::Return;
+using ::testing::StrictMock;
+
+// ipmid.hpp isn't installed where we can grab it and this value is per BMC
+// SoC.
+#define MAX_IPMI_BUFFER 64
+
+TEST(IpmiCheckVerifyTest, CallPassedOn)
+{
+ // This IPMI handler just bundles the response.
+
+ StrictMock<UpdaterMock> updater;
+
+ size_t dataLen;
+ uint8_t request[MAX_IPMI_BUFFER] = {0};
+ uint8_t reply[MAX_IPMI_BUFFER] = {0};
+
+ dataLen = 1; // request is only the command.
+ request[0] = FlashSubCmds::flashVerifyCheck;
+
+ EXPECT_CALL(updater, checkVerify())
+ .WillOnce(Return(VerifyCheckResponse::running));
+ EXPECT_EQ(IPMI_CC_OK, checkVerify(&updater, request, reply, &dataLen));
+ EXPECT_EQ(sizeof(uint8_t), dataLen);
+ EXPECT_EQ(VerifyCheckResponse::running, reply[0]);
+}
diff --git a/test/updater_mock.hpp b/test/updater_mock.hpp
index 589df39..0fd6683 100644
--- a/test/updater_mock.hpp
+++ b/test/updater_mock.hpp
@@ -18,4 +18,5 @@
MOCK_METHOD0(hashFinish, bool());
MOCK_METHOD0(startDataVerification, bool());
MOCK_METHOD0(abortUpdate, bool());
+ MOCK_METHOD0(checkVerify, VerifyCheckResponse());
};