Loading fastboot/README.md +19 −10 Original line number Original line Diff line number Diff line Loading @@ -29,20 +29,27 @@ Linux, macOS, or Windows. 2. Client response with a single packet no greater than 256 bytes. 2. Client response with a single packet no greater than 256 bytes. The first four bytes of the response are "OKAY", "FAIL", "DATA", 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. message. a. INFO -> the remaining 252 bytes are an informative message a. INFO -> the remaining 252 bytes are an informative message (providing progress or diagnostic messages). They should (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 of the response (if present) provide a textual failure message to present to the user. Stop. 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 A DATA response packet will be 12 bytes long, in the form of DATA00000000 where the 8 digit hexadecimal number represents DATA00000000 where the 8 digit hexadecimal number represents the total data size to transfer. the total data size to transfer. Loading @@ -54,15 +61,17 @@ Linux, macOS, or Windows. in the "DATA" response above. in the "DATA" response above. 4. Client responds with a single packet no greater than 256 bytes. 4. Client responds with a single packet no greater than 256 bytes. The first four bytes of the response are "OKAY", "FAIL", or "INFO". The first four bytes of the response are "OKAY", "FAIL", Similar to #2: "INFO" or "TEXT". Similar to #2: a. INFO -> display the formatted remaining 252 bytes and return to #4 a. INFO -> display the remaining 252 bytes and return to #4 b. TEXT -> display the unformatted remaining 252 bytes and return to #4 b. FAIL -> display the remaining 252 bytes (if present) as a failure c. FAIL -> display the remaining 252 bytes (if present) as a failure reason and consider the command failed. Stop. reason and consider the command failed. Stop. c. OKAY -> success. Go to #5 d. OKAY -> success. Go to #5 5. Success. Stop. 5. Success. Stop. Loading fastboot/fastboot.cpp +6 −0 Original line number Original line Diff line number Diff line Loading @@ -255,6 +255,10 @@ static void InfoMessage(const std::string& info) { fprintf(stderr, "(bootloader) %s\n", info.c_str()); 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<char>* out) { bool ReadFileToVector(const std::string& file, std::vector<char>* out) { out->clear(); out->clear(); Loading Loading @@ -2305,7 +2309,9 @@ int FastBootTool::Main(int argc, char* argv[]) { .prolog = Status, .prolog = Status, .epilog = Epilog, .epilog = Epilog, .info = InfoMessage, .info = InfoMessage, .text = TextMessage, }; }; fastboot::FastBootDriver fastboot_driver(transport, driver_callbacks, false); fastboot::FastBootDriver fastboot_driver(transport, driver_callbacks, false); fb = &fastboot_driver; fb = &fastboot_driver; Loading fastboot/fastboot_driver.cpp +5 −0 Original line number Original line Diff line number Diff line Loading @@ -64,6 +64,7 @@ FastBootDriver::FastBootDriver(Transport* transport, DriverCallbacks driver_call prolog_(std::move(driver_callbacks.prolog)), prolog_(std::move(driver_callbacks.prolog)), epilog_(std::move(driver_callbacks.epilog)), epilog_(std::move(driver_callbacks.epilog)), info_(std::move(driver_callbacks.info)), info_(std::move(driver_callbacks.info)), text_(std::move(driver_callbacks.text)), disable_checks_(no_checks) {} disable_checks_(no_checks) {} FastBootDriver::~FastBootDriver() { FastBootDriver::~FastBootDriver() { Loading Loading @@ -498,6 +499,10 @@ RetCode FastBootDriver::HandleResponse(std::string* response, std::vector<std::s error_ = android::base::StringPrintf("remote: '%s'", status + strlen("FAIL")); error_ = android::base::StringPrintf("remote: '%s'", status + strlen("FAIL")); set_response(input.substr(strlen("FAIL"))); set_response(input.substr(strlen("FAIL"))); return DEVICE_FAIL; return DEVICE_FAIL; } else if (android::base::StartsWith(input, "TEXT")) { text_(input.substr(strlen("TEXT"))); // Reset timeout as many more TEXT may come start = std::chrono::steady_clock::now(); } else if (android::base::StartsWith(input, "DATA")) { } else if (android::base::StartsWith(input, "DATA")) { std::string tmp = input.substr(strlen("DATA")); std::string tmp = input.substr(strlen("DATA")); uint32_t num = strtol(tmp.c_str(), 0, 16); uint32_t num = strtol(tmp.c_str(), 0, 16); Loading fastboot/fastboot_driver.h +2 −0 Original line number Original line Diff line number Diff line Loading @@ -60,6 +60,7 @@ struct DriverCallbacks { std::function<void(const std::string&)> prolog = [](const std::string&) {}; std::function<void(const std::string&)> prolog = [](const std::string&) {}; std::function<void(int)> epilog = [](int) {}; std::function<void(int)> epilog = [](int) {}; std::function<void(const std::string&)> info = [](const std::string&) {}; std::function<void(const std::string&)> info = [](const std::string&) {}; std::function<void(const std::string&)> text = [](const std::string&) {}; }; }; class FastBootDriver { class FastBootDriver { Loading Loading @@ -169,6 +170,7 @@ class FastBootDriver { std::function<void(const std::string&)> prolog_; std::function<void(const std::string&)> prolog_; std::function<void(int)> epilog_; std::function<void(int)> epilog_; std::function<void(const std::string&)> info_; std::function<void(const std::string&)> info_; std::function<void(const std::string&)> text_; bool disable_checks_; bool disable_checks_; }; }; Loading fastboot/fastboot_driver_test.cpp +35 −0 Original line number Original line Diff line number Diff line Loading @@ -58,3 +58,38 @@ TEST_F(DriverTest, InfoMessage) { ASSERT_EQ(info.size(), size_t(1)); ASSERT_EQ(info.size(), size_t(1)); ASSERT_EQ(info[0], "this is an info line"); 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<std::string> 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?"); } Loading
fastboot/README.md +19 −10 Original line number Original line Diff line number Diff line Loading @@ -29,20 +29,27 @@ Linux, macOS, or Windows. 2. Client response with a single packet no greater than 256 bytes. 2. Client response with a single packet no greater than 256 bytes. The first four bytes of the response are "OKAY", "FAIL", "DATA", 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. message. a. INFO -> the remaining 252 bytes are an informative message a. INFO -> the remaining 252 bytes are an informative message (providing progress or diagnostic messages). They should (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 of the response (if present) provide a textual failure message to present to the user. Stop. 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 A DATA response packet will be 12 bytes long, in the form of DATA00000000 where the 8 digit hexadecimal number represents DATA00000000 where the 8 digit hexadecimal number represents the total data size to transfer. the total data size to transfer. Loading @@ -54,15 +61,17 @@ Linux, macOS, or Windows. in the "DATA" response above. in the "DATA" response above. 4. Client responds with a single packet no greater than 256 bytes. 4. Client responds with a single packet no greater than 256 bytes. The first four bytes of the response are "OKAY", "FAIL", or "INFO". The first four bytes of the response are "OKAY", "FAIL", Similar to #2: "INFO" or "TEXT". Similar to #2: a. INFO -> display the formatted remaining 252 bytes and return to #4 a. INFO -> display the remaining 252 bytes and return to #4 b. TEXT -> display the unformatted remaining 252 bytes and return to #4 b. FAIL -> display the remaining 252 bytes (if present) as a failure c. FAIL -> display the remaining 252 bytes (if present) as a failure reason and consider the command failed. Stop. reason and consider the command failed. Stop. c. OKAY -> success. Go to #5 d. OKAY -> success. Go to #5 5. Success. Stop. 5. Success. Stop. Loading
fastboot/fastboot.cpp +6 −0 Original line number Original line Diff line number Diff line Loading @@ -255,6 +255,10 @@ static void InfoMessage(const std::string& info) { fprintf(stderr, "(bootloader) %s\n", info.c_str()); 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<char>* out) { bool ReadFileToVector(const std::string& file, std::vector<char>* out) { out->clear(); out->clear(); Loading Loading @@ -2305,7 +2309,9 @@ int FastBootTool::Main(int argc, char* argv[]) { .prolog = Status, .prolog = Status, .epilog = Epilog, .epilog = Epilog, .info = InfoMessage, .info = InfoMessage, .text = TextMessage, }; }; fastboot::FastBootDriver fastboot_driver(transport, driver_callbacks, false); fastboot::FastBootDriver fastboot_driver(transport, driver_callbacks, false); fb = &fastboot_driver; fb = &fastboot_driver; Loading
fastboot/fastboot_driver.cpp +5 −0 Original line number Original line Diff line number Diff line Loading @@ -64,6 +64,7 @@ FastBootDriver::FastBootDriver(Transport* transport, DriverCallbacks driver_call prolog_(std::move(driver_callbacks.prolog)), prolog_(std::move(driver_callbacks.prolog)), epilog_(std::move(driver_callbacks.epilog)), epilog_(std::move(driver_callbacks.epilog)), info_(std::move(driver_callbacks.info)), info_(std::move(driver_callbacks.info)), text_(std::move(driver_callbacks.text)), disable_checks_(no_checks) {} disable_checks_(no_checks) {} FastBootDriver::~FastBootDriver() { FastBootDriver::~FastBootDriver() { Loading Loading @@ -498,6 +499,10 @@ RetCode FastBootDriver::HandleResponse(std::string* response, std::vector<std::s error_ = android::base::StringPrintf("remote: '%s'", status + strlen("FAIL")); error_ = android::base::StringPrintf("remote: '%s'", status + strlen("FAIL")); set_response(input.substr(strlen("FAIL"))); set_response(input.substr(strlen("FAIL"))); return DEVICE_FAIL; return DEVICE_FAIL; } else if (android::base::StartsWith(input, "TEXT")) { text_(input.substr(strlen("TEXT"))); // Reset timeout as many more TEXT may come start = std::chrono::steady_clock::now(); } else if (android::base::StartsWith(input, "DATA")) { } else if (android::base::StartsWith(input, "DATA")) { std::string tmp = input.substr(strlen("DATA")); std::string tmp = input.substr(strlen("DATA")); uint32_t num = strtol(tmp.c_str(), 0, 16); uint32_t num = strtol(tmp.c_str(), 0, 16); Loading
fastboot/fastboot_driver.h +2 −0 Original line number Original line Diff line number Diff line Loading @@ -60,6 +60,7 @@ struct DriverCallbacks { std::function<void(const std::string&)> prolog = [](const std::string&) {}; std::function<void(const std::string&)> prolog = [](const std::string&) {}; std::function<void(int)> epilog = [](int) {}; std::function<void(int)> epilog = [](int) {}; std::function<void(const std::string&)> info = [](const std::string&) {}; std::function<void(const std::string&)> info = [](const std::string&) {}; std::function<void(const std::string&)> text = [](const std::string&) {}; }; }; class FastBootDriver { class FastBootDriver { Loading Loading @@ -169,6 +170,7 @@ class FastBootDriver { std::function<void(const std::string&)> prolog_; std::function<void(const std::string&)> prolog_; std::function<void(int)> epilog_; std::function<void(int)> epilog_; std::function<void(const std::string&)> info_; std::function<void(const std::string&)> info_; std::function<void(const std::string&)> text_; bool disable_checks_; bool disable_checks_; }; }; Loading
fastboot/fastboot_driver_test.cpp +35 −0 Original line number Original line Diff line number Diff line Loading @@ -58,3 +58,38 @@ TEST_F(DriverTest, InfoMessage) { ASSERT_EQ(info.size(), size_t(1)); ASSERT_EQ(info.size(), size_t(1)); ASSERT_EQ(info[0], "this is an info line"); 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<std::string> 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?"); }