diff options
-rw-r--r-- | fastboot/Android.mk | 1 | ||||
-rw-r--r-- | fastboot/engine.cpp | 16 | ||||
-rw-r--r-- | fastboot/fastboot.cpp | 144 | ||||
-rw-r--r-- | fastboot/fastboot.h | 14 | ||||
-rw-r--r-- | fastboot/protocol.cpp | 117 | ||||
-rw-r--r-- | fastboot/transport.h | 48 | ||||
-rw-r--r-- | fastboot/usb.h | 8 | ||||
-rw-r--r-- | fastboot/usb_linux.cpp | 91 | ||||
-rw-r--r-- | fastboot/usb_osx.cpp | 73 | ||||
-rw-r--r-- | fastboot/usb_windows.cpp | 133 | ||||
-rw-r--r-- | fastboot/usbtest.cpp | 16 |
11 files changed, 304 insertions, 357 deletions
diff --git a/fastboot/Android.mk b/fastboot/Android.mk index 5ca88cb3e..7a7366eee 100644 --- a/fastboot/Android.mk +++ b/fastboot/Android.mk @@ -83,6 +83,5 @@ include $(CLEAR_VARS) LOCAL_SRC_FILES := usbtest.cpp usb_linux.cpp util.cpp LOCAL_MODULE := usbtest LOCAL_CFLAGS := -Werror -LOCAL_STATIC_LIBRARIES := libbase include $(BUILD_HOST_EXECUTABLE) endif diff --git a/fastboot/engine.cpp b/fastboot/engine.cpp index ac5a17a06..d4be63b73 100644 --- a/fastboot/engine.cpp +++ b/fastboot/engine.cpp @@ -75,13 +75,13 @@ static Action *action_last = 0; -bool fb_getvar(Transport* transport, const std::string& key, std::string* value) { +bool fb_getvar(usb_handle* usb, const std::string& key, std::string* value) { std::string cmd = "getvar:"; cmd += key; char buf[FB_RESPONSE_SZ + 1]; memset(buf, 0, sizeof(buf)); - if (fb_command_response(transport, cmd.c_str(), buf)) { + if (fb_command_response(usb, cmd.c_str(), buf)) { return false; } *value = buf; @@ -330,7 +330,7 @@ void fb_queue_wait_for_disconnect(void) queue_action(OP_WAIT_FOR_DISCONNECT, ""); } -int fb_execute_queue(Transport* transport) +int fb_execute_queue(usb_handle *usb) { Action *a; char resp[FB_RESPONSE_SZ+1]; @@ -350,25 +350,25 @@ int fb_execute_queue(Transport* transport) fprintf(stderr,"%s...\n",a->msg); } if (a->op == OP_DOWNLOAD) { - status = fb_download_data(transport, a->data, a->size); + status = fb_download_data(usb, a->data, a->size); status = a->func(a, status, status ? fb_get_error() : ""); if (status) break; } else if (a->op == OP_COMMAND) { - status = fb_command(transport, a->cmd); + status = fb_command(usb, a->cmd); status = a->func(a, status, status ? fb_get_error() : ""); if (status) break; } else if (a->op == OP_QUERY) { - status = fb_command_response(transport, a->cmd, resp); + status = fb_command_response(usb, a->cmd, resp); status = a->func(a, status, status ? fb_get_error() : resp); if (status) break; } else if (a->op == OP_NOTICE) { fprintf(stderr,"%s\n",(char*)a->data); } else if (a->op == OP_DOWNLOAD_SPARSE) { - status = fb_download_data_sparse(transport, reinterpret_cast<sparse_file*>(a->data)); + status = fb_download_data_sparse(usb, reinterpret_cast<sparse_file*>(a->data)); status = a->func(a, status, status ? fb_get_error() : ""); if (status) break; } else if (a->op == OP_WAIT_FOR_DISCONNECT) { - transport->WaitForDisconnect(); + usb_wait_for_disconnect(usb); } else { die("bogus action"); } diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp index e3aeb912e..3ab8f94fa 100644 --- a/fastboot/fastboot.cpp +++ b/fastboot/fastboot.cpp @@ -55,8 +55,6 @@ #include "bootimg_utils.h" #include "fastboot.h" #include "fs.h" -#include "transport.h" -#include "usb.h" #ifndef O_BINARY #define O_BINARY 0 @@ -224,16 +222,16 @@ static int list_devices_callback(usb_ifc_info* info) { return -1; } -static Transport* open_device() { - static Transport* transport = nullptr; +static usb_handle* open_device() { + static usb_handle *usb = 0; int announce = 1; - if (transport) return transport; + if(usb) return usb; - for (;;) { - transport = usb_open(match_fastboot); - if (transport) return transport; - if (announce) { + for(;;) { + usb = usb_open(match_fastboot); + if(usb) return usb; + if(announce) { announce = 0; fprintf(stderr, "< waiting for %s >\n", serial ? serial : "any device"); } @@ -599,10 +597,9 @@ static struct sparse_file **load_sparse_files(int fd, int max_size) return out_s; } -static int64_t get_target_sparse_limit(Transport* transport) { +static int64_t get_target_sparse_limit(usb_handle* usb) { std::string max_download_size; - if (!fb_getvar(transport, "max-download-size", &max_download_size) || - max_download_size.empty()) { + if (!fb_getvar(usb, "max-download-size", &max_download_size) || max_download_size.empty()) { fprintf(stderr, "target didn't report max-download-size\n"); return 0; } @@ -621,7 +618,7 @@ static int64_t get_target_sparse_limit(Transport* transport) { return limit; } -static int64_t get_sparse_limit(Transport* transport, int64_t size) { +static int64_t get_sparse_limit(usb_handle* usb, int64_t size) { int64_t limit; if (sparse_limit == 0) { @@ -630,7 +627,7 @@ static int64_t get_sparse_limit(Transport* transport, int64_t size) { limit = sparse_limit; } else { if (target_sparse_limit == -1) { - target_sparse_limit = get_target_sparse_limit(transport); + target_sparse_limit = get_target_sparse_limit(usb); } if (target_sparse_limit > 0) { limit = target_sparse_limit; @@ -649,22 +646,22 @@ static int64_t get_sparse_limit(Transport* transport, 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(Transport* transport, const char* partition) { +static bool needs_erase(usb_handle* usb, const char* partition) { std::string partition_type; - if (!fb_getvar(transport, std::string("partition-type:") + partition, &partition_type)) { + if (!fb_getvar(usb, std::string("partition-type:") + partition, &partition_type)) { return false; } return partition_type == "ext4"; } -static int load_buf_fd(Transport* transport, int fd, struct fastboot_buffer* buf) { +static int load_buf_fd(usb_handle* usb, 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(transport, sz); + int64_t limit = get_sparse_limit(usb, sz); if (limit) { sparse_file** s = load_sparse_files(fd, limit); if (s == nullptr) { @@ -683,7 +680,8 @@ static int load_buf_fd(Transport* transport, int fd, struct fastboot_buffer* buf return 0; } -static int load_buf(Transport* transport, const char *fname, struct fastboot_buffer *buf) +static int load_buf(usb_handle *usb, const char *fname, + struct fastboot_buffer *buf) { int fd; @@ -692,7 +690,7 @@ static int load_buf(Transport* transport, const char *fname, struct fastboot_buf return -1; } - return load_buf_fd(transport, fd, buf); + return load_buf_fd(usb, fd, buf); } static void flash_buf(const char *pname, struct fastboot_buffer *buf) @@ -715,20 +713,20 @@ static void flash_buf(const char *pname, struct fastboot_buffer *buf) } } -static std::vector<std::string> get_suffixes(Transport* transport) { +static std::vector<std::string> get_suffixes(usb_handle* usb) { std::vector<std::string> suffixes; std::string suffix_list; - if (!fb_getvar(transport, "slot-suffixes", &suffix_list)) { + if (!fb_getvar(usb, "slot-suffixes", &suffix_list)) { die("Could not get suffixes.\n"); } return android::base::Split(suffix_list, ","); } -static std::string verify_slot(Transport* transport, const char *slot) { +static std::string verify_slot(usb_handle* usb, const char *slot) { if (strcmp(slot, "all") == 0) { return "all"; } - std::vector<std::string> suffixes = get_suffixes(transport); + std::vector<std::string> suffixes = get_suffixes(usb); for (const std::string &suffix : suffixes) { if (suffix == slot) return slot; @@ -740,18 +738,17 @@ static std::string verify_slot(Transport* transport, const char *slot) { exit(1); } -static void do_for_partition(Transport* transport, const char *part, const char *slot, - std::function<void(const std::string&)> func, bool force_slot) { +static void do_for_partition(usb_handle* usb, 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(transport, std::string("has-slot:")+part, &has_slot)) { + if (!fb_getvar(usb, 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(transport, "current-slot", ¤t_slot)) { + if (!fb_getvar(usb, "current-slot", ¤t_slot)) { die("Failed to identify current slot.\n"); } func(std::string(part) + '-' + current_slot); @@ -760,43 +757,40 @@ static void do_for_partition(Transport* transport, const char *part, const char } } 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(Transport* transport, const char *part, const char *slot, - std::function<void(const std::string&)> func, bool force_slot) { +static void do_for_partitions(usb_handle* usb, 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(transport, std::string("has-slot:") + part, &has_slot)) { + if (!fb_getvar(usb, 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(transport); + std::vector<std::string> suffixes = get_suffixes(usb); for (std::string &suffix : suffixes) { - do_for_partition(transport, part, suffix.c_str(), func, force_slot); + do_for_partition(usb, part, suffix.c_str(), func, force_slot); } } else { - do_for_partition(transport, part, "", func, force_slot); + do_for_partition(usb, part, "", func, force_slot); } } else { - do_for_partition(transport, part, slot, func, force_slot); + do_for_partition(usb, part, slot, func, force_slot); } } -static void do_flash(Transport* transport, const char* pname, const char* fname) { +static void do_flash(usb_handle* usb, const char* pname, const char* fname) { struct fastboot_buffer buf; - if (load_buf(transport, fname, &buf)) { + if (load_buf(usb, fname, &buf)) { die("cannot load '%s'", fname); } flash_buf(pname, &buf); @@ -810,7 +804,7 @@ static void do_update_signature(ZipArchiveHandle zip, char* fn) { fb_queue_command("signature", "installing signature"); } -static void do_update(Transport* transport, const char* filename, const char* slot_override, bool erase_first) { +static void do_update(usb_handle* usb, const char* filename, const char* slot_override, bool erase_first) { queue_info_dump(); fb_queue_query_save("product", cur_product, sizeof(cur_product)); @@ -841,12 +835,12 @@ static void do_update(Transport* transport, const char* filename, const char* sl exit(1); // unzip_to_file already explained why. } fastboot_buffer buf; - int rc = load_buf_fd(transport, fd, &buf); + int rc = load_buf_fd(usb, 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(transport, partition.c_str())) { + if (erase_first && needs_erase(usb, partition.c_str())) { fb_queue_erase(partition.c_str()); } flash_buf(partition.c_str(), &buf); @@ -855,7 +849,7 @@ static void do_update(Transport* transport, const char* filename, const char* sl * program exits. */ }; - do_for_partitions(transport, images[i].part_name, slot_override, update, false); + do_for_partitions(usb, images[i].part_name, slot_override, update, false); } CloseArchive(zip); @@ -877,7 +871,7 @@ static void do_send_signature(char* fn) { fb_queue_command("signature", "installing signature"); } -static void do_flashall(Transport* transport, const char* slot_override, int erase_first) { +static void do_flashall(usb_handle* usb, const char *slot_override, int erase_first) { queue_info_dump(); fb_queue_query_save("product", cur_product, sizeof(cur_product)); @@ -894,7 +888,7 @@ static void do_flashall(Transport* transport, const char* slot_override, int era for (size_t i = 0; i < ARRAY_SIZE(images); i++) { fname = find_item(images[i].part_name, product); fastboot_buffer buf; - if (load_buf(transport, fname, &buf)) { + if (load_buf(usb, fname, &buf)) { if (images[i].is_optional) continue; die("could not load %s\n", images[i].img_name); @@ -902,12 +896,12 @@ static void do_flashall(Transport* transport, const char* slot_override, int era auto flashall = [&](const std::string &partition) { do_send_signature(fname); - if (erase_first && needs_erase(transport, partition.c_str())) { + if (erase_first && needs_erase(usb, partition.c_str())) { fb_queue_erase(partition.c_str()); } flash_buf(partition.c_str(), &buf); }; - do_for_partitions(transport, images[i].part_name, slot_override, flashall, false); + do_for_partitions(usb, images[i].part_name, slot_override, flashall, false); } } @@ -992,7 +986,7 @@ static int64_t parse_num(const char *arg) return num; } -static void fb_perform_format(Transport* transport, +static void fb_perform_format(usb_handle* usb, const char* partition, int skip_if_not_supported, const char* type_override, const char* size_override) { std::string partition_type, partition_size; @@ -1010,7 +1004,7 @@ static void fb_perform_format(Transport* transport, limit = sparse_limit; } - if (!fb_getvar(transport, std::string("partition-type:") + partition, &partition_type)) { + if (!fb_getvar(usb, std::string("partition-type:") + partition, &partition_type)) { errMsg = "Can't determine partition type.\n"; goto failed; } @@ -1022,7 +1016,7 @@ static void fb_perform_format(Transport* transport, partition_type = type_override; } - if (!fb_getvar(transport, std::string("partition-size:") + partition, &partition_size)) { + if (!fb_getvar(usb, std::string("partition-size:") + partition, &partition_size)) { errMsg = "Unable to get partition size\n"; goto failed; } @@ -1064,7 +1058,7 @@ static void fb_perform_format(Transport* transport, return; } - if (load_buf_fd(transport, fd, &buf)) { + if (load_buf_fd(usb, fd, &buf)) { fprintf(stderr, "Cannot read image: %s\n", strerror(errno)); close(fd); return; @@ -1216,11 +1210,11 @@ int main(int argc, char **argv) return 0; } - Transport* transport = open_device(); + usb_handle* usb = open_device(); if (slot_override != "") - slot_override = verify_slot(transport, slot_override.c_str()); + slot_override = verify_slot(usb, slot_override.c_str()); if (next_active != "") - next_active = verify_slot(transport, next_active.c_str()); + next_active = verify_slot(usb, next_active.c_str()); if (wants_set_active) { if (next_active == "") { @@ -1241,8 +1235,8 @@ int main(int argc, char **argv) require(2); auto erase = [&](const std::string &partition) { - std::string partition_type; - if (fb_getvar(transport, std::string("partition-type:") + argv[1], &partition_type) && + std::string partition_type; + if (fb_getvar(usb, 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()); @@ -1250,7 +1244,7 @@ int main(int argc, char **argv) fb_queue_erase(partition.c_str()); }; - do_for_partitions(transport, argv[1], slot_override.c_str(), erase, true); + do_for_partitions(usb, argv[1], slot_override.c_str(), erase, true); skip(2); } else if(!strncmp(*argv, "format", strlen("format"))) { char *overrides; @@ -1280,12 +1274,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(transport, partition.c_str())) { + if (erase_first && needs_erase(usb, partition.c_str())) { fb_queue_erase(partition.c_str()); } - fb_perform_format(transport, partition.c_str(), 0, type_override, size_override); + fb_perform_format(usb, partition.c_str(), 0, type_override, size_override); }; - do_for_partitions(transport, argv[1], slot_override.c_str(), format, true); + do_for_partitions(usb, argv[1], slot_override.c_str(), format, true); skip(2); } else if(!strcmp(*argv, "signature")) { require(2); @@ -1347,12 +1341,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(transport, partition.c_str())) { + if (erase_first && needs_erase(usb, partition.c_str())) { fb_queue_erase(partition.c_str()); } - do_flash(transport, partition.c_str(), fname); + do_flash(usb, partition.c_str(), fname); }; - do_for_partitions(transport, pname, slot_override.c_str(), flash, true); + do_for_partitions(usb, pname, slot_override.c_str(), flash, true); } else if(!strcmp(*argv, "flash:raw")) { char *kname = argv[2]; char *rname = 0; @@ -1372,17 +1366,17 @@ int main(int argc, char **argv) auto flashraw = [&](const std::string &partition) { fb_queue_flash(partition.c_str(), data, sz); }; - do_for_partitions(transport, argv[1], slot_override.c_str(), flashraw, true); + do_for_partitions(usb, argv[1], slot_override.c_str(), flashraw, true); } else if(!strcmp(*argv, "flashall")) { skip(1); - do_flashall(transport, slot_override.c_str(), erase_first); + do_flashall(usb, slot_override.c_str(), erase_first); wants_reboot = true; } else if(!strcmp(*argv, "update")) { if (argc > 1) { - do_update(transport, argv[1], slot_override.c_str(), erase_first); + do_update(usb, argv[1], slot_override.c_str(), erase_first); skip(2); } else { - do_update(transport, "update.zip", slot_override.c_str(), erase_first); + do_update(usb, "update.zip", slot_override.c_str(), erase_first); skip(1); } wants_reboot = true; @@ -1413,13 +1407,13 @@ int main(int argc, char **argv) if (wants_wipe) { fprintf(stderr, "wiping userdata...\n"); fb_queue_erase("userdata"); - fb_perform_format(transport, "userdata", 1, nullptr, nullptr); + fb_perform_format(usb, "userdata", 1, nullptr, nullptr); std::string cache_type; - if (fb_getvar(transport, "partition-type:cache", &cache_type) && !cache_type.empty()) { + if (fb_getvar(usb, "partition-type:cache", &cache_type) && !cache_type.empty()) { fprintf(stderr, "wiping cache...\n"); fb_queue_erase("cache"); - fb_perform_format(transport, "cache", 1, nullptr, nullptr); + fb_perform_format(usb, "cache", 1, nullptr, nullptr); } } if (wants_set_active) { @@ -1433,5 +1427,5 @@ int main(int argc, char **argv) fb_queue_wait_for_disconnect(); } - return fb_execute_queue(transport) ? EXIT_FAILURE : EXIT_SUCCESS; + return fb_execute_queue(usb) ? EXIT_FAILURE : EXIT_SUCCESS; } diff --git a/fastboot/fastboot.h b/fastboot/fastboot.h index acfbc1352..784ec5c10 100644 --- a/fastboot/fastboot.h +++ b/fastboot/fastboot.h @@ -34,22 +34,22 @@ #include <string> -#include "transport.h" +#include "usb.h" struct sparse_file; /* protocol.c - fastboot protocol */ -int fb_command(Transport* transport, const char* cmd); -int fb_command_response(Transport* transport, const char* cmd, char* response); -int fb_download_data(Transport* transport, const void* data, uint32_t size); -int fb_download_data_sparse(Transport* transport, struct sparse_file* s); +int fb_command(usb_handle *usb, const char *cmd); +int fb_command_response(usb_handle *usb, const char *cmd, char *response); +int fb_download_data(usb_handle *usb, const void *data, uint32_t size); +int fb_download_data_sparse(usb_handle *usb, struct sparse_file *s); char *fb_get_error(void); #define FB_COMMAND_SZ 64 #define FB_RESPONSE_SZ 64 /* engine.c - high level command queue engine */ -bool fb_getvar(Transport* transport, const std::string& key, std::string* value); +bool fb_getvar(usb_handle* usb, const std::string& key, std::string* value); void fb_queue_flash(const char *ptn, void *data, uint32_t sz); void fb_queue_flash_sparse(const char *ptn, struct sparse_file *s, uint32_t sz); void fb_queue_erase(const char *ptn); @@ -63,7 +63,7 @@ void fb_queue_command(const char *cmd, const char *msg); void fb_queue_download(const char *name, void *data, uint32_t size); void fb_queue_notice(const char *notice); void fb_queue_wait_for_disconnect(void); -int fb_execute_queue(Transport* transport); +int fb_execute_queue(usb_handle *usb); void fb_set_active(const char *slot); /* util stuff */ diff --git a/fastboot/protocol.cpp b/fastboot/protocol.cpp index 4850b4a0d..cbd48e873 100644 --- a/fastboot/protocol.cpp +++ b/fastboot/protocol.cpp @@ -39,7 +39,6 @@ #include <sparse/sparse.h> #include "fastboot.h" -#include "transport.h" static char ERROR[128]; @@ -48,21 +47,21 @@ char *fb_get_error(void) return ERROR; } -static int check_response(Transport* transport, uint32_t size, char* response) { +static int check_response(usb_handle* usb, uint32_t size, char* response) { char status[65]; while (true) { - int r = transport->Read(status, 64); + int r = usb_read(usb, status, 64); if (r < 0) { sprintf(ERROR, "status read failed (%s)", strerror(errno)); - transport->Close(); + usb_close(usb); return -1; } status[r] = 0; if (r < 4) { sprintf(ERROR, "status malformed (%d bytes)", r); - transport->Close(); + usb_close(usb); return -1; } @@ -91,21 +90,21 @@ static int check_response(Transport* transport, uint32_t size, char* response) { uint32_t dsize = strtol(status + 4, 0, 16); if (dsize > size) { strcpy(ERROR, "data size too large"); - transport->Close(); + usb_close(usb); return -1; } return dsize; } strcpy(ERROR,"unknown status code"); - transport->Close(); + usb_close(usb); break; } return -1; } -static int _command_start(Transport* transport, const char* cmd, uint32_t size, char* response) { +static int _command_start(usb_handle* usb, const char* cmd, uint32_t size, char* response) { size_t cmdsize = strlen(cmd); if (cmdsize > 64) { sprintf(ERROR, "command too large"); @@ -116,51 +115,51 @@ static int _command_start(Transport* transport, const char* cmd, uint32_t size, response[0] = 0; } - if (transport->Write(cmd, cmdsize) != static_cast<int>(cmdsize)) { + if (usb_write(usb, cmd, cmdsize) != static_cast<int>(cmdsize)) { sprintf(ERROR, "command write failed (%s)", strerror(errno)); - transport->Close(); + usb_close(usb); return -1; } - return check_response(transport, size, response); + return check_response(usb, size, response); } -static int _command_data(Transport* transport, const void* data, uint32_t size) { - int r = transport->Write(data, size); +static int _command_data(usb_handle* usb, const void* data, uint32_t size) { + int r = usb_write(usb, data, size); if (r < 0) { sprintf(ERROR, "data transfer failure (%s)", strerror(errno)); - transport->Close(); + usb_close(usb); return -1; } if (r != ((int) size)) { sprintf(ERROR, "data transfer failure (short transfer)"); - transport->Close(); + usb_close(usb); return -1; } return r; } -static int _command_end(Transport* transport) { - return check_response(transport, 0, 0) < 0 ? -1 : 0; +static int _command_end(usb_handle* usb) { + return check_response(usb, 0, 0) < 0 ? -1 : 0; } -static int _command_send(Transport* transport, const char* cmd, const void* data, uint32_t size, +static int _command_send(usb_handle* usb, const char* cmd, const void* data, uint32_t size, char* response) { if (size == 0) { return -1; } - int r = _command_start(transport, cmd, size, response); + int r = _command_start(usb, cmd, size, response); if (r < 0) { return -1; } - r = _command_data(transport, data, size); + r = _command_data(usb, data, size); if (r < 0) { return -1; } - r = _command_end(transport); + r = _command_end(usb); if (r < 0) { return -1; } @@ -168,59 +167,59 @@ static int _command_send(Transport* transport, const char* cmd, const void* data return size; } -static int _command_send_no_data(Transport* transport, const char* cmd, char* response) { - return _command_start(transport, cmd, 0, response); +static int _command_send_no_data(usb_handle* usb, const char* cmd, char* response) { + return _command_start(usb, cmd, 0, response); } -int fb_command(Transport* transport, const char* cmd) { - return _command_send_no_data(transport, cmd, 0); +int fb_command(usb_handle* usb, const char* cmd) { + return _command_send_no_data(usb, cmd, 0); } -int fb_command_response(Transport* transport, const char* cmd, char* response) { - return _command_send_no_data(transport, cmd, response); +int fb_command_response(usb_handle* usb, const char* cmd, char* response) { + return _command_send_no_data(usb, cmd, response); } -int fb_download_data(Transport* transport, const void* data, uint32_t size) { +int fb_download_data(usb_handle* usb, const void* data, uint32_t size) { char cmd[64]; sprintf(cmd, "download:%08x", size); - return _command_send(transport, cmd, data, size, 0) < 0 ? -1 : 0; + return _command_send(usb, cmd, data, size, 0) < 0 ? -1 : 0; } -#define TRANSPORT_BUF_SIZE 1024 -static char transport_buf[TRANSPORT_BUF_SIZE]; -static int transport_buf_len; +#define USB_BUF_SIZE 1024 +static char usb_buf[USB_BUF_SIZE]; +static int usb_buf_len; static int fb_download_data_sparse_write(void *priv, const void *data, int len) { int r; - Transport* transport = reinterpret_cast<Transport*>(priv); + usb_handle* usb = reinterpret_cast<usb_handle*>(priv); int to_write; const char* ptr = reinterpret_cast<const char*>(data); - if (transport_buf_len) { - to_write = std::min(TRANSPORT_BUF_SIZE - transport_buf_len, len); + if (usb_buf_len) { + to_write = std::min(USB_BUF_SIZE - usb_buf_len, len); - memcpy(transport_buf + transport_buf_len, ptr, to_write); - transport_buf_len += to_write; + memcpy(usb_buf + usb_buf_len, ptr, to_write); + usb_buf_len += to_write; ptr += to_write; len -= to_write; } - if (transport_buf_len == TRANSPORT_BUF_SIZE) { - r = _command_data(transport, transport_buf, TRANSPORT_BUF_SIZE); - if (r != TRANSPORT_BUF_SIZE) { + if (usb_buf_len == USB_BUF_SIZE) { + r = _command_data(usb, usb_buf, USB_BUF_SIZE); + if (r != USB_BUF_SIZE) { return -1; } - transport_buf_len = 0; + usb_buf_len = 0; } - if (len > TRANSPORT_BUF_SIZE) { - if (transport_buf_len > 0) { - sprintf(ERROR, "internal error: transport_buf not empty\n"); + if (len > USB_BUF_SIZE) { + if (usb_buf_len > 0) { + sprintf(ERROR, "internal error: usb_buf not empty\n"); return -1; } - to_write = round_down(len, TRANSPORT_BUF_SIZE); - r = _command_data(transport, ptr, to_write); + to_write = round_down(len, USB_BUF_SIZE); + r = _command_data(usb, ptr, to_write); if (r != to_write) { return -1; } @@ -229,28 +228,28 @@ static int fb_download_data_sparse_write(void *priv, const void *data, int len) } if (len > 0) { - if (len > TRANSPORT_BUF_SIZE) { - sprintf(ERROR, "internal error: too much left for transport_buf\n"); + if (len > USB_BUF_SIZE) { + sprintf(ERROR, "internal error: too much left for usb_buf\n"); return -1; } - memcpy(transport_buf, ptr, len); - transport_buf_len = len; + memcpy(usb_buf, ptr, len); + usb_buf_len = len; } return 0; } -static int fb_download_data_sparse_flush(Transport* transport) { - if (transport_buf_len > 0) { - if (_command_data(transport, transport_buf, transport_buf_len) != transport_buf_len) { +static int fb_download_data_sparse_flush(usb_handle* usb) { + if (usb_buf_len > 0) { + if (_command_data(usb, usb_buf, usb_buf_len) != usb_buf_len) { return -1; } - transport_buf_len = 0; + usb_buf_len = 0; } return 0; } -int fb_download_data_sparse(Transport* transport, struct sparse_file* s) { +int fb_download_data_sparse(usb_handle* usb, struct sparse_file* s) { int size = sparse_file_len(s, true, false); if (size <= 0) { return -1; @@ -258,20 +257,20 @@ int fb_download_data_sparse(Transport* transport, struct sparse_file* s) { char cmd[64]; sprintf(cmd, "download:%08x", size); - int r = _command_start(transport, cmd, size, 0); + int r = _command_start(usb, cmd, size, 0); if (r < 0) { return -1; } - r = sparse_file_callback(s, true, false, fb_download_data_sparse_write, transport); + r = sparse_file_callback(s, true, false, fb_download_data_sparse_write, usb); if (r < 0) { return -1; } - r = fb_download_data_sparse_flush(transport); + r = fb_download_data_sparse_flush(usb); if (r < 0) { return -1; } - return _command_end(transport); + return _command_end(usb); } diff --git a/fastboot/transport.h b/fastboot/transport.h deleted file mode 100644 index 55a5abbc0..000000000 --- a/fastboot/transport.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef TRANSPORT_H_ -#define TRANSPORT_H_ - -#include <base/macros.h> - -// General interface to allow the fastboot protocol to be used over different -// types of transports. -class Transport { - public: - Transport() = default; - virtual ~Transport() = default; - - // Reads |len| bytes into |data|. Returns the number of bytes actually - // read or -1 on error. - virtual ssize_t Read(void* data, size_t len) = 0; - - // Writes |len| bytes from |data|. Returns the number of bytes actually - // written or -1 on error. - virtual ssize_t Write(const void* data, size_t len) = 0; - - // Closes the underlying transport. Returns 0 on success. - virtual int Close() = 0; - - // Blocks until the transport disconnects. Transports that don't support - // this will return immediately. Returns 0 on success. - virtual int WaitForDisconnect() { return 0; } - - private: - DISALLOW_COPY_AND_ASSIGN(Transport); -}; - -#endif // TRANSPORT_H_ diff --git a/fastboot/usb.h b/fastboot/usb.h index 4acf12d57..0fda41aae 100644 --- a/fastboot/usb.h +++ b/fastboot/usb.h @@ -29,7 +29,7 @@ #ifndef _USB_H_ #define _USB_H_ -#include "transport.h" +struct usb_handle; struct usb_ifc_info { /* from device descriptor */ @@ -55,6 +55,10 @@ struct usb_ifc_info { typedef int (*ifc_match_func)(usb_ifc_info *ifc); -Transport* usb_open(ifc_match_func callback); +usb_handle *usb_open(ifc_match_func callback); +int usb_close(usb_handle *h); +int usb_read(usb_handle *h, void *_data, int len); +int usb_write(usb_handle *h, const void *_data, int len); +int usb_wait_for_disconnect(usb_handle *h); #endif diff --git a/fastboot/usb_linux.cpp b/fastboot/usb_linux.cpp index 02ffcd978..7b879073d 100644 --- a/fastboot/usb_linux.cpp +++ b/fastboot/usb_linux.cpp @@ -43,8 +43,6 @@ #include <linux/version.h> #include <linux/usb/ch9.h> -#include <memory> - #include "fastboot.h" #include "usb.h" @@ -87,22 +85,6 @@ struct usb_handle unsigned char ep_out; }; -class LinuxUsbTransport : public Transport { - public: - LinuxUsbTransport(std::unique_ptr<usb_handle> handle) : handle_(std::move(handle)) {} - ~LinuxUsbTransport() override = default; - - ssize_t Read(void* data, size_t len) override; - ssize_t Write(const void* data, size_t len) override; - int Close() override; - int WaitForDisconnect() override; - - private: - std::unique_ptr<usb_handle> handle_; - - DISALLOW_COPY_AND_ASSIGN(LinuxUsbTransport); -}; - /* True if name isn't a valid name for a USB device in /sys/bus/usb/devices. * Device names are made up of numbers, dots, and dashes, e.g., '7-1.5'. * We reject interfaces (e.g., '7-1.5:1.0') and host controllers (e.g. 'usb1'). @@ -326,9 +308,9 @@ static int convert_to_devfs_name(const char* sysfs_name, return 0; } -static std::unique_ptr<usb_handle> find_usb_device(const char* base, ifc_match_func callback) +static usb_handle *find_usb_device(const char *base, ifc_match_func callback) { - std::unique_ptr<usb_handle> usb; + usb_handle *usb = 0; char devname[64]; char desc[1024]; int n, in, out, ifc; @@ -339,37 +321,39 @@ static std::unique_ptr<usb_handle> find_usb_device(const char* base, ifc_match_f int writable; busdir = opendir(base); - if (busdir == 0) return 0; + if(busdir == 0) return 0; - while ((de = readdir(busdir)) && (usb == nullptr)) { - if (badname(de->d_name)) continue; + while((de = readdir(busdir)) && (usb == 0)) { + if(badname(de->d_name)) continue; - if (!convert_to_devfs_name(de->d_name, devname, sizeof(devname))) { + if(!convert_to_devfs_name(de->d_name, devname, sizeof(devname))) { // DBG("[ scanning %s ]\n", devname); writable = 1; - if ((fd = open(devname, O_RDWR)) < 0) { + if((fd = open(devname, O_RDWR)) < 0) { // Check if we have read-only access, so we can give a helpful // diagnostic like "adb devices" does. writable = 0; - if ((fd = open(devname, O_RDONLY)) < 0) { + if((fd = open(devname, O_RDONLY)) < 0) { continue; } } n = read(fd, desc, sizeof(desc)); - if (filter_usb_device(de->d_name, desc, n, writable, callback, &in, &out, &ifc) == 0) { - usb.reset(new usb_handle()); + if(filter_usb_device(de->d_name, desc, n, writable, callback, + &in, &out, &ifc) == 0) { + usb = reinterpret_cast<usb_handle*>(calloc(1, sizeof(usb_handle))); strcpy(usb->fname, devname); usb->ep_in = in; usb->ep_out = out; usb->desc = fd; n = ioctl(fd, USBDEVFS_CLAIMINTERFACE, &ifc); - if (n != 0) { + if(n != 0) { close(fd); - usb.reset(); + free(usb); + usb = 0; continue; } } else { @@ -382,14 +366,14 @@ static std::unique_ptr<usb_handle> find_usb_device(const char* base, ifc_match_f return usb; } -ssize_t LinuxUsbTransport::Write(const void* _data, size_t len) +int usb_write(usb_handle *h, const void *_data, int len) { unsigned char *data = (unsigned char*) _data; unsigned count = 0; struct usbdevfs_bulktransfer bulk; int n; - if (handle_->ep_out == 0 || handle_->desc == -1) { + if(h->ep_out == 0 || h->desc == -1) { return -1; } @@ -397,12 +381,12 @@ ssize_t LinuxUsbTransport::Write(const void* _data, size_t len) int xfer; xfer = (len > MAX_USBFS_BULK_SIZE) ? MAX_USBFS_BULK_SIZE : len; - bulk.ep = handle_->ep_out; + bulk.ep = h->ep_out; bulk.len = xfer; bulk.data = data; bulk.timeout = 0; - n = ioctl(handle_->desc, USBDEVFS_BULK, &bulk); + n = ioctl(h->desc, USBDEVFS_BULK, &bulk); if(n != xfer) { DBG("ERROR: n = %d, errno = %d (%s)\n", n, errno, strerror(errno)); @@ -417,30 +401,30 @@ ssize_t LinuxUsbTransport::Write(const void* _data, size_t len) return count; } -ssize_t LinuxUsbTransport::Read(void* _data, size_t len) +int usb_read(usb_handle *h, void *_data, int len) { unsigned char *data = (unsigned char*) _data; unsigned count = 0; struct usbdevfs_bulktransfer bulk; int n, retry; - if (handle_->ep_in == 0 || handle_->desc == -1) { + if(h->ep_in == 0 || h->desc == -1) { return -1; } while(len > 0) { int xfer = (len > MAX_USBFS_BULK_SIZE) ? MAX_USBFS_BULK_SIZE : len; - bulk.ep = handle_->ep_in; + bulk.ep = h->ep_in; bulk.len = xfer; bulk.data = data; bulk.timeout = 0; retry = 0; do{ - DBG("[ usb read %d fd = %d], fname=%s\n", xfer, handle_->desc, handle_->fname); - n = ioctl(handle_->desc, USBDEVFS_BULK, &bulk); - DBG("[ usb read %d ] = %d, fname=%s, Retry %d \n", xfer, n, handle_->fname, retry); + DBG("[ usb read %d fd = %d], fname=%s\n", xfer, h->desc, h->fname); + n = ioctl(h->desc, USBDEVFS_BULK, &bulk); + DBG("[ usb read %d ] = %d, fname=%s, Retry %d \n", xfer, n, h->fname, retry); if( n < 0 ) { DBG1("ERROR: n = %d, errno = %d (%s)\n",n, errno, strerror(errno)); @@ -462,12 +446,24 @@ ssize_t LinuxUsbTransport::Read(void* _data, size_t len) return count; } -int LinuxUsbTransport::Close() +void usb_kick(usb_handle *h) +{ + int fd; + + fd = h->desc; + h->desc = -1; + if(fd >= 0) { + close(fd); + DBG("[ usb closed %d ]\n", fd); + } +} + +int usb_close(usb_handle *h) { int fd; - fd = handle_->desc; - handle_->desc = -1; + fd = h->desc; + h->desc = -1; if(fd >= 0) { close(fd); DBG("[ usb closed %d ]\n", fd); @@ -476,21 +472,20 @@ int LinuxUsbTransport::Close() return 0; } -Transport* usb_open(ifc_match_func callback) +usb_handle *usb_open(ifc_match_func callback) { - std::unique_ptr<usb_handle> handle = find_usb_device("/sys/bus/usb/devices", callback); - return handle ? new LinuxUsbTransport(std::move(handle)) : nullptr; + return find_usb_device("/sys/bus/usb/devices", callback); } /* Wait for the system to notice the device is gone, so that a subsequent * fastboot command won't try to access the device before it's rebooted. * Returns 0 for success, -1 for timeout. */ -int LinuxUsbTransport::WaitForDisconnect() +int usb_wait_for_disconnect(usb_handle *usb) { double deadline = now() + WAIT_FOR_DISCONNECT_TIMEOUT; while (now() < deadline) { - if (access(handle_->fname, F_OK)) + if (access(usb->fname, F_OK)) return 0; usleep(50000); } diff --git a/fastboot/usb_osx.cpp b/fastboot/usb_osx.cpp index ee5d57530..45ae833e5 100644 --- a/fastboot/usb_osx.cpp +++ b/fastboot/usb_osx.cpp @@ -35,8 +35,6 @@ #include <IOKit/IOMessage.h> #include <mach/mach_port.h> -#include <memory> - #include "usb.h" @@ -65,21 +63,6 @@ struct usb_handle unsigned int zero_mask; }; -class OsxUsbTransport : public Transport { - public: - OsxUsbTransport(std::unique_ptr<usb_handle> handle) : handle_(std::move(handle)) {} - ~OsxUsbTransport() override = default; - - ssize_t Read(void* data, size_t len) override; - ssize_t Write(const void* data, size_t len) override; - int Close() override; - - private: - std::unique_ptr<usb_handle> handle_; - - DISALLOW_COPY_AND_ASSIGN(OsxUsbTransport); -}; - /** Try out all the interfaces and see if there's a match. Returns 0 on * success, -1 on failure. */ static int try_interfaces(IOUSBDeviceInterface182 **dev, usb_handle *handle) { @@ -407,7 +390,7 @@ static int try_device(io_service_t device, usb_handle *handle) { /** Initializes the USB system. Returns 0 on success, -1 on error. */ -static int init_usb(ifc_match_func callback, std::unique_ptr<usb_handle>* handle) { +static int init_usb(ifc_match_func callback, usb_handle **handle) { int ret = -1; CFMutableDictionaryRef matchingDict; kern_return_t result; @@ -460,8 +443,8 @@ static int init_usb(ifc_match_func callback, std::unique_ptr<usb_handle>* handle } if (h.success) { - handle->reset(new usb_handle); - memcpy(handle->get(), &h, sizeof(usb_handle)); + *handle = reinterpret_cast<usb_handle*>(calloc(1, sizeof(usb_handle))); + memcpy(*handle, &h, sizeof(usb_handle)); ret = 0; break; } @@ -480,23 +463,28 @@ static int init_usb(ifc_match_func callback, std::unique_ptr<usb_handle>* handle * Definitions of this file's public functions. */ -Transport* usb_open(ifc_match_func callback) { - std::unique_ptr<usb_handle> handle; +usb_handle *usb_open(ifc_match_func callback) { + usb_handle *handle = NULL; if (init_usb(callback, &handle) < 0) { /* Something went wrong initializing USB. */ - return nullptr; + return NULL; } - return new OsxUsbTransport(std::move(handle)); + return handle; } -int OsxUsbTransport::Close() { +int usb_close(usb_handle *h) { /* TODO: Something better here? */ return 0; } -ssize_t OsxUsbTransport::Read(void* data, size_t len) { +int usb_wait_for_disconnect(usb_handle *usb) { + /* TODO: Punt for now */ + return 0; +} + +int usb_read(usb_handle *h, void *data, int len) { IOReturn result; UInt32 numBytes = len; @@ -504,21 +492,22 @@ ssize_t OsxUsbTransport::Read(void* data, size_t len) { return 0; } - if (handle_ == nullptr) { + if (h == NULL) { return -1; } - if (handle_->interface == nullptr) { + if (h->interface == NULL) { ERR("usb_read interface was null\n"); return -1; } - if (handle_->bulkIn == 0) { + if (h->bulkIn == 0) { ERR("bulkIn endpoint not assigned\n"); return -1; } - result = (*handle_->interface)->ReadPipe(handle_->interface, handle_->bulkIn, data, &numBytes); + result = (*h->interface)->ReadPipe( + h->interface, h->bulkIn, data, &numBytes); if (result == 0) { return (int) numBytes; @@ -529,30 +518,30 @@ ssize_t OsxUsbTransport::Read(void* data, size_t len) { return -1; } -ssize_t OsxUsbTransport::Write(const void* data, size_t len) { +int usb_write(usb_handle *h, const void *data, int len) { IOReturn result; if (len == 0) { return 0; } - if (handle_ == NULL) { + if (h == NULL) { return -1; } - if (handle_->interface == NULL) { + if (h->interface == NULL) { ERR("usb_write interface was null\n"); return -1; } - if (handle_->bulkOut == 0) { + if (h->bulkOut == 0) { ERR("bulkOut endpoint not assigned\n"); return -1; } #if 0 - result = (*handle_->interface)->WritePipe( - handle_->interface, handle_->bulkOut, (void *)data, len); + result = (*h->interface)->WritePipe( + h->interface, h->bulkOut, (void *)data, len); #else /* Attempt to work around crashes in the USB driver that may be caused * by trying to write too much data at once. The kernel IOCopyMapper @@ -565,8 +554,8 @@ ssize_t OsxUsbTransport::Write(const void* data, size_t len) { int lenToSend = lenRemaining > maxLenToSend ? maxLenToSend : lenRemaining; - result = (*handle_->interface)->WritePipe( - handle_->interface, handle_->bulkOut, (void *)data, lenToSend); + result = (*h->interface)->WritePipe( + h->interface, h->bulkOut, (void *)data, lenToSend); if (result != 0) break; lenRemaining -= lenToSend; @@ -575,11 +564,11 @@ ssize_t OsxUsbTransport::Write(const void* data, size_t len) { #endif #if 0 - if ((result == 0) && (handle_->zero_mask)) { + if ((result == 0) && (h->zero_mask)) { /* we need 0-markers and our transfer */ - if(!(len & handle_->zero_mask)) { - result = (*handle_->interface)->WritePipe( - handle_->interface, handle_->bulkOut, (void *)data, 0); + if(!(len & h->zero_mask)) { + result = (*h->interface)->WritePipe( + h->interface, h->bulkOut, (void *)data, 0); } } #endif diff --git a/fastboot/usb_windows.cpp b/fastboot/usb_windows.cpp index 443382d9a..a09610f5c 100644 --- a/fastboot/usb_windows.cpp +++ b/fastboot/usb_windows.cpp @@ -34,9 +34,6 @@ #include <stdio.h> #include <stdlib.h> -#include <memory> -#include <string> - #include "usb.h" //#define TRACE_USB 1 @@ -63,32 +60,24 @@ struct usb_handle { ADBAPIHANDLE adb_write_pipe; /// Interface name - std::string interface_name; -}; - -class WindowsUsbTransport : public Transport { - public: - WindowsUsbTransport(std::unique_ptr<usb_handle> handle) : handle_(std::move(handle)) {} - ~WindowsUsbTransport() override = default; - - ssize_t Read(void* data, size_t len) override; - ssize_t Write(const void* data, size_t len) override; - int Close() override; - - private: - std::unique_ptr<usb_handle> handle_; - - DISALLOW_COPY_AND_ASSIGN(WindowsUsbTransport); + char* interface_name; }; /// Class ID assigned to the device by androidusb.sys static const GUID usb_class_id = ANDROID_USB_CLASS_ID; + /// Checks if interface (device) matches certain criteria int recognized_device(usb_handle* handle, ifc_match_func callback); /// Opens usb interface (device) by interface (device) name. -std::unique_ptr<usb_handle> do_usb_open(const wchar_t* interface_name); +usb_handle* do_usb_open(const wchar_t* interface_name); + +/// Writes data to the opened usb handle +int usb_write(usb_handle* handle, const void* data, int len); + +/// Reads data using the opened usb handle +int usb_read(usb_handle *handle, void* data, int len); /// Cleans up opened usb handle void usb_cleanup_handle(usb_handle* handle); @@ -96,17 +85,23 @@ void usb_cleanup_handle(usb_handle* handle); /// Cleans up (but don't close) opened usb handle void usb_kick(usb_handle* handle); +/// Closes opened usb handle +int usb_close(usb_handle* handle); + -std::unique_ptr<usb_handle> do_usb_open(const wchar_t* interface_name) { +usb_handle* do_usb_open(const wchar_t* interface_name) { // Allocate our handle - std::unique_ptr<usb_handle> ret = new usb_handle; + usb_handle* ret = (usb_handle*)malloc(sizeof(usb_handle)); + if (NULL == ret) + return NULL; // Create interface. ret->adb_interface = AdbCreateInterfaceByName(interface_name); - if (nullptr == ret->adb_interface) { + if (NULL == ret->adb_interface) { + free(ret); errno = GetLastError(); - return nullptr; + return NULL; } // Open read pipe (endpoint) @@ -114,30 +109,35 @@ std::unique_ptr<usb_handle> do_usb_open(const wchar_t* interface_name) { AdbOpenDefaultBulkReadEndpoint(ret->adb_interface, AdbOpenAccessTypeReadWrite, AdbOpenSharingModeReadWrite); - if (nullptr != ret->adb_read_pipe) { + if (NULL != ret->adb_read_pipe) { // Open write pipe (endpoint) ret->adb_write_pipe = AdbOpenDefaultBulkWriteEndpoint(ret->adb_interface, AdbOpenAccessTypeReadWrite, AdbOpenSharingModeReadWrite); - if (nullptr != ret->adb_write_pipe) { + if (NULL != ret->adb_write_pipe) { // Save interface name unsigned long name_len = 0; // First get expected name length AdbGetInterfaceName(ret->adb_interface, - nullptr, + NULL, &name_len, true); if (0 != name_len) { - // Now save the name - ret->interface_name.resize(name_len); - if (AdbGetInterfaceName(ret->adb_interface, - &ret->interface_name[0], - &name_len, - true)) { - // We're done at this point - return ret; + ret->interface_name = (char*)malloc(name_len); + + if (NULL != ret->interface_name) { + // Now save the name + if (AdbGetInterfaceName(ret->adb_interface, + ret->interface_name, + &name_len, + true)) { + // We're done at this point + return ret; + } + } else { + SetLastError(ERROR_OUTOFMEMORY); } } } @@ -145,31 +145,35 @@ std::unique_ptr<usb_handle> do_usb_open(const wchar_t* interface_name) { // Something went wrong. errno = GetLastError(); - usb_cleanup_handle(ret.get()); + usb_cleanup_handle(ret); + free(ret); SetLastError(errno); - return nullptr; + return NULL; } -ssize_t WindowsUsbTransport::Write(const void* data, size_t len) { +int usb_write(usb_handle* handle, const void* data, int len) { unsigned long time_out = 5000; unsigned long written = 0; unsigned count = 0; int ret; DBG("usb_write %d\n", len); - if (nullptr != handle_) { + if (NULL != handle) { // Perform write while(len > 0) { int xfer = (len > MAX_USBFS_BULK_SIZE) ? MAX_USBFS_BULK_SIZE : len; - ret = AdbWriteEndpointSync(handle_->adb_write_pipe, const_cast<void*>(data), xfer, - &written, time_out); + ret = AdbWriteEndpointSync(handle->adb_write_pipe, + (void*)data, + (unsigned long)xfer, + &written, + time_out); errno = GetLastError(); DBG("AdbWriteEndpointSync returned %d, errno: %d\n", ret, errno); if (ret == 0) { // assume ERROR_INVALID_HANDLE indicates we are disconnected if (errno == ERROR_INVALID_HANDLE) - usb_kick(handle_.get()); + usb_kick(handle); return -1; } @@ -190,17 +194,21 @@ ssize_t WindowsUsbTransport::Write(const void* data, size_t len) { return -1; } -ssize_t WindowsUsbTransport::Read(void* data, size_t len) { +int usb_read(usb_handle *handle, void* data, int len) { unsigned long time_out = 0; unsigned long read = 0; int ret; DBG("usb_read %d\n", len); - if (nullptr != handle_) { + if (NULL != handle) { while (1) { int xfer = (len > MAX_USBFS_BULK_SIZE) ? MAX_USBFS_BULK_SIZE : len; - ret = AdbReadEndpointSync(handle_->adb_read_pipe, data, xfer, &read, time_out); + ret = AdbReadEndpointSync(handle->adb_read_pipe, + (void*)data, + (unsigned long)xfer, + &read, + time_out); errno = GetLastError(); DBG("usb_read got: %ld, expected: %d, errno: %d\n", read, xfer, errno); if (ret) { @@ -208,7 +216,7 @@ ssize_t WindowsUsbTransport::Read(void* data, size_t len) { } else { // assume ERROR_INVALID_HANDLE indicates we are disconnected if (errno == ERROR_INVALID_HANDLE) - usb_kick(handle_.get()); + usb_kick(handle); break; } // else we timed out - try again @@ -225,6 +233,8 @@ ssize_t WindowsUsbTransport::Read(void* data, size_t len) { void usb_cleanup_handle(usb_handle* handle) { if (NULL != handle) { + if (NULL != handle->interface_name) + free(handle->interface_name); if (NULL != handle->adb_write_pipe) AdbCloseHandle(handle->adb_write_pipe); if (NULL != handle->adb_read_pipe) @@ -232,7 +242,7 @@ void usb_cleanup_handle(usb_handle* handle) { if (NULL != handle->adb_interface) AdbCloseHandle(handle->adb_interface); - handle->interface_name.clear(); + handle->interface_name = NULL; handle->adb_write_pipe = NULL; handle->adb_read_pipe = NULL; handle->adb_interface = NULL; @@ -248,18 +258,23 @@ void usb_kick(usb_handle* handle) { } } -int WindowsUsbTransport::Close() { +int usb_close(usb_handle* handle) { DBG("usb_close\n"); - if (nullptr != handle_) { + if (NULL != handle) { // Cleanup handle - usb_cleanup_handle(handle_.get()); - handle_.reset(); + usb_cleanup_handle(handle); + free(handle); } return 0; } +int usb_wait_for_disconnect(usb_handle *usb) { + /* TODO: Punt for now */ + return 0; +} + int recognized_device(usb_handle* handle, ifc_match_func callback) { struct usb_ifc_info info; USB_DEVICE_DESCRIPTOR device_desc; @@ -311,8 +326,8 @@ int recognized_device(usb_handle* handle, ifc_match_func callback) { return 0; } -static std::unique_ptr<usb_handle> find_usb_device(ifc_match_func callback) { - std::unique_ptr<usb_handle> handle; +static usb_handle *find_usb_device(ifc_match_func callback) { + usb_handle* handle = NULL; char entry_buffer[2048]; char interf_name[2048]; AdbInterfaceInfo* next_interface = (AdbInterfaceInfo*)(&entry_buffer[0]); @@ -341,12 +356,13 @@ static std::unique_ptr<usb_handle> find_usb_device(ifc_match_func callback) { handle = do_usb_open(next_interface->device_name); if (NULL != handle) { // Lets see if this interface (device) belongs to us - if (recognized_device(handle.get(), callback)) { + if (recognized_device(handle, callback)) { // found it! break; } else { - usb_cleanup_handle(handle.get()); - handle.reset(); + usb_cleanup_handle(handle); + free(handle); + handle = NULL; } } @@ -357,10 +373,9 @@ static std::unique_ptr<usb_handle> find_usb_device(ifc_match_func callback) { return handle; } -Transport* usb_open(ifc_match_func callback) +usb_handle *usb_open(ifc_match_func callback) { - std::unique_ptr<usb_handle> handle = find_usb_device(callback); - return handle ? new WindowsUsbTransport(std::move(handle)) : nullptr; + return find_usb_device(callback); } // called from fastboot.c diff --git a/fastboot/usbtest.cpp b/fastboot/usbtest.cpp index 9423c6d96..e6e2b37e0 100644 --- a/fastboot/usbtest.cpp +++ b/fastboot/usbtest.cpp @@ -86,7 +86,7 @@ int match_loop(usb_ifc_info *info) return 0; } -int test_null(Transport* usb) +int test_null(usb_handle *usb) { unsigned i; unsigned char buf[4096]; @@ -94,8 +94,8 @@ int test_null(Transport* usb) long long t0, t1; t0 = NOW(); - for (i = 0; i < arg_count; i++) { - if (usb->Write(buf, arg_size) != static_cast<int>(arg_size)) { + for(i = 0; i < arg_count; i++) { + if(usb_write(usb, buf, arg_size) != (int)arg_size) { fprintf(stderr,"write failed (%s)\n", strerror(errno)); return -1; } @@ -105,15 +105,15 @@ int test_null(Transport* usb) return 0; } -int test_zero(Transport* usb) +int test_zero(usb_handle *usb) { unsigned i; unsigned char buf[4096]; long long t0, t1; t0 = NOW(); - for (i = 0; i < arg_count; i++) { - if (usb->Read(buf, arg_size) != static_cast<int>(arg_size)) { + for(i = 0; i < arg_count; i++) { + if(usb_read(usb, buf, arg_size) != (int)arg_size) { fprintf(stderr,"read failed (%s)\n", strerror(errno)); return -1; } @@ -127,7 +127,7 @@ struct { const char *cmd; ifc_match_func match; - int (*test)(Transport* usb); + int (*test)(usb_handle *usb); const char *help; } tests[] = { { "list", printifc, NULL, "list interfaces" }, @@ -177,7 +177,7 @@ int process_args(int argc, char **argv) int main(int argc, char **argv) { - Transport* usb; + usb_handle *usb; int i; if(argc < 2) |