fastboot driver: add RunAndReadBuffer helper

Refactor UploadInner and add a new RunAndReadBuffer helper function
that handles the generic procedure of:

1. Sending a command
2. Receiving a DATA response with N bytes
3. Receiving another response

Test: pass
Bug: 173654501

Change-Id: I568bea127315e42d8a111c23602fc582e7bc935b
This commit is contained in:
Yifan Hong 2021-02-17 11:16:39 -08:00
parent b10d067e0c
commit bbf374dbd7
2 changed files with 33 additions and 23 deletions

View file

@ -297,41 +297,54 @@ RetCode FastBootDriver::Upload(const std::string& outfile, std::string* response
return result;
}
RetCode FastBootDriver::UploadInner(const std::string& outfile, std::string* response,
std::vector<std::string>* info) {
// This function executes cmd, then expect a "DATA" response with a number N, followed
// by N bytes, and another response.
// This is the common way for the device to send data to the driver used by upload and fetch.
RetCode FastBootDriver::RunAndReadBuffer(
const std::string& cmd, std::string* response, std::vector<std::string>* info,
const std::function<RetCode(const char* data, uint64_t size)>& write_fn) {
RetCode ret;
int dsize = 0;
if ((ret = RawCommand(FB_CMD_UPLOAD, response, info, &dsize))) {
error_ = "Upload request failed: " + error_;
if ((ret = RawCommand(cmd, response, info, &dsize))) {
error_ = android::base::StringPrintf("%s request failed: %s", cmd.c_str(), error_.c_str());
return ret;
}
if (!dsize) {
error_ = "Upload request failed, device reports 0 bytes available";
if (dsize <= 0) {
error_ = android::base::StringPrintf("%s request failed, device reports %d bytes available",
cmd.c_str(), dsize);
return BAD_DEV_RESP;
}
std::vector<char> data;
data.resize(dsize);
if ((ret = ReadBuffer(data))) {
std::vector<char> data(dsize);
if ((ret = ReadBuffer(data.data(), data.size())) != SUCCESS) {
return ret;
}
if ((ret = write_fn(data.data(), data.size())) != SUCCESS) {
return ret;
}
return HandleResponse(response, info);
}
RetCode FastBootDriver::UploadInner(const std::string& outfile, std::string* response,
std::vector<std::string>* info) {
std::ofstream ofs;
ofs.open(outfile, std::ofstream::out | std::ofstream::binary);
if (ofs.fail()) {
error_ = android::base::StringPrintf("Failed to open '%s'", outfile.c_str());
return IO_ERROR;
}
ofs.write(data.data(), data.size());
if (ofs.fail() || ofs.bad()) {
error_ = android::base::StringPrintf("Writing to '%s' failed", outfile.c_str());
return IO_ERROR;
}
auto write_fn = [&](const char* data, uint64_t size) {
ofs.write(data, size);
if (ofs.fail() || ofs.bad()) {
error_ = android::base::StringPrintf("Writing to '%s' failed", outfile.c_str());
return IO_ERROR;
}
return SUCCESS;
};
RetCode ret = RunAndReadBuffer(FB_CMD_UPLOAD, response, info, write_fn);
ofs.close();
return HandleResponse(response, info);
return ret;
}
// Helpers
@ -524,11 +537,6 @@ RetCode FastBootDriver::SendBuffer(const void* buf, size_t size) {
return SUCCESS;
}
RetCode FastBootDriver::ReadBuffer(std::vector<char>& buf) {
// Read the buffer
return ReadBuffer(buf.data(), buf.size());
}
RetCode FastBootDriver::ReadBuffer(void* buf, size_t size) {
// Read the buffer
ssize_t tmp = transport_->Read(buf, size);

View file

@ -149,11 +149,13 @@ class FastBootDriver {
RetCode SendBuffer(const std::vector<char>& buf);
RetCode SendBuffer(const void* buf, size_t size);
RetCode ReadBuffer(std::vector<char>& buf);
RetCode ReadBuffer(void* buf, size_t size);
RetCode UploadInner(const std::string& outfile, std::string* response = nullptr,
std::vector<std::string>* info = nullptr);
RetCode RunAndReadBuffer(const std::string& cmd, std::string* response,
std::vector<std::string>* info,
const std::function<RetCode(const char*, uint64_t)>& write_fn);
int SparseWriteCallback(std::vector<char>& tpbuf, const char* data, size_t len);