Loading adb/adb.h +1 −1 Original line number Original line Diff line number Diff line Loading @@ -36,7 +36,7 @@ #define ADB_VERSION_MAJOR 1 // Used for help/version information #define ADB_VERSION_MAJOR 1 // Used for help/version information #define ADB_VERSION_MINOR 0 // Used for help/version information #define ADB_VERSION_MINOR 0 // Used for help/version information #define ADB_SERVER_VERSION 31 // Increment this when we want to force users to start a new adb server #define ADB_SERVER_VERSION 32 // Increment this when we want to force users to start a new adb server typedef struct amessage amessage; typedef struct amessage amessage; typedef struct apacket apacket; typedef struct apacket apacket; Loading adb/adb_client.c +2 −1 Original line number Original line Diff line number Diff line Loading @@ -279,7 +279,7 @@ int adb_connect(const char *service) fd = _adb_connect(service); fd = _adb_connect(service); if(fd == -1) { if(fd == -1) { fprintf(stderr,"error: %s\n", __adb_error); D("_adb_connect error: %s\n", __adb_error); } else if(fd == -2) { } else if(fd == -2) { fprintf(stderr,"** daemon still not running\n"); fprintf(stderr,"** daemon still not running\n"); } } Loading @@ -296,6 +296,7 @@ int adb_command(const char *service) { { int fd = adb_connect(service); int fd = adb_connect(service); if(fd < 0) { if(fd < 0) { fprintf(stderr, "error: %s\n", adb_error()); return -1; return -1; } } Loading adb/commandline.c +110 −1 Original line number Original line Diff line number Diff line Loading @@ -500,6 +500,115 @@ int adb_download(const char *service, const char *fn, unsigned progress) return status; return status; } } #define SIDELOAD_HOST_BLOCK_SIZE (CHUNK_SIZE) /* * The sideload-host protocol serves the data in a file (given on the * command line) to the client, using a simple protocol: * * - The connect message includes the total number of bytes in the * file and a block size chosen by us. * * - The other side sends the desired block number as eight decimal * digits (eg "00000023" for block 23). Blocks are numbered from * zero. * * - We send back the data of the requested block. The last block is * likely to be partial; when the last block is requested we only * send the part of the block that exists, it's not padded up to the * block size. * * - When the other side sends "DONEDONE" instead of a block number, * we hang up. */ int adb_sideload_host(const char* fn) { uint8_t* data; unsigned sz; size_t xfer = 0; int status; printf("loading: '%s'", fn); fflush(stdout); data = load_file(fn, &sz); if (data == 0) { printf("\n"); fprintf(stderr, "* cannot read '%s' *\n", fn); return -1; } char buf[100]; sprintf(buf, "sideload-host:%d:%d", sz, SIDELOAD_HOST_BLOCK_SIZE); int fd = adb_connect(buf); if (fd < 0) { // Try falling back to the older sideload method. Maybe this // is an older device that doesn't support sideload-host. printf("\n"); status = adb_download_buffer("sideload", fn, data, sz, 1); goto done; } int opt = SIDELOAD_HOST_BLOCK_SIZE; opt = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const void *) &opt, sizeof(opt)); int last_percent = -1; while (true) { if (readx(fd, buf, 8)) { fprintf(stderr, "* failed to read command: %s\n", adb_error()); status = -1; goto done; } if (strncmp("DONEDONE", buf, 8) == 0) { status = 0; break; } buf[8] = '\0'; int block = strtol(buf, NULL, 10); size_t offset = block * SIDELOAD_HOST_BLOCK_SIZE; if (offset >= sz) { fprintf(stderr, "* attempt to read past end: %s\n", adb_error()); status = -1; goto done; } uint8_t* start = data + offset; size_t offset_end = offset + SIDELOAD_HOST_BLOCK_SIZE; size_t to_write = SIDELOAD_HOST_BLOCK_SIZE; if (offset_end > sz) { to_write = sz - offset; } if(writex(fd, start, to_write)) { adb_status(fd); fprintf(stderr,"* failed to write data '%s' *\n", adb_error()); status = -1; goto done; } xfer += to_write; // For normal OTA packages, we expect to transfer every byte // twice, plus a bit of overhead (one read during // verification, one read of each byte for installation, plus // extra access to things like the zip central directory). // This estimate of the completion becomes 100% when we've // transferred ~2.13 (=100/47) times the package size. int percent = (int)(xfer * 47LL / (sz ? sz : 1)); if (percent != last_percent) { printf("\rserving: '%s' (~%d%%) ", fn, percent); fflush(stdout); last_percent = percent; } } printf("\rTotal xfer: %.2fx%*s\n", (double)xfer / (sz ? sz : 1), (int)strlen(fn)+10, ""); done: if (fd >= 0) adb_close(fd); free(data); return status; } static void status_window(transport_type ttype, const char* serial) static void status_window(transport_type ttype, const char* serial) { { char command[4096]; char command[4096]; Loading Loading @@ -1290,7 +1399,7 @@ top: if(!strcmp(argv[0], "sideload")) { if(!strcmp(argv[0], "sideload")) { if(argc != 2) return usage(); if(argc != 2) return usage(); if(adb_download("sideload", argv[1], 1)) { if (adb_sideload_host(argv[1])) { return 1; return 1; } else { } else { return 0; return 0; Loading Loading
adb/adb.h +1 −1 Original line number Original line Diff line number Diff line Loading @@ -36,7 +36,7 @@ #define ADB_VERSION_MAJOR 1 // Used for help/version information #define ADB_VERSION_MAJOR 1 // Used for help/version information #define ADB_VERSION_MINOR 0 // Used for help/version information #define ADB_VERSION_MINOR 0 // Used for help/version information #define ADB_SERVER_VERSION 31 // Increment this when we want to force users to start a new adb server #define ADB_SERVER_VERSION 32 // Increment this when we want to force users to start a new adb server typedef struct amessage amessage; typedef struct amessage amessage; typedef struct apacket apacket; typedef struct apacket apacket; Loading
adb/adb_client.c +2 −1 Original line number Original line Diff line number Diff line Loading @@ -279,7 +279,7 @@ int adb_connect(const char *service) fd = _adb_connect(service); fd = _adb_connect(service); if(fd == -1) { if(fd == -1) { fprintf(stderr,"error: %s\n", __adb_error); D("_adb_connect error: %s\n", __adb_error); } else if(fd == -2) { } else if(fd == -2) { fprintf(stderr,"** daemon still not running\n"); fprintf(stderr,"** daemon still not running\n"); } } Loading @@ -296,6 +296,7 @@ int adb_command(const char *service) { { int fd = adb_connect(service); int fd = adb_connect(service); if(fd < 0) { if(fd < 0) { fprintf(stderr, "error: %s\n", adb_error()); return -1; return -1; } } Loading
adb/commandline.c +110 −1 Original line number Original line Diff line number Diff line Loading @@ -500,6 +500,115 @@ int adb_download(const char *service, const char *fn, unsigned progress) return status; return status; } } #define SIDELOAD_HOST_BLOCK_SIZE (CHUNK_SIZE) /* * The sideload-host protocol serves the data in a file (given on the * command line) to the client, using a simple protocol: * * - The connect message includes the total number of bytes in the * file and a block size chosen by us. * * - The other side sends the desired block number as eight decimal * digits (eg "00000023" for block 23). Blocks are numbered from * zero. * * - We send back the data of the requested block. The last block is * likely to be partial; when the last block is requested we only * send the part of the block that exists, it's not padded up to the * block size. * * - When the other side sends "DONEDONE" instead of a block number, * we hang up. */ int adb_sideload_host(const char* fn) { uint8_t* data; unsigned sz; size_t xfer = 0; int status; printf("loading: '%s'", fn); fflush(stdout); data = load_file(fn, &sz); if (data == 0) { printf("\n"); fprintf(stderr, "* cannot read '%s' *\n", fn); return -1; } char buf[100]; sprintf(buf, "sideload-host:%d:%d", sz, SIDELOAD_HOST_BLOCK_SIZE); int fd = adb_connect(buf); if (fd < 0) { // Try falling back to the older sideload method. Maybe this // is an older device that doesn't support sideload-host. printf("\n"); status = adb_download_buffer("sideload", fn, data, sz, 1); goto done; } int opt = SIDELOAD_HOST_BLOCK_SIZE; opt = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const void *) &opt, sizeof(opt)); int last_percent = -1; while (true) { if (readx(fd, buf, 8)) { fprintf(stderr, "* failed to read command: %s\n", adb_error()); status = -1; goto done; } if (strncmp("DONEDONE", buf, 8) == 0) { status = 0; break; } buf[8] = '\0'; int block = strtol(buf, NULL, 10); size_t offset = block * SIDELOAD_HOST_BLOCK_SIZE; if (offset >= sz) { fprintf(stderr, "* attempt to read past end: %s\n", adb_error()); status = -1; goto done; } uint8_t* start = data + offset; size_t offset_end = offset + SIDELOAD_HOST_BLOCK_SIZE; size_t to_write = SIDELOAD_HOST_BLOCK_SIZE; if (offset_end > sz) { to_write = sz - offset; } if(writex(fd, start, to_write)) { adb_status(fd); fprintf(stderr,"* failed to write data '%s' *\n", adb_error()); status = -1; goto done; } xfer += to_write; // For normal OTA packages, we expect to transfer every byte // twice, plus a bit of overhead (one read during // verification, one read of each byte for installation, plus // extra access to things like the zip central directory). // This estimate of the completion becomes 100% when we've // transferred ~2.13 (=100/47) times the package size. int percent = (int)(xfer * 47LL / (sz ? sz : 1)); if (percent != last_percent) { printf("\rserving: '%s' (~%d%%) ", fn, percent); fflush(stdout); last_percent = percent; } } printf("\rTotal xfer: %.2fx%*s\n", (double)xfer / (sz ? sz : 1), (int)strlen(fn)+10, ""); done: if (fd >= 0) adb_close(fd); free(data); return status; } static void status_window(transport_type ttype, const char* serial) static void status_window(transport_type ttype, const char* serial) { { char command[4096]; char command[4096]; Loading Loading @@ -1290,7 +1399,7 @@ top: if(!strcmp(argv[0], "sideload")) { if(!strcmp(argv[0], "sideload")) { if(argc != 2) return usage(); if(argc != 2) return usage(); if(adb_download("sideload", argv[1], 1)) { if (adb_sideload_host(argv[1])) { return 1; return 1; } else { } else { return 0; return 0; Loading