1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in 12 * the documentation and/or other materials provided with the 13 * distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 #pragma once 29 #include <cstdlib> 30 #include <deque> 31 #include <limits> 32 #include <string> 33 #include <vector> 34 35 #include <android-base/logging.h> 36 #include <android-base/stringprintf.h> 37 #include <android-base/unique_fd.h> 38 #include <bootimg.h> 39 #include <inttypes.h> 40 #include <sparse/sparse.h> 41 42 #include "constants.h" 43 #include "transport.h" 44 45 class Transport; 46 47 namespace fastboot { 48 49 enum RetCode : int { 50 SUCCESS = 0, 51 BAD_ARG, 52 IO_ERROR, 53 BAD_DEV_RESP, 54 DEVICE_FAIL, 55 TIMEOUT, 56 }; 57 58 struct DriverCallbacks { 59 std::function<void(const std::string&)> prolog = [](const std::string&) {}; 60 std::function<void(int)> epilog = [](int) {}; 61 std::function<void(const std::string&)> info = [](const std::string&) {}; 62 }; 63 64 class FastBootDriver { 65 friend class FastBootTest; 66 67 public: 68 static constexpr int RESP_TIMEOUT = 30; // 30 seconds 69 static constexpr uint32_t MAX_DOWNLOAD_SIZE = std::numeric_limits<uint32_t>::max(); 70 static constexpr size_t TRANSPORT_CHUNK_SIZE = 1024; 71 72 FastBootDriver(Transport* transport, DriverCallbacks driver_callbacks = {}, 73 bool no_checks = false); 74 ~FastBootDriver(); 75 76 RetCode Boot(std::string* response = nullptr, std::vector<std::string>* info = nullptr); 77 RetCode Continue(std::string* response = nullptr, std::vector<std::string>* info = nullptr); 78 RetCode CreatePartition(const std::string& partition, const std::string& size); 79 RetCode DeletePartition(const std::string& partition); 80 RetCode Download(const std::string& name, android::base::borrowed_fd fd, size_t size, 81 std::string* response = nullptr, std::vector<std::string>* info = nullptr); 82 RetCode Download(android::base::borrowed_fd fd, size_t size, std::string* response = nullptr, 83 std::vector<std::string>* info = nullptr); 84 RetCode Download(const std::string& name, const std::vector<char>& buf, 85 std::string* response = nullptr, std::vector<std::string>* info = nullptr); 86 RetCode Download(const std::vector<char>& buf, std::string* response = nullptr, 87 std::vector<std::string>* info = nullptr); 88 RetCode Download(const std::string& partition, struct sparse_file* s, uint32_t sz, 89 size_t current, size_t total, bool use_crc, std::string* response = nullptr, 90 std::vector<std::string>* info = nullptr); 91 RetCode Download(sparse_file* s, bool use_crc = false, std::string* response = nullptr, 92 std::vector<std::string>* info = nullptr); 93 RetCode Erase(const std::string& partition, std::string* response = nullptr, 94 std::vector<std::string>* info = nullptr); 95 RetCode Flash(const std::string& partition, std::string* response = nullptr, 96 std::vector<std::string>* info = nullptr); 97 RetCode GetVar(const std::string& key, std::string* val, 98 std::vector<std::string>* info = nullptr); 99 RetCode GetVarAll(std::vector<std::string>* response); 100 RetCode Reboot(std::string* response = nullptr, std::vector<std::string>* info = nullptr); 101 RetCode RebootTo(std::string target, std::string* response = nullptr, 102 std::vector<std::string>* info = nullptr); 103 RetCode ResizePartition(const std::string& partition, const std::string& size); 104 RetCode SetActive(const std::string& slot, std::string* response = nullptr, 105 std::vector<std::string>* info = nullptr); 106 RetCode Upload(const std::string& outfile, std::string* response = nullptr, 107 std::vector<std::string>* info = nullptr); 108 RetCode SnapshotUpdateCommand(const std::string& command, std::string* response = nullptr, 109 std::vector<std::string>* info = nullptr); 110 RetCode FetchToFd(const std::string& partition, android::base::borrowed_fd fd, 111 int64_t offset = -1, int64_t size = -1, std::string* response = nullptr, 112 std::vector<std::string>* info = nullptr); 113 114 /* HIGHER LEVEL COMMANDS -- Composed of the commands above */ 115 RetCode FlashPartition(const std::string& partition, const std::vector<char>& data); 116 RetCode FlashPartition(const std::string& partition, android::base::borrowed_fd fd, 117 uint32_t sz); 118 RetCode FlashPartition(const std::string& partition, sparse_file* s, uint32_t sz, 119 size_t current, size_t total); 120 121 RetCode Partitions(std::vector<std::tuple<std::string, uint64_t>>* partitions); 122 RetCode Require(const std::string& var, const std::vector<std::string>& allowed, bool* reqmet, 123 bool invert = false); 124 125 /* HELPERS */ 126 void SetInfoCallback(std::function<void(const std::string&)> info); 127 static const std::string RCString(RetCode rc); 128 std::string Error(); 129 RetCode WaitForDisconnect(); 130 131 // Note: set_transport will return the previous transport. 132 Transport* set_transport(Transport* transport); transport()133 Transport* transport() const { return transport_; } 134 135 RetCode RawCommand(const std::string& cmd, const std::string& message, 136 std::string* response = nullptr, std::vector<std::string>* info = nullptr, 137 int* dsize = nullptr); 138 139 RetCode RawCommand(const std::string& cmd, std::string* response = nullptr, 140 std::vector<std::string>* info = nullptr, int* dsize = nullptr); 141 142 protected: 143 RetCode DownloadCommand(uint32_t size, std::string* response = nullptr, 144 std::vector<std::string>* info = nullptr); 145 RetCode HandleResponse(std::string* response = nullptr, 146 std::vector<std::string>* info = nullptr, int* dsize = nullptr); 147 148 std::string ErrnoStr(const std::string& msg); 149 150 Transport* transport_; 151 152 private: 153 RetCode SendBuffer(android::base::borrowed_fd fd, size_t size); 154 RetCode SendBuffer(const std::vector<char>& buf); 155 RetCode SendBuffer(const void* buf, size_t size); 156 157 RetCode ReadBuffer(void* buf, size_t size); 158 159 RetCode UploadInner(const std::string& outfile, std::string* response = nullptr, 160 std::vector<std::string>* info = nullptr); 161 RetCode RunAndReadBuffer(const std::string& cmd, std::string* response, 162 std::vector<std::string>* info, 163 const std::function<RetCode(const char*, uint64_t)>& write_fn); 164 165 int SparseWriteCallback(std::vector<char>& tpbuf, const char* data, size_t len); 166 167 std::string error_; 168 std::function<void(const std::string&)> prolog_; 169 std::function<void(int)> epilog_; 170 std::function<void(const std::string&)> info_; 171 bool disable_checks_; 172 }; 173 174 } // namespace fastboot 175