summaryrefslogtreecommitdiff
path: root/fastboot/fastboot.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'fastboot/fastboot.cpp')
-rw-r--r--fastboot/fastboot.cpp144
1 files changed, 75 insertions, 69 deletions
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index 9f72c8336..a16d7dd23 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -55,6 +55,8 @@
#include "bootimg_utils.h"
#include "fastboot.h"
#include "fs.h"
+#include "transport.h"
+#include "usb.h"
#ifndef O_BINARY
#define O_BINARY 0
@@ -222,16 +224,16 @@ static int list_devices_callback(usb_ifc_info* info) {
return -1;
}
-static usb_handle* open_device() {
- static usb_handle *usb = 0;
+static Transport* open_device() {
+ static Transport* transport = nullptr;
int announce = 1;
- if(usb) return usb;
+ if (transport) return transport;
- for(;;) {
- usb = usb_open(match_fastboot);
- if(usb) return usb;
- if(announce) {
+ for (;;) {
+ transport = usb_open(match_fastboot);
+ if (transport) return transport;
+ if (announce) {
announce = 0;
fprintf(stderr, "< waiting for %s >\n", serial ? serial : "any device");
}
@@ -597,9 +599,10 @@ static struct sparse_file **load_sparse_files(int fd, int max_size)
return out_s;
}
-static int64_t get_target_sparse_limit(usb_handle* usb) {
+static int64_t get_target_sparse_limit(Transport* transport) {
std::string max_download_size;
- if (!fb_getvar(usb, "max-download-size", &max_download_size) || max_download_size.empty()) {
+ if (!fb_getvar(transport, "max-download-size", &max_download_size) ||
+ max_download_size.empty()) {
fprintf(stderr, "target didn't report max-download-size\n");
return 0;
}
@@ -618,7 +621,7 @@ static int64_t get_target_sparse_limit(usb_handle* usb) {
return limit;
}
-static int64_t get_sparse_limit(usb_handle* usb, int64_t size) {
+static int64_t get_sparse_limit(Transport* transport, int64_t size) {
int64_t limit;
if (sparse_limit == 0) {
@@ -627,7 +630,7 @@ static int64_t get_sparse_limit(usb_handle* usb, int64_t size) {
limit = sparse_limit;
} else {
if (target_sparse_limit == -1) {
- target_sparse_limit = get_target_sparse_limit(usb);
+ target_sparse_limit = get_target_sparse_limit(transport);
}
if (target_sparse_limit > 0) {
limit = target_sparse_limit;
@@ -646,22 +649,22 @@ static int64_t get_sparse_limit(usb_handle* usb, int64_t size) {
// Until we get lazy inode table init working in make_ext4fs, we need to
// erase partitions of type ext4 before flashing a filesystem so no stale
// inodes are left lying around. Otherwise, e2fsck gets very upset.
-static bool needs_erase(usb_handle* usb, const char* partition) {
+static bool needs_erase(Transport* transport, const char* partition) {
std::string partition_type;
- if (!fb_getvar(usb, std::string("partition-type:") + partition, &partition_type)) {
+ if (!fb_getvar(transport, std::string("partition-type:") + partition, &partition_type)) {
return false;
}
return partition_type == "ext4";
}
-static int load_buf_fd(usb_handle* usb, int fd, struct fastboot_buffer* buf) {
+static int load_buf_fd(Transport* transport, int fd, struct fastboot_buffer* buf) {
int64_t sz = get_file_size(fd);
if (sz == -1) {
return -1;
}
lseek64(fd, 0, SEEK_SET);
- int64_t limit = get_sparse_limit(usb, sz);
+ int64_t limit = get_sparse_limit(transport, sz);
if (limit) {
sparse_file** s = load_sparse_files(fd, limit);
if (s == nullptr) {
@@ -680,8 +683,7 @@ static int load_buf_fd(usb_handle* usb, int fd, struct fastboot_buffer* buf) {
return 0;
}
-static int load_buf(usb_handle *usb, const char *fname,
- struct fastboot_buffer *buf)
+static int load_buf(Transport* transport, const char *fname, struct fastboot_buffer *buf)
{
int fd;
@@ -690,7 +692,7 @@ static int load_buf(usb_handle *usb, const char *fname,
return -1;
}
- return load_buf_fd(usb, fd, buf);
+ return load_buf_fd(transport, fd, buf);
}
static void flash_buf(const char *pname, struct fastboot_buffer *buf)
@@ -713,20 +715,20 @@ static void flash_buf(const char *pname, struct fastboot_buffer *buf)
}
}
-static std::vector<std::string> get_suffixes(usb_handle* usb) {
+static std::vector<std::string> get_suffixes(Transport* transport) {
std::vector<std::string> suffixes;
std::string suffix_list;
- if (!fb_getvar(usb, "slot-suffixes", &suffix_list)) {
+ if (!fb_getvar(transport, "slot-suffixes", &suffix_list)) {
die("Could not get suffixes.\n");
}
return android::base::Split(suffix_list, ",");
}
-static std::string verify_slot(usb_handle* usb, const char *slot) {
+static std::string verify_slot(Transport* transport, const char *slot) {
if (strcmp(slot, "all") == 0) {
return "all";
}
- std::vector<std::string> suffixes = get_suffixes(usb);
+ std::vector<std::string> suffixes = get_suffixes(transport);
for (const std::string &suffix : suffixes) {
if (suffix == slot)
return slot;
@@ -738,17 +740,18 @@ static std::string verify_slot(usb_handle* usb, const char *slot) {
exit(1);
}
-static void do_for_partition(usb_handle* usb, const char *part, const char *slot, std::function<void(const std::string&)> func, bool force_slot) {
+static void do_for_partition(Transport* transport, const char *part, const char *slot,
+ std::function<void(const std::string&)> func, bool force_slot) {
std::string has_slot;
std::string current_slot;
- if (!fb_getvar(usb, std::string("has-slot:")+part, &has_slot)) {
+ if (!fb_getvar(transport, std::string("has-slot:")+part, &has_slot)) {
/* If has-slot is not supported, the answer is no. */
has_slot = "no";
}
if (has_slot == "yes") {
if (!slot || slot[0] == 0) {
- if (!fb_getvar(usb, "current-slot", &current_slot)) {
+ if (!fb_getvar(transport, "current-slot", &current_slot)) {
die("Failed to identify current slot.\n");
}
func(std::string(part) + current_slot);
@@ -757,40 +760,43 @@ static void do_for_partition(usb_handle* usb, const char *part, const char *slot
}
} else {
if (force_slot && slot && slot[0]) {
- fprintf(stderr, "Warning: %s does not support slots, and slot %s was requested.\n", part, slot);
+ fprintf(stderr, "Warning: %s does not support slots, and slot %s was requested.\n",
+ part, slot);
}
func(part);
}
}
-/* This function will find the real partition name given a base name, and a slot. If slot is NULL or empty,
- * it will use the current slot. If slot is "all", it will return a list of all possible partition names.
- * If force_slot is true, it will fail if a slot is specified, and the given partition does not support slots.
+/* This function will find the real partition name given a base name, and a slot. If slot is NULL or
+ * empty, it will use the current slot. If slot is "all", it will return a list of all possible
+ * partition names. If force_slot is true, it will fail if a slot is specified, and the given
+ * partition does not support slots.
*/
-static void do_for_partitions(usb_handle* usb, const char *part, const char *slot, std::function<void(const std::string&)> func, bool force_slot) {
+static void do_for_partitions(Transport* transport, const char *part, const char *slot,
+ std::function<void(const std::string&)> func, bool force_slot) {
std::string has_slot;
if (slot && strcmp(slot, "all") == 0) {
- if (!fb_getvar(usb, std::string("has-slot:") + part, &has_slot)) {
+ if (!fb_getvar(transport, std::string("has-slot:") + part, &has_slot)) {
die("Could not check if partition %s has slot.", part);
}
if (has_slot == "yes") {
- std::vector<std::string> suffixes = get_suffixes(usb);
+ std::vector<std::string> suffixes = get_suffixes(transport);
for (std::string &suffix : suffixes) {
- do_for_partition(usb, part, suffix.c_str(), func, force_slot);
+ do_for_partition(transport, part, suffix.c_str(), func, force_slot);
}
} else {
- do_for_partition(usb, part, "", func, force_slot);
+ do_for_partition(transport, part, "", func, force_slot);
}
} else {
- do_for_partition(usb, part, slot, func, force_slot);
+ do_for_partition(transport, part, slot, func, force_slot);
}
}
-static void do_flash(usb_handle* usb, const char* pname, const char* fname) {
+static void do_flash(Transport* transport, const char* pname, const char* fname) {
struct fastboot_buffer buf;
- if (load_buf(usb, fname, &buf)) {
+ if (load_buf(transport, fname, &buf)) {
die("cannot load '%s'", fname);
}
flash_buf(pname, &buf);
@@ -804,7 +810,7 @@ static void do_update_signature(ZipArchiveHandle zip, char* fn) {
fb_queue_command("signature", "installing signature");
}
-static void do_update(usb_handle* usb, const char* filename, const char* slot_override, bool erase_first) {
+static void do_update(Transport* transport, const char* filename, const char* slot_override, bool erase_first) {
queue_info_dump();
fb_queue_query_save("product", cur_product, sizeof(cur_product));
@@ -835,12 +841,12 @@ static void do_update(usb_handle* usb, const char* filename, const char* slot_ov
exit(1); // unzip_to_file already explained why.
}
fastboot_buffer buf;
- int rc = load_buf_fd(usb, fd, &buf);
+ int rc = load_buf_fd(transport, fd, &buf);
if (rc) die("cannot load %s from flash", images[i].img_name);
auto update = [&](const std::string &partition) {
do_update_signature(zip, images[i].sig_name);
- if (erase_first && needs_erase(usb, partition.c_str())) {
+ if (erase_first && needs_erase(transport, partition.c_str())) {
fb_queue_erase(partition.c_str());
}
flash_buf(partition.c_str(), &buf);
@@ -849,7 +855,7 @@ static void do_update(usb_handle* usb, const char* filename, const char* slot_ov
* program exits.
*/
};
- do_for_partitions(usb, images[i].part_name, slot_override, update, false);
+ do_for_partitions(transport, images[i].part_name, slot_override, update, false);
}
CloseArchive(zip);
@@ -871,7 +877,7 @@ static void do_send_signature(char* fn) {
fb_queue_command("signature", "installing signature");
}
-static void do_flashall(usb_handle* usb, const char *slot_override, int erase_first) {
+static void do_flashall(Transport* transport, const char* slot_override, int erase_first) {
queue_info_dump();
fb_queue_query_save("product", cur_product, sizeof(cur_product));
@@ -888,7 +894,7 @@ static void do_flashall(usb_handle* usb, const char *slot_override, int erase_fi
for (size_t i = 0; i < ARRAY_SIZE(images); i++) {
fname = find_item(images[i].part_name, product);
fastboot_buffer buf;
- if (load_buf(usb, fname, &buf)) {
+ if (load_buf(transport, fname, &buf)) {
if (images[i].is_optional)
continue;
die("could not load %s\n", images[i].img_name);
@@ -896,12 +902,12 @@ static void do_flashall(usb_handle* usb, const char *slot_override, int erase_fi
auto flashall = [&](const std::string &partition) {
do_send_signature(fname);
- if (erase_first && needs_erase(usb, partition.c_str())) {
+ if (erase_first && needs_erase(transport, partition.c_str())) {
fb_queue_erase(partition.c_str());
}
flash_buf(partition.c_str(), &buf);
};
- do_for_partitions(usb, images[i].part_name, slot_override, flashall, false);
+ do_for_partitions(transport, images[i].part_name, slot_override, flashall, false);
}
}
@@ -986,7 +992,7 @@ static int64_t parse_num(const char *arg)
return num;
}
-static void fb_perform_format(usb_handle* usb,
+static void fb_perform_format(Transport* transport,
const char* partition, int skip_if_not_supported,
const char* type_override, const char* size_override) {
std::string partition_type, partition_size;
@@ -1004,7 +1010,7 @@ static void fb_perform_format(usb_handle* usb,
limit = sparse_limit;
}
- if (!fb_getvar(usb, std::string("partition-type:") + partition, &partition_type)) {
+ if (!fb_getvar(transport, std::string("partition-type:") + partition, &partition_type)) {
errMsg = "Can't determine partition type.\n";
goto failed;
}
@@ -1016,7 +1022,7 @@ static void fb_perform_format(usb_handle* usb,
partition_type = type_override;
}
- if (!fb_getvar(usb, std::string("partition-size:") + partition, &partition_size)) {
+ if (!fb_getvar(transport, std::string("partition-size:") + partition, &partition_size)) {
errMsg = "Unable to get partition size\n";
goto failed;
}
@@ -1058,7 +1064,7 @@ static void fb_perform_format(usb_handle* usb,
return;
}
- if (load_buf_fd(usb, fd, &buf)) {
+ if (load_buf_fd(transport, fd, &buf)) {
fprintf(stderr, "Cannot read image: %s\n", strerror(errno));
close(fd);
return;
@@ -1210,11 +1216,11 @@ int main(int argc, char **argv)
return 0;
}
- usb_handle* usb = open_device();
+ Transport* transport = open_device();
if (slot_override != "")
- slot_override = verify_slot(usb, slot_override.c_str());
+ slot_override = verify_slot(transport, slot_override.c_str());
if (next_active != "")
- next_active = verify_slot(usb, next_active.c_str());
+ next_active = verify_slot(transport, next_active.c_str());
if (wants_set_active) {
if (next_active == "") {
@@ -1235,8 +1241,8 @@ int main(int argc, char **argv)
require(2);
auto erase = [&](const std::string &partition) {
- std::string partition_type;
- if (fb_getvar(usb, std::string("partition-type:") + argv[1], &partition_type) &&
+ std::string partition_type;
+ if (fb_getvar(transport, std::string("partition-type:") + argv[1], &partition_type) &&
fs_get_generator(partition_type) != nullptr) {
fprintf(stderr, "******** Did you mean to fastboot format this %s partition?\n",
partition_type.c_str());
@@ -1244,7 +1250,7 @@ int main(int argc, char **argv)
fb_queue_erase(partition.c_str());
};
- do_for_partitions(usb, argv[1], slot_override.c_str(), erase, true);
+ do_for_partitions(transport, argv[1], slot_override.c_str(), erase, true);
skip(2);
} else if(!strncmp(*argv, "format", strlen("format"))) {
char *overrides;
@@ -1274,12 +1280,12 @@ int main(int argc, char **argv)
if (size_override && !size_override[0]) size_override = nullptr;
auto format = [&](const std::string &partition) {
- if (erase_first && needs_erase(usb, partition.c_str())) {
+ if (erase_first && needs_erase(transport, partition.c_str())) {
fb_queue_erase(partition.c_str());
}
- fb_perform_format(usb, partition.c_str(), 0, type_override, size_override);
+ fb_perform_format(transport, partition.c_str(), 0, type_override, size_override);
};
- do_for_partitions(usb, argv[1], slot_override.c_str(), format, true);
+ do_for_partitions(transport, argv[1], slot_override.c_str(), format, true);
skip(2);
} else if(!strcmp(*argv, "signature")) {
require(2);
@@ -1341,12 +1347,12 @@ int main(int argc, char **argv)
if (fname == 0) die("cannot determine image filename for '%s'", pname);
auto flash = [&](const std::string &partition) {
- if (erase_first && needs_erase(usb, partition.c_str())) {
+ if (erase_first && needs_erase(transport, partition.c_str())) {
fb_queue_erase(partition.c_str());
}
- do_flash(usb, partition.c_str(), fname);
+ do_flash(transport, partition.c_str(), fname);
};
- do_for_partitions(usb, pname, slot_override.c_str(), flash, true);
+ do_for_partitions(transport, pname, slot_override.c_str(), flash, true);
} else if(!strcmp(*argv, "flash:raw")) {
char *kname = argv[2];
char *rname = 0;
@@ -1366,17 +1372,17 @@ int main(int argc, char **argv)
auto flashraw = [&](const std::string &partition) {
fb_queue_flash(partition.c_str(), data, sz);
};
- do_for_partitions(usb, argv[1], slot_override.c_str(), flashraw, true);
+ do_for_partitions(transport, argv[1], slot_override.c_str(), flashraw, true);
} else if(!strcmp(*argv, "flashall")) {
skip(1);
- do_flashall(usb, slot_override.c_str(), erase_first);
+ do_flashall(transport, slot_override.c_str(), erase_first);
wants_reboot = true;
} else if(!strcmp(*argv, "update")) {
if (argc > 1) {
- do_update(usb, argv[1], slot_override.c_str(), erase_first);
+ do_update(transport, argv[1], slot_override.c_str(), erase_first);
skip(2);
} else {
- do_update(usb, "update.zip", slot_override.c_str(), erase_first);
+ do_update(transport, "update.zip", slot_override.c_str(), erase_first);
skip(1);
}
wants_reboot = true;
@@ -1407,13 +1413,13 @@ int main(int argc, char **argv)
if (wants_wipe) {
fprintf(stderr, "wiping userdata...\n");
fb_queue_erase("userdata");
- fb_perform_format(usb, "userdata", 1, nullptr, nullptr);
+ fb_perform_format(transport, "userdata", 1, nullptr, nullptr);
std::string cache_type;
- if (fb_getvar(usb, "partition-type:cache", &cache_type) && !cache_type.empty()) {
+ if (fb_getvar(transport, "partition-type:cache", &cache_type) && !cache_type.empty()) {
fprintf(stderr, "wiping cache...\n");
fb_queue_erase("cache");
- fb_perform_format(usb, "cache", 1, nullptr, nullptr);
+ fb_perform_format(transport, "cache", 1, nullptr, nullptr);
}
}
if (wants_set_active) {
@@ -1427,5 +1433,5 @@ int main(int argc, char **argv)
fb_queue_wait_for_disconnect();
}
- return fb_execute_queue(usb) ? EXIT_FAILURE : EXIT_SUCCESS;
+ return fb_execute_queue(transport) ? EXIT_FAILURE : EXIT_SUCCESS;
}