Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bbf374db authored by Yifan Hong's avatar Yifan Hong
Browse files

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
parent b10d067e
Loading
Loading
Loading
Loading
+30 −22
Original line number Diff line number Diff line
@@ -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());
    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);
+3 −1
Original line number Diff line number Diff line
@@ -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);