Merge "Fastboot: Add new TEXT message to protocol to handle long lines."
This commit is contained in:
commit
368a908334
7 changed files with 71 additions and 12 deletions
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -255,6 +255,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<char>* out) {
|
||||
out->clear();
|
||||
|
||||
|
|
@ -2305,7 +2309,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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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<std::s
|
|||
error_ = android::base::StringPrintf("remote: '%s'", status + strlen("FAIL"));
|
||||
set_response(input.substr(strlen("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")) {
|
||||
std::string tmp = input.substr(strlen("DATA"));
|
||||
uint32_t num = strtol(tmp.c_str(), 0, 16);
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ struct DriverCallbacks {
|
|||
std::function<void(const std::string&)> prolog = [](const std::string&) {};
|
||||
std::function<void(int)> epilog = [](int) {};
|
||||
std::function<void(const std::string&)> info = [](const std::string&) {};
|
||||
std::function<void(const std::string&)> text = [](const std::string&) {};
|
||||
};
|
||||
|
||||
class FastBootDriver {
|
||||
|
|
@ -169,6 +170,7 @@ class FastBootDriver {
|
|||
std::function<void(const std::string&)> prolog_;
|
||||
std::function<void(int)> epilog_;
|
||||
std::function<void(const std::string&)> info_;
|
||||
std::function<void(const std::string&)> text_;
|
||||
bool disable_checks_;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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<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?");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue