fastboot: create Transport object.
This CL creates a Transport object to provide a generic interface for various transports. Specifically this is designed to be able to add UDP support to fastboot in an upcoming CL without changing the main program logic. Also includes some minor code style fixes and replaces malloc/free in the USB implementation files with smart pointers and std::string. Bug: http://b/22029765 Change-Id: I68641af0da7d13db4647f5e20a18d04d67f0b327
This commit is contained in:
parent
ab75edb4ad
commit
6f233a7799
|
@ -83,5 +83,6 @@ 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
|
||||
|
|
|
@ -75,13 +75,13 @@ static Action *action_last = 0;
|
|||
|
||||
|
||||
|
||||
bool fb_getvar(usb_handle* usb, const std::string& key, std::string* value) {
|
||||
bool fb_getvar(Transport* transport, 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(usb, cmd.c_str(), buf)) {
|
||||
if (fb_command_response(transport, 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(usb_handle *usb)
|
||||
int fb_execute_queue(Transport* transport)
|
||||
{
|
||||
Action *a;
|
||||
char resp[FB_RESPONSE_SZ+1];
|
||||
|
@ -350,25 +350,25 @@ int fb_execute_queue(usb_handle *usb)
|
|||
fprintf(stderr,"%s...\n",a->msg);
|
||||
}
|
||||
if (a->op == OP_DOWNLOAD) {
|
||||
status = fb_download_data(usb, a->data, a->size);
|
||||
status = fb_download_data(transport, 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(usb, a->cmd);
|
||||
status = fb_command(transport, a->cmd);
|
||||
status = a->func(a, status, status ? fb_get_error() : "");
|
||||
if (status) break;
|
||||
} else if (a->op == OP_QUERY) {
|
||||
status = fb_command_response(usb, a->cmd, resp);
|
||||
status = fb_command_response(transport, 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(usb, reinterpret_cast<sparse_file*>(a->data));
|
||||
status = fb_download_data_sparse(transport, 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) {
|
||||
usb_wait_for_disconnect(usb);
|
||||
transport->WaitForDisconnect();
|
||||
} else {
|
||||
die("bogus action");
|
||||
}
|
||||
|
|
|
@ -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", ¤t_slot)) {
|
||||
if (!fb_getvar(transport, "current-slot", ¤t_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;
|
||||
}
|
||||
|
|
|
@ -34,22 +34,22 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
#include "usb.h"
|
||||
#include "transport.h"
|
||||
|
||||
struct sparse_file;
|
||||
|
||||
/* protocol.c - fastboot protocol */
|
||||
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);
|
||||
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);
|
||||
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(usb_handle* usb, const std::string& key, std::string* value);
|
||||
bool fb_getvar(Transport* transport, 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(usb_handle *usb);
|
||||
int fb_execute_queue(Transport* transport);
|
||||
void fb_set_active(const char *slot);
|
||||
|
||||
/* util stuff */
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include <sparse/sparse.h>
|
||||
|
||||
#include "fastboot.h"
|
||||
#include "transport.h"
|
||||
|
||||
static char ERROR[128];
|
||||
|
||||
|
@ -47,21 +48,21 @@ char *fb_get_error(void)
|
|||
return ERROR;
|
||||
}
|
||||
|
||||
static int check_response(usb_handle* usb, uint32_t size, char* response) {
|
||||
static int check_response(Transport* transport, uint32_t size, char* response) {
|
||||
char status[65];
|
||||
|
||||
while (true) {
|
||||
int r = usb_read(usb, status, 64);
|
||||
int r = transport->Read(status, 64);
|
||||
if (r < 0) {
|
||||
sprintf(ERROR, "status read failed (%s)", strerror(errno));
|
||||
usb_close(usb);
|
||||
transport->Close();
|
||||
return -1;
|
||||
}
|
||||
status[r] = 0;
|
||||
|
||||
if (r < 4) {
|
||||
sprintf(ERROR, "status malformed (%d bytes)", r);
|
||||
usb_close(usb);
|
||||
transport->Close();
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -90,21 +91,21 @@ static int check_response(usb_handle* usb, uint32_t size, char* response) {
|
|||
uint32_t dsize = strtol(status + 4, 0, 16);
|
||||
if (dsize > size) {
|
||||
strcpy(ERROR, "data size too large");
|
||||
usb_close(usb);
|
||||
transport->Close();
|
||||
return -1;
|
||||
}
|
||||
return dsize;
|
||||
}
|
||||
|
||||
strcpy(ERROR,"unknown status code");
|
||||
usb_close(usb);
|
||||
transport->Close();
|
||||
break;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int _command_start(usb_handle* usb, const char* cmd, uint32_t size, char* response) {
|
||||
static int _command_start(Transport* transport, const char* cmd, uint32_t size, char* response) {
|
||||
size_t cmdsize = strlen(cmd);
|
||||
if (cmdsize > 64) {
|
||||
sprintf(ERROR, "command too large");
|
||||
|
@ -115,51 +116,51 @@ static int _command_start(usb_handle* usb, const char* cmd, uint32_t size, char*
|
|||
response[0] = 0;
|
||||
}
|
||||
|
||||
if (usb_write(usb, cmd, cmdsize) != static_cast<int>(cmdsize)) {
|
||||
if (transport->Write(cmd, cmdsize) != static_cast<int>(cmdsize)) {
|
||||
sprintf(ERROR, "command write failed (%s)", strerror(errno));
|
||||
usb_close(usb);
|
||||
transport->Close();
|
||||
return -1;
|
||||
}
|
||||
|
||||
return check_response(usb, size, response);
|
||||
return check_response(transport, size, response);
|
||||
}
|
||||
|
||||
static int _command_data(usb_handle* usb, const void* data, uint32_t size) {
|
||||
int r = usb_write(usb, data, size);
|
||||
static int _command_data(Transport* transport, const void* data, uint32_t size) {
|
||||
int r = transport->Write(data, size);
|
||||
if (r < 0) {
|
||||
sprintf(ERROR, "data transfer failure (%s)", strerror(errno));
|
||||
usb_close(usb);
|
||||
transport->Close();
|
||||
return -1;
|
||||
}
|
||||
if (r != ((int) size)) {
|
||||
sprintf(ERROR, "data transfer failure (short transfer)");
|
||||
usb_close(usb);
|
||||
transport->Close();
|
||||
return -1;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
static int _command_end(usb_handle* usb) {
|
||||
return check_response(usb, 0, 0) < 0 ? -1 : 0;
|
||||
static int _command_end(Transport* transport) {
|
||||
return check_response(transport, 0, 0) < 0 ? -1 : 0;
|
||||
}
|
||||
|
||||
static int _command_send(usb_handle* usb, const char* cmd, const void* data, uint32_t size,
|
||||
static int _command_send(Transport* transport, const char* cmd, const void* data, uint32_t size,
|
||||
char* response) {
|
||||
if (size == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int r = _command_start(usb, cmd, size, response);
|
||||
int r = _command_start(transport, cmd, size, response);
|
||||
if (r < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
r = _command_data(usb, data, size);
|
||||
r = _command_data(transport, data, size);
|
||||
if (r < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
r = _command_end(usb);
|
||||
r = _command_end(transport);
|
||||
if (r < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -167,59 +168,59 @@ static int _command_send(usb_handle* usb, const char* cmd, const void* data, uin
|
|||
return size;
|
||||
}
|
||||
|
||||
static int _command_send_no_data(usb_handle* usb, const char* cmd, char* response) {
|
||||
return _command_start(usb, cmd, 0, response);
|
||||
static int _command_send_no_data(Transport* transport, const char* cmd, char* response) {
|
||||
return _command_start(transport, cmd, 0, response);
|
||||
}
|
||||
|
||||
int fb_command(usb_handle* usb, const char* cmd) {
|
||||
return _command_send_no_data(usb, cmd, 0);
|
||||
int fb_command(Transport* transport, const char* cmd) {
|
||||
return _command_send_no_data(transport, cmd, 0);
|
||||
}
|
||||
|
||||
int fb_command_response(usb_handle* usb, const char* cmd, char* response) {
|
||||
return _command_send_no_data(usb, cmd, response);
|
||||
int fb_command_response(Transport* transport, const char* cmd, char* response) {
|
||||
return _command_send_no_data(transport, cmd, response);
|
||||
}
|
||||
|
||||
int fb_download_data(usb_handle* usb, const void* data, uint32_t size) {
|
||||
int fb_download_data(Transport* transport, const void* data, uint32_t size) {
|
||||
char cmd[64];
|
||||
sprintf(cmd, "download:%08x", size);
|
||||
return _command_send(usb, cmd, data, size, 0) < 0 ? -1 : 0;
|
||||
return _command_send(transport, cmd, data, size, 0) < 0 ? -1 : 0;
|
||||
}
|
||||
|
||||
#define USB_BUF_SIZE 1024
|
||||
static char usb_buf[USB_BUF_SIZE];
|
||||
static int usb_buf_len;
|
||||
#define TRANSPORT_BUF_SIZE 1024
|
||||
static char transport_buf[TRANSPORT_BUF_SIZE];
|
||||
static int transport_buf_len;
|
||||
|
||||
static int fb_download_data_sparse_write(void *priv, const void *data, int len)
|
||||
{
|
||||
int r;
|
||||
usb_handle* usb = reinterpret_cast<usb_handle*>(priv);
|
||||
Transport* transport = reinterpret_cast<Transport*>(priv);
|
||||
int to_write;
|
||||
const char* ptr = reinterpret_cast<const char*>(data);
|
||||
|
||||
if (usb_buf_len) {
|
||||
to_write = std::min(USB_BUF_SIZE - usb_buf_len, len);
|
||||
if (transport_buf_len) {
|
||||
to_write = std::min(TRANSPORT_BUF_SIZE - transport_buf_len, len);
|
||||
|
||||
memcpy(usb_buf + usb_buf_len, ptr, to_write);
|
||||
usb_buf_len += to_write;
|
||||
memcpy(transport_buf + transport_buf_len, ptr, to_write);
|
||||
transport_buf_len += to_write;
|
||||
ptr += to_write;
|
||||
len -= to_write;
|
||||
}
|
||||
|
||||
if (usb_buf_len == USB_BUF_SIZE) {
|
||||
r = _command_data(usb, usb_buf, USB_BUF_SIZE);
|
||||
if (r != USB_BUF_SIZE) {
|
||||
if (transport_buf_len == TRANSPORT_BUF_SIZE) {
|
||||
r = _command_data(transport, transport_buf, TRANSPORT_BUF_SIZE);
|
||||
if (r != TRANSPORT_BUF_SIZE) {
|
||||
return -1;
|
||||
}
|
||||
usb_buf_len = 0;
|
||||
transport_buf_len = 0;
|
||||
}
|
||||
|
||||
if (len > USB_BUF_SIZE) {
|
||||
if (usb_buf_len > 0) {
|
||||
sprintf(ERROR, "internal error: usb_buf not empty\n");
|
||||
if (len > TRANSPORT_BUF_SIZE) {
|
||||
if (transport_buf_len > 0) {
|
||||
sprintf(ERROR, "internal error: transport_buf not empty\n");
|
||||
return -1;
|
||||
}
|
||||
to_write = round_down(len, USB_BUF_SIZE);
|
||||
r = _command_data(usb, ptr, to_write);
|
||||
to_write = round_down(len, TRANSPORT_BUF_SIZE);
|
||||
r = _command_data(transport, ptr, to_write);
|
||||
if (r != to_write) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -228,28 +229,28 @@ static int fb_download_data_sparse_write(void *priv, const void *data, int len)
|
|||
}
|
||||
|
||||
if (len > 0) {
|
||||
if (len > USB_BUF_SIZE) {
|
||||
sprintf(ERROR, "internal error: too much left for usb_buf\n");
|
||||
if (len > TRANSPORT_BUF_SIZE) {
|
||||
sprintf(ERROR, "internal error: too much left for transport_buf\n");
|
||||
return -1;
|
||||
}
|
||||
memcpy(usb_buf, ptr, len);
|
||||
usb_buf_len = len;
|
||||
memcpy(transport_buf, ptr, len);
|
||||
transport_buf_len = len;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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) {
|
||||
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) {
|
||||
return -1;
|
||||
}
|
||||
usb_buf_len = 0;
|
||||
transport_buf_len = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fb_download_data_sparse(usb_handle* usb, struct sparse_file* s) {
|
||||
int fb_download_data_sparse(Transport* transport, struct sparse_file* s) {
|
||||
int size = sparse_file_len(s, true, false);
|
||||
if (size <= 0) {
|
||||
return -1;
|
||||
|
@ -257,20 +258,20 @@ int fb_download_data_sparse(usb_handle* usb, struct sparse_file* s) {
|
|||
|
||||
char cmd[64];
|
||||
sprintf(cmd, "download:%08x", size);
|
||||
int r = _command_start(usb, cmd, size, 0);
|
||||
int r = _command_start(transport, cmd, size, 0);
|
||||
if (r < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
r = sparse_file_callback(s, true, false, fb_download_data_sparse_write, usb);
|
||||
r = sparse_file_callback(s, true, false, fb_download_data_sparse_write, transport);
|
||||
if (r < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
r = fb_download_data_sparse_flush(usb);
|
||||
r = fb_download_data_sparse_flush(transport);
|
||||
if (r < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return _command_end(usb);
|
||||
return _command_end(transport);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* 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_
|
|
@ -29,7 +29,7 @@
|
|||
#ifndef _USB_H_
|
||||
#define _USB_H_
|
||||
|
||||
struct usb_handle;
|
||||
#include "transport.h"
|
||||
|
||||
struct usb_ifc_info {
|
||||
/* from device descriptor */
|
||||
|
@ -55,10 +55,6 @@ struct usb_ifc_info {
|
|||
|
||||
typedef int (*ifc_match_func)(usb_ifc_info *ifc);
|
||||
|
||||
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);
|
||||
Transport* usb_open(ifc_match_func callback);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -43,6 +43,8 @@
|
|||
#include <linux/version.h>
|
||||
#include <linux/usb/ch9.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "fastboot.h"
|
||||
#include "usb.h"
|
||||
|
||||
|
@ -85,6 +87,22 @@ 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').
|
||||
|
@ -308,9 +326,9 @@ static int convert_to_devfs_name(const char* sysfs_name,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static usb_handle *find_usb_device(const char *base, ifc_match_func callback)
|
||||
static std::unique_ptr<usb_handle> find_usb_device(const char* base, ifc_match_func callback)
|
||||
{
|
||||
usb_handle *usb = 0;
|
||||
std::unique_ptr<usb_handle> usb;
|
||||
char devname[64];
|
||||
char desc[1024];
|
||||
int n, in, out, ifc;
|
||||
|
@ -321,39 +339,37 @@ static usb_handle *find_usb_device(const char *base, ifc_match_func callback)
|
|||
int writable;
|
||||
|
||||
busdir = opendir(base);
|
||||
if(busdir == 0) return 0;
|
||||
if (busdir == 0) return 0;
|
||||
|
||||
while((de = readdir(busdir)) && (usb == 0)) {
|
||||
if(badname(de->d_name)) continue;
|
||||
while ((de = readdir(busdir)) && (usb == nullptr)) {
|
||||
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 = reinterpret_cast<usb_handle*>(calloc(1, sizeof(usb_handle)));
|
||||
if (filter_usb_device(de->d_name, desc, n, writable, callback, &in, &out, &ifc) == 0) {
|
||||
usb.reset(new 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);
|
||||
free(usb);
|
||||
usb = 0;
|
||||
usb.reset();
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
|
@ -366,14 +382,14 @@ static usb_handle *find_usb_device(const char *base, ifc_match_func callback)
|
|||
return usb;
|
||||
}
|
||||
|
||||
int usb_write(usb_handle *h, const void *_data, int len)
|
||||
ssize_t LinuxUsbTransport::Write(const void* _data, size_t len)
|
||||
{
|
||||
unsigned char *data = (unsigned char*) _data;
|
||||
unsigned count = 0;
|
||||
struct usbdevfs_bulktransfer bulk;
|
||||
int n;
|
||||
|
||||
if(h->ep_out == 0 || h->desc == -1) {
|
||||
if (handle_->ep_out == 0 || handle_->desc == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -381,12 +397,12 @@ int usb_write(usb_handle *h, const void *_data, int len)
|
|||
int xfer;
|
||||
xfer = (len > MAX_USBFS_BULK_SIZE) ? MAX_USBFS_BULK_SIZE : len;
|
||||
|
||||
bulk.ep = h->ep_out;
|
||||
bulk.ep = handle_->ep_out;
|
||||
bulk.len = xfer;
|
||||
bulk.data = data;
|
||||
bulk.timeout = 0;
|
||||
|
||||
n = ioctl(h->desc, USBDEVFS_BULK, &bulk);
|
||||
n = ioctl(handle_->desc, USBDEVFS_BULK, &bulk);
|
||||
if(n != xfer) {
|
||||
DBG("ERROR: n = %d, errno = %d (%s)\n",
|
||||
n, errno, strerror(errno));
|
||||
|
@ -401,30 +417,30 @@ int usb_write(usb_handle *h, const void *_data, int len)
|
|||
return count;
|
||||
}
|
||||
|
||||
int usb_read(usb_handle *h, void *_data, int len)
|
||||
ssize_t LinuxUsbTransport::Read(void* _data, size_t len)
|
||||
{
|
||||
unsigned char *data = (unsigned char*) _data;
|
||||
unsigned count = 0;
|
||||
struct usbdevfs_bulktransfer bulk;
|
||||
int n, retry;
|
||||
|
||||
if(h->ep_in == 0 || h->desc == -1) {
|
||||
if (handle_->ep_in == 0 || handle_->desc == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
while(len > 0) {
|
||||
int xfer = (len > MAX_USBFS_BULK_SIZE) ? MAX_USBFS_BULK_SIZE : len;
|
||||
|
||||
bulk.ep = h->ep_in;
|
||||
bulk.ep = handle_->ep_in;
|
||||
bulk.len = xfer;
|
||||
bulk.data = data;
|
||||
bulk.timeout = 0;
|
||||
retry = 0;
|
||||
|
||||
do{
|
||||
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);
|
||||
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);
|
||||
|
||||
if( n < 0 ) {
|
||||
DBG1("ERROR: n = %d, errno = %d (%s)\n",n, errno, strerror(errno));
|
||||
|
@ -446,24 +462,12 @@ int usb_read(usb_handle *h, void *_data, int len)
|
|||
return count;
|
||||
}
|
||||
|
||||
void usb_kick(usb_handle *h)
|
||||
int LinuxUsbTransport::Close()
|
||||
{
|
||||
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 = h->desc;
|
||||
h->desc = -1;
|
||||
fd = handle_->desc;
|
||||
handle_->desc = -1;
|
||||
if(fd >= 0) {
|
||||
close(fd);
|
||||
DBG("[ usb closed %d ]\n", fd);
|
||||
|
@ -472,20 +476,21 @@ int usb_close(usb_handle *h)
|
|||
return 0;
|
||||
}
|
||||
|
||||
usb_handle *usb_open(ifc_match_func callback)
|
||||
Transport* usb_open(ifc_match_func callback)
|
||||
{
|
||||
return find_usb_device("/sys/bus/usb/devices", callback);
|
||||
std::unique_ptr<usb_handle> handle = find_usb_device("/sys/bus/usb/devices", callback);
|
||||
return handle ? new LinuxUsbTransport(std::move(handle)) : nullptr;
|
||||
}
|
||||
|
||||
/* 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 usb_wait_for_disconnect(usb_handle *usb)
|
||||
int LinuxUsbTransport::WaitForDisconnect()
|
||||
{
|
||||
double deadline = now() + WAIT_FOR_DISCONNECT_TIMEOUT;
|
||||
while (now() < deadline) {
|
||||
if (access(usb->fname, F_OK))
|
||||
if (access(handle_->fname, F_OK))
|
||||
return 0;
|
||||
usleep(50000);
|
||||
}
|
||||
|
|
|
@ -35,6 +35,8 @@
|
|||
#include <IOKit/IOMessage.h>
|
||||
#include <mach/mach_port.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "usb.h"
|
||||
|
||||
|
||||
|
@ -63,6 +65,21 @@ 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) {
|
||||
|
@ -390,7 +407,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, usb_handle **handle) {
|
||||
static int init_usb(ifc_match_func callback, std::unique_ptr<usb_handle>* handle) {
|
||||
int ret = -1;
|
||||
CFMutableDictionaryRef matchingDict;
|
||||
kern_return_t result;
|
||||
|
@ -443,8 +460,8 @@ static int init_usb(ifc_match_func callback, usb_handle **handle) {
|
|||
}
|
||||
|
||||
if (h.success) {
|
||||
*handle = reinterpret_cast<usb_handle*>(calloc(1, sizeof(usb_handle)));
|
||||
memcpy(*handle, &h, sizeof(usb_handle));
|
||||
handle->reset(new usb_handle);
|
||||
memcpy(handle->get(), &h, sizeof(usb_handle));
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
@ -463,28 +480,23 @@ static int init_usb(ifc_match_func callback, usb_handle **handle) {
|
|||
* Definitions of this file's public functions.
|
||||
*/
|
||||
|
||||
usb_handle *usb_open(ifc_match_func callback) {
|
||||
usb_handle *handle = NULL;
|
||||
Transport* usb_open(ifc_match_func callback) {
|
||||
std::unique_ptr<usb_handle> handle;
|
||||
|
||||
if (init_usb(callback, &handle) < 0) {
|
||||
/* Something went wrong initializing USB. */
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return handle;
|
||||
return new OsxUsbTransport(std::move(handle));
|
||||
}
|
||||
|
||||
int usb_close(usb_handle *h) {
|
||||
int OsxUsbTransport::Close() {
|
||||
/* TODO: Something better here? */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usb_wait_for_disconnect(usb_handle *usb) {
|
||||
/* TODO: Punt for now */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usb_read(usb_handle *h, void *data, int len) {
|
||||
ssize_t OsxUsbTransport::Read(void* data, size_t len) {
|
||||
IOReturn result;
|
||||
UInt32 numBytes = len;
|
||||
|
||||
|
@ -492,22 +504,21 @@ int usb_read(usb_handle *h, void *data, int len) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (h == NULL) {
|
||||
if (handle_ == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (h->interface == NULL) {
|
||||
if (handle_->interface == nullptr) {
|
||||
ERR("usb_read interface was null\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (h->bulkIn == 0) {
|
||||
if (handle_->bulkIn == 0) {
|
||||
ERR("bulkIn endpoint not assigned\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
result = (*h->interface)->ReadPipe(
|
||||
h->interface, h->bulkIn, data, &numBytes);
|
||||
result = (*handle_->interface)->ReadPipe(handle_->interface, handle_->bulkIn, data, &numBytes);
|
||||
|
||||
if (result == 0) {
|
||||
return (int) numBytes;
|
||||
|
@ -518,30 +529,30 @@ int usb_read(usb_handle *h, void *data, int len) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
int usb_write(usb_handle *h, const void *data, int len) {
|
||||
ssize_t OsxUsbTransport::Write(const void* data, size_t len) {
|
||||
IOReturn result;
|
||||
|
||||
if (len == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (h == NULL) {
|
||||
if (handle_ == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (h->interface == NULL) {
|
||||
if (handle_->interface == NULL) {
|
||||
ERR("usb_write interface was null\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (h->bulkOut == 0) {
|
||||
if (handle_->bulkOut == 0) {
|
||||
ERR("bulkOut endpoint not assigned\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
result = (*h->interface)->WritePipe(
|
||||
h->interface, h->bulkOut, (void *)data, len);
|
||||
result = (*handle_->interface)->WritePipe(
|
||||
handle_->interface, handle_->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
|
||||
|
@ -554,8 +565,8 @@ int usb_write(usb_handle *h, const void *data, int len) {
|
|||
int lenToSend = lenRemaining > maxLenToSend
|
||||
? maxLenToSend : lenRemaining;
|
||||
|
||||
result = (*h->interface)->WritePipe(
|
||||
h->interface, h->bulkOut, (void *)data, lenToSend);
|
||||
result = (*handle_->interface)->WritePipe(
|
||||
handle_->interface, handle_->bulkOut, (void *)data, lenToSend);
|
||||
if (result != 0) break;
|
||||
|
||||
lenRemaining -= lenToSend;
|
||||
|
@ -564,11 +575,11 @@ int usb_write(usb_handle *h, const void *data, int len) {
|
|||
#endif
|
||||
|
||||
#if 0
|
||||
if ((result == 0) && (h->zero_mask)) {
|
||||
if ((result == 0) && (handle_->zero_mask)) {
|
||||
/* we need 0-markers and our transfer */
|
||||
if(!(len & h->zero_mask)) {
|
||||
result = (*h->interface)->WritePipe(
|
||||
h->interface, h->bulkOut, (void *)data, 0);
|
||||
if(!(len & handle_->zero_mask)) {
|
||||
result = (*handle_->interface)->WritePipe(
|
||||
handle_->interface, handle_->bulkOut, (void *)data, 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -34,6 +34,9 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "usb.h"
|
||||
|
||||
//#define TRACE_USB 1
|
||||
|
@ -60,24 +63,32 @@ struct usb_handle {
|
|||
ADBAPIHANDLE adb_write_pipe;
|
||||
|
||||
/// Interface name
|
||||
char* 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);
|
||||
};
|
||||
|
||||
/// 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.
|
||||
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);
|
||||
std::unique_ptr<usb_handle> do_usb_open(const wchar_t* interface_name);
|
||||
|
||||
/// Cleans up opened usb handle
|
||||
void usb_cleanup_handle(usb_handle* handle);
|
||||
|
@ -85,23 +96,17 @@ 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);
|
||||
|
||||
|
||||
usb_handle* do_usb_open(const wchar_t* interface_name) {
|
||||
std::unique_ptr<usb_handle> do_usb_open(const wchar_t* interface_name) {
|
||||
// Allocate our handle
|
||||
usb_handle* ret = (usb_handle*)malloc(sizeof(usb_handle));
|
||||
if (NULL == ret)
|
||||
return NULL;
|
||||
std::unique_ptr<usb_handle> ret = new usb_handle;
|
||||
|
||||
// Create interface.
|
||||
ret->adb_interface = AdbCreateInterfaceByName(interface_name);
|
||||
|
||||
if (NULL == ret->adb_interface) {
|
||||
free(ret);
|
||||
if (nullptr == ret->adb_interface) {
|
||||
errno = GetLastError();
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Open read pipe (endpoint)
|
||||
|
@ -109,35 +114,30 @@ usb_handle* do_usb_open(const wchar_t* interface_name) {
|
|||
AdbOpenDefaultBulkReadEndpoint(ret->adb_interface,
|
||||
AdbOpenAccessTypeReadWrite,
|
||||
AdbOpenSharingModeReadWrite);
|
||||
if (NULL != ret->adb_read_pipe) {
|
||||
if (nullptr != ret->adb_read_pipe) {
|
||||
// Open write pipe (endpoint)
|
||||
ret->adb_write_pipe =
|
||||
AdbOpenDefaultBulkWriteEndpoint(ret->adb_interface,
|
||||
AdbOpenAccessTypeReadWrite,
|
||||
AdbOpenSharingModeReadWrite);
|
||||
if (NULL != ret->adb_write_pipe) {
|
||||
if (nullptr != ret->adb_write_pipe) {
|
||||
// Save interface name
|
||||
unsigned long name_len = 0;
|
||||
|
||||
// First get expected name length
|
||||
AdbGetInterfaceName(ret->adb_interface,
|
||||
NULL,
|
||||
nullptr,
|
||||
&name_len,
|
||||
true);
|
||||
if (0 != name_len) {
|
||||
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);
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -145,35 +145,31 @@ usb_handle* do_usb_open(const wchar_t* interface_name) {
|
|||
|
||||
// Something went wrong.
|
||||
errno = GetLastError();
|
||||
usb_cleanup_handle(ret);
|
||||
free(ret);
|
||||
usb_cleanup_handle(ret.get());
|
||||
SetLastError(errno);
|
||||
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int usb_write(usb_handle* handle, const void* data, int len) {
|
||||
ssize_t WindowsUsbTransport::Write(const void* data, size_t len) {
|
||||
unsigned long time_out = 5000;
|
||||
unsigned long written = 0;
|
||||
unsigned count = 0;
|
||||
int ret;
|
||||
|
||||
DBG("usb_write %d\n", len);
|
||||
if (NULL != handle) {
|
||||
if (nullptr != handle_) {
|
||||
// Perform write
|
||||
while(len > 0) {
|
||||
int xfer = (len > MAX_USBFS_BULK_SIZE) ? MAX_USBFS_BULK_SIZE : len;
|
||||
ret = AdbWriteEndpointSync(handle->adb_write_pipe,
|
||||
(void*)data,
|
||||
(unsigned long)xfer,
|
||||
&written,
|
||||
time_out);
|
||||
ret = AdbWriteEndpointSync(handle_->adb_write_pipe, const_cast<void*>(data), 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);
|
||||
usb_kick(handle_.get());
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -194,21 +190,17 @@ int usb_write(usb_handle* handle, const void* data, int len) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
int usb_read(usb_handle *handle, void* data, int len) {
|
||||
ssize_t WindowsUsbTransport::Read(void* data, size_t len) {
|
||||
unsigned long time_out = 0;
|
||||
unsigned long read = 0;
|
||||
int ret;
|
||||
|
||||
DBG("usb_read %d\n", len);
|
||||
if (NULL != handle) {
|
||||
if (nullptr != handle_) {
|
||||
while (1) {
|
||||
int xfer = (len > MAX_USBFS_BULK_SIZE) ? MAX_USBFS_BULK_SIZE : len;
|
||||
|
||||
ret = AdbReadEndpointSync(handle->adb_read_pipe,
|
||||
(void*)data,
|
||||
(unsigned long)xfer,
|
||||
&read,
|
||||
time_out);
|
||||
ret = AdbReadEndpointSync(handle_->adb_read_pipe, data, xfer, &read, time_out);
|
||||
errno = GetLastError();
|
||||
DBG("usb_read got: %ld, expected: %d, errno: %d\n", read, xfer, errno);
|
||||
if (ret) {
|
||||
|
@ -216,7 +208,7 @@ int usb_read(usb_handle *handle, void* data, int len) {
|
|||
} else {
|
||||
// assume ERROR_INVALID_HANDLE indicates we are disconnected
|
||||
if (errno == ERROR_INVALID_HANDLE)
|
||||
usb_kick(handle);
|
||||
usb_kick(handle_.get());
|
||||
break;
|
||||
}
|
||||
// else we timed out - try again
|
||||
|
@ -233,8 +225,6 @@ int usb_read(usb_handle *handle, void* data, int 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)
|
||||
|
@ -242,7 +232,7 @@ void usb_cleanup_handle(usb_handle* handle) {
|
|||
if (NULL != handle->adb_interface)
|
||||
AdbCloseHandle(handle->adb_interface);
|
||||
|
||||
handle->interface_name = NULL;
|
||||
handle->interface_name.clear();
|
||||
handle->adb_write_pipe = NULL;
|
||||
handle->adb_read_pipe = NULL;
|
||||
handle->adb_interface = NULL;
|
||||
|
@ -258,23 +248,18 @@ void usb_kick(usb_handle* handle) {
|
|||
}
|
||||
}
|
||||
|
||||
int usb_close(usb_handle* handle) {
|
||||
int WindowsUsbTransport::Close() {
|
||||
DBG("usb_close\n");
|
||||
|
||||
if (NULL != handle) {
|
||||
if (nullptr != handle_) {
|
||||
// Cleanup handle
|
||||
usb_cleanup_handle(handle);
|
||||
free(handle);
|
||||
usb_cleanup_handle(handle_.get());
|
||||
handle_.reset();
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -326,8 +311,8 @@ int recognized_device(usb_handle* handle, ifc_match_func callback) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static usb_handle *find_usb_device(ifc_match_func callback) {
|
||||
usb_handle* handle = NULL;
|
||||
static std::unique_ptr<usb_handle> find_usb_device(ifc_match_func callback) {
|
||||
std::unique_ptr<usb_handle> handle;
|
||||
char entry_buffer[2048];
|
||||
char interf_name[2048];
|
||||
AdbInterfaceInfo* next_interface = (AdbInterfaceInfo*)(&entry_buffer[0]);
|
||||
|
@ -356,13 +341,12 @@ static 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, callback)) {
|
||||
if (recognized_device(handle.get(), callback)) {
|
||||
// found it!
|
||||
break;
|
||||
} else {
|
||||
usb_cleanup_handle(handle);
|
||||
free(handle);
|
||||
handle = NULL;
|
||||
usb_cleanup_handle(handle.get());
|
||||
handle.reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -373,9 +357,10 @@ static usb_handle *find_usb_device(ifc_match_func callback) {
|
|||
return handle;
|
||||
}
|
||||
|
||||
usb_handle *usb_open(ifc_match_func callback)
|
||||
Transport* usb_open(ifc_match_func callback)
|
||||
{
|
||||
return find_usb_device(callback);
|
||||
std::unique_ptr<usb_handle> handle = find_usb_device(callback);
|
||||
return handle ? new WindowsUsbTransport(std::move(handle)) : nullptr;
|
||||
}
|
||||
|
||||
// called from fastboot.c
|
||||
|
|
|
@ -86,7 +86,7 @@ int match_loop(usb_ifc_info *info)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int test_null(usb_handle *usb)
|
||||
int test_null(Transport* usb)
|
||||
{
|
||||
unsigned i;
|
||||
unsigned char buf[4096];
|
||||
|
@ -94,8 +94,8 @@ int test_null(usb_handle *usb)
|
|||
long long t0, t1;
|
||||
|
||||
t0 = NOW();
|
||||
for(i = 0; i < arg_count; i++) {
|
||||
if(usb_write(usb, buf, arg_size) != (int)arg_size) {
|
||||
for (i = 0; i < arg_count; i++) {
|
||||
if (usb->Write(buf, arg_size) != static_cast<int>(arg_size)) {
|
||||
fprintf(stderr,"write failed (%s)\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
@ -105,15 +105,15 @@ int test_null(usb_handle *usb)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int test_zero(usb_handle *usb)
|
||||
int test_zero(Transport* usb)
|
||||
{
|
||||
unsigned i;
|
||||
unsigned char buf[4096];
|
||||
long long t0, t1;
|
||||
|
||||
t0 = NOW();
|
||||
for(i = 0; i < arg_count; i++) {
|
||||
if(usb_read(usb, buf, arg_size) != (int)arg_size) {
|
||||
for (i = 0; i < arg_count; i++) {
|
||||
if (usb->Read(buf, arg_size) != static_cast<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)(usb_handle *usb);
|
||||
int (*test)(Transport* 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)
|
||||
{
|
||||
usb_handle *usb;
|
||||
Transport* usb;
|
||||
int i;
|
||||
|
||||
if(argc < 2)
|
||||
|
|
Loading…
Reference in New Issue