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 <bootimg.h> 38 #include <inttypes.h> 39 #include <sparse/sparse.h> 40 41 #include "constants.h" 42 #include "transport.h" 43 44 class Transport; 45 46 namespace fastboot { 47 48 enum RetCode : int { 49 SUCCESS = 0, 50 BAD_ARG, 51 IO_ERROR, 52 BAD_DEV_RESP, 53 DEVICE_FAIL, 54 TIMEOUT, 55 }; 56 57 struct DriverCallbacks { 58 std::function<void(const std::string&)> prolog = [](const std::string&) {}; 59 std::function<void(int)> epilog = [](int) {}; 60 std::function<void(const std::string&)> info = [](const std::string&) {}; 61 }; 62 63 class FastBootDriver { 64 friend class FastBootTest; 65 66 public: 67 static constexpr int RESP_TIMEOUT = 30; // 30 seconds 68 static constexpr uint32_t MAX_DOWNLOAD_SIZE = std::numeric_limits<uint32_t>::max(); 69 static constexpr size_t TRANSPORT_CHUNK_SIZE = 1024; 70 71 FastBootDriver(Transport* transport, DriverCallbacks driver_callbacks = {}, 72 bool no_checks = false); 73 ~FastBootDriver(); 74 75 RetCode Boot(std::string* response = nullptr, std::vector<std::string>* info = nullptr); 76 RetCode Continue(std::string* response = nullptr, std::vector<std::string>* info = nullptr); 77 RetCode CreatePartition(const std::string& partition, const std::string& size); 78 RetCode DeletePartition(const std::string& partition); 79 RetCode Download(const std::string& name, int fd, size_t size, std::string* response = nullptr, 80 std::vector<std::string>* info = nullptr); 81 RetCode Download(int fd, size_t size, std::string* response = nullptr, 82 std::vector<std::string>* info = nullptr); 83 RetCode Download(const std::string& name, const std::vector<char>& buf, 84 std::string* response = nullptr, std::vector<std::string>* info = nullptr); 85 RetCode Download(const std::vector<char>& buf, std::string* response = nullptr, 86 std::vector<std::string>* info = nullptr); 87 RetCode Download(const std::string& partition, struct sparse_file* s, uint32_t sz, 88 size_t current, size_t total, bool use_crc, std::string* response = nullptr, 89 std::vector<std::string>* info = nullptr); 90 RetCode Download(sparse_file* s, bool use_crc = false, std::string* response = nullptr, 91 std::vector<std::string>* info = nullptr); 92 RetCode Erase(const std::string& partition, std::string* response = nullptr, 93 std::vector<std::string>* info = nullptr); 94 RetCode Flash(const std::string& partition, std::string* response = nullptr, 95 std::vector<std::string>* info = nullptr); 96 RetCode GetVar(const std::string& key, std::string* val, 97 std::vector<std::string>* info = nullptr); 98 RetCode GetVarAll(std::vector<std::string>* response); 99 RetCode Reboot(std::string* response = nullptr, std::vector<std::string>* info = nullptr); 100 RetCode RebootTo(std::string target, std::string* response = nullptr, 101 std::vector<std::string>* info = nullptr); 102 RetCode ResizePartition(const std::string& partition, const std::string& size); 103 RetCode SetActive(const std::string& slot, std::string* response = nullptr, 104 std::vector<std::string>* info = nullptr); 105 RetCode Upload(const std::string& outfile, std::string* response = nullptr, 106 std::vector<std::string>* info = nullptr); 107 108 /* HIGHER LEVEL COMMANDS -- Composed of the commands above */ 109 RetCode FlashPartition(const std::string& partition, const std::vector<char>& data); 110 RetCode FlashPartition(const std::string& partition, int fd, uint32_t sz); 111 RetCode FlashPartition(const std::string& partition, sparse_file* s, uint32_t sz, 112 size_t current, size_t total); 113 114 RetCode Partitions(std::vector<std::tuple<std::string, uint64_t>>* partitions); 115 RetCode Require(const std::string& var, const std::vector<std::string>& allowed, bool* reqmet, 116 bool invert = false); 117 118 /* HELPERS */ 119 void SetInfoCallback(std::function<void(const std::string&)> info); 120 static const std::string RCString(RetCode rc); 121 std::string Error(); 122 RetCode WaitForDisconnect(); 123 124 // Note: set_transport will return the previous transport. 125 Transport* set_transport(Transport* transport); transport()126 Transport* transport() const { return transport_; } 127 128 RetCode RawCommand(const std::string& cmd, const std::string& message, 129 std::string* response = nullptr, std::vector<std::string>* info = nullptr, 130 int* dsize = nullptr); 131 132 RetCode RawCommand(const std::string& cmd, std::string* response = nullptr, 133 std::vector<std::string>* info = nullptr, int* dsize = nullptr); 134 135 protected: 136 RetCode DownloadCommand(uint32_t size, std::string* response = nullptr, 137 std::vector<std::string>* info = nullptr); 138 RetCode HandleResponse(std::string* response = nullptr, 139 std::vector<std::string>* info = nullptr, int* dsize = nullptr); 140 141 std::string ErrnoStr(const std::string& msg); 142 143 Transport* transport_; 144 145 private: 146 RetCode SendBuffer(int fd, size_t size); 147 RetCode SendBuffer(const std::vector<char>& buf); 148 RetCode SendBuffer(const void* buf, size_t size); 149 150 RetCode ReadBuffer(std::vector<char>& buf); 151 RetCode ReadBuffer(void* buf, size_t size); 152 153 RetCode UploadInner(const std::string& outfile, std::string* response = nullptr, 154 std::vector<std::string>* info = nullptr); 155 156 int SparseWriteCallback(std::vector<char>& tpbuf, const char* data, size_t len); 157 158 std::string error_; 159 std::function<void(const std::string&)> prolog_; 160 std::function<void(int)> epilog_; 161 std::function<void(const std::string&)> info_; 162 bool disable_checks_; 163 }; 164 165 } // namespace fastboot 166