From 99097cc020a92bff3c6546a486db274096238271 Mon Sep 17 00:00:00 2001 From: Raphael Herouart Date: Fri, 30 Dec 2022 11:51:54 +0000 Subject: [PATCH] Fastboot: Add new TEXT message to protocol to handle long lines. Trusty Benchmarks need to be evaluated in ABL which is much more controlled than linux. However fastboot prints evry atomic message from trusty/abl on its own line starting with "(bootloader)" Bug: 263454481 Test: - "fastboot oem trusty runtest trusty.hwrng.bench" Change-Id: I99847a8cc54457c8ec809e219736325dce0ac891 --- fastboot/README.md | 29 +++++++++++++-------- fastboot/fastboot.cpp | 6 +++++ fastboot/fastboot_driver.cpp | 5 ++++ fastboot/fastboot_driver.h | 2 ++ fastboot/fastboot_driver_test.cpp | 35 ++++++++++++++++++++++++++ trusty/libtrusty/tipc-test/tipc_test.c | 3 ++- trusty/utils/trusty-ut-ctrl/ut-ctrl.c | 3 ++- 7 files changed, 71 insertions(+), 12 deletions(-) diff --git a/fastboot/README.md b/fastboot/README.md index d3b6c1ae7..63db5c38b 100644 --- a/fastboot/README.md +++ b/fastboot/README.md @@ -29,20 +29,27 @@ Linux, macOS, or Windows. 2. Client response with a single packet no greater than 256 bytes. The first four bytes of the response are "OKAY", "FAIL", "DATA", - or "INFO". Additional bytes may contain an (ascii) informative + "INFO" or "TEXT". Additional bytes may contain an (ascii) informative message. a. INFO -> the remaining 252 bytes are an informative message (providing progress or diagnostic messages). They should - be displayed and then step #2 repeats + be displayed and then step #2 repeats. The print format is: + "(bootloader) " + InfoMessagePayload + '\n' - b. FAIL -> the requested command failed. The remaining 252 bytes + b. TEXT -> the remaining 252 bytes are arbitrary. They should + be displayed and then step #2 repeats. + It differs from info in that no formatting is applied. + The payload is printed as-is with no newline at the end. + Payload is expected to be NULL terminated. + + c. FAIL -> the requested command failed. The remaining 252 bytes of the response (if present) provide a textual failure message to present to the user. Stop. - c. OKAY -> the requested command completed successfully. Go to #5 + d. OKAY -> the requested command completed successfully. Go to #5 - d. DATA -> the requested command is ready for the data phase. + e. DATA -> the requested command is ready for the data phase. A DATA response packet will be 12 bytes long, in the form of DATA00000000 where the 8 digit hexadecimal number represents the total data size to transfer. @@ -54,15 +61,17 @@ Linux, macOS, or Windows. in the "DATA" response above. 4. Client responds with a single packet no greater than 256 bytes. - The first four bytes of the response are "OKAY", "FAIL", or "INFO". - Similar to #2: + The first four bytes of the response are "OKAY", "FAIL", + "INFO" or "TEXT". Similar to #2: - a. INFO -> display the remaining 252 bytes and return to #4 + a. INFO -> display the formatted remaining 252 bytes and return to #4 - b. FAIL -> display the remaining 252 bytes (if present) as a failure + b. TEXT -> display the unformatted remaining 252 bytes and return to #4 + + c. FAIL -> display the remaining 252 bytes (if present) as a failure reason and consider the command failed. Stop. - c. OKAY -> success. Go to #5 + d. OKAY -> success. Go to #5 5. Success. Stop. diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp index 0c8747c06..a30b10cd6 100644 --- a/fastboot/fastboot.cpp +++ b/fastboot/fastboot.cpp @@ -251,6 +251,10 @@ static void InfoMessage(const std::string& info) { fprintf(stderr, "(bootloader) %s\n", info.c_str()); } +static void TextMessage(const std::string& text) { + fprintf(stderr, "%s", text.c_str()); +} + bool ReadFileToVector(const std::string& file, std::vector* out) { out->clear(); @@ -2303,7 +2307,9 @@ int FastBootTool::Main(int argc, char* argv[]) { .prolog = Status, .epilog = Epilog, .info = InfoMessage, + .text = TextMessage, }; + fastboot::FastBootDriver fastboot_driver(transport, driver_callbacks, false); fb = &fastboot_driver; diff --git a/fastboot/fastboot_driver.cpp b/fastboot/fastboot_driver.cpp index 99a48734c..9770ab25c 100644 --- a/fastboot/fastboot_driver.cpp +++ b/fastboot/fastboot_driver.cpp @@ -64,6 +64,7 @@ FastBootDriver::FastBootDriver(Transport* transport, DriverCallbacks driver_call prolog_(std::move(driver_callbacks.prolog)), epilog_(std::move(driver_callbacks.epilog)), info_(std::move(driver_callbacks.info)), + text_(std::move(driver_callbacks.text)), disable_checks_(no_checks) {} FastBootDriver::~FastBootDriver() { @@ -498,6 +499,10 @@ RetCode FastBootDriver::HandleResponse(std::string* response, std::vector prolog = [](const std::string&) {}; std::function epilog = [](int) {}; std::function info = [](const std::string&) {}; + std::function text = [](const std::string&) {}; }; class FastBootDriver { @@ -169,6 +170,7 @@ class FastBootDriver { std::function prolog_; std::function epilog_; std::function info_; + std::function text_; bool disable_checks_; }; diff --git a/fastboot/fastboot_driver_test.cpp b/fastboot/fastboot_driver_test.cpp index e874c3a87..6f6cf8c49 100644 --- a/fastboot/fastboot_driver_test.cpp +++ b/fastboot/fastboot_driver_test.cpp @@ -58,3 +58,38 @@ TEST_F(DriverTest, InfoMessage) { ASSERT_EQ(info.size(), size_t(1)); ASSERT_EQ(info[0], "this is an info line"); } + +TEST_F(DriverTest, TextMessage) { + MockTransport transport; + std::string text; + + DriverCallbacks callbacks{[](const std::string&) {}, [](int) {}, [](const std::string&) {}, + [&text](const std::string& extra_text) { text += extra_text; }}; + + FastBootDriver driver(&transport, callbacks); + + EXPECT_CALL(transport, Write(_, _)) + .With(AllArgs(RawData("oem trusty runtest trusty.hwaes.bench"))) + .WillOnce(ReturnArg<1>()); + EXPECT_CALL(transport, Read(_, _)).WillOnce(Invoke(CopyData("TEXTthis is a text line"))); + EXPECT_CALL(transport, Read(_, _)) + .WillOnce(Invoke( + CopyData("TEXT, albeit very long and split over multiple TEXT messages."))); + EXPECT_CALL(transport, Read(_, _)) + .WillOnce(Invoke(CopyData("TEXT Indeed we can do that now with a TEXT message whenever " + "we feel like it."))); + EXPECT_CALL(transport, Read(_, _)) + .WillOnce(Invoke(CopyData("TEXT Isn't that truly super cool?"))); + + EXPECT_CALL(transport, Read(_, _)).WillOnce(Invoke(CopyData("OKAY"))); + + std::vector info; + ASSERT_EQ(driver.RawCommand("oem trusty runtest trusty.hwaes.bench", "", nullptr, &info), + SUCCESS) + << driver.Error(); + ASSERT_EQ(text, + "this is a text line" + ", albeit very long and split over multiple TEXT messages." + " Indeed we can do that now with a TEXT message whenever we feel like it." + " Isn't that truly super cool?"); +} diff --git a/trusty/libtrusty/tipc-test/tipc_test.c b/trusty/libtrusty/tipc-test/tipc_test.c index eb0acb5f5..81c988110 100644 --- a/trusty/libtrusty/tipc-test/tipc_test.c +++ b/trusty/libtrusty/tipc-test/tipc_test.c @@ -596,6 +596,7 @@ static int ta2ta_ipc_test(void) TEST_PASSED = 0, TEST_FAILED = 1, TEST_MESSAGE = 2, + TEST_TEXT = 3, }; int fd; @@ -625,7 +626,7 @@ static int ta2ta_ipc_test(void) break; } else if (rx_buf[0] == TEST_FAILED) { break; - } else if (rx_buf[0] == TEST_MESSAGE) { + } else if (rx_buf[0] == TEST_MESSAGE || rx_buf[0] == TEST_TEXT) { write(STDOUT_FILENO, rx_buf + 1, ret - 1); } else { fprintf(stderr, "%s: Bad message header: %d\n", __func__, rx_buf[0]); diff --git a/trusty/utils/trusty-ut-ctrl/ut-ctrl.c b/trusty/utils/trusty-ut-ctrl/ut-ctrl.c index 9e72af3d5..6cc66707e 100644 --- a/trusty/utils/trusty-ut-ctrl/ut-ctrl.c +++ b/trusty/utils/trusty-ut-ctrl/ut-ctrl.c @@ -94,6 +94,7 @@ enum test_message_header { TEST_PASSED = 0, TEST_FAILED = 1, TEST_MESSAGE = 2, + TEST_TEXT = 3, }; static int run_trusty_unitest(const char* utapp) { @@ -121,7 +122,7 @@ static int run_trusty_unitest(const char* utapp) { break; } else if (rx_buf[0] == TEST_FAILED) { break; - } else if (rx_buf[0] == TEST_MESSAGE) { + } else if (rx_buf[0] == TEST_MESSAGE || rx_buf[0] == TEST_TEXT) { write(STDOUT_FILENO, rx_buf + 1, rc - 1); } else { fprintf(stderr, "%s: Bad message header: %d\n", __func__, rx_buf[0]);