adb_client.c

来自「Android 一些工具」· C语言 代码 · 共 319 行

C
319
字号
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <errno.h>#include <limits.h>#include <stdarg.h>#include <zipfile/zipfile.h>#include <sys/types.h>#include <sys/stat.h>#include "sysdeps.h"#define  TRACE_TAG  TRACE_ADB#include "adb_client.h"static transport_type __adb_transport = kTransportAny;static const char* __adb_serial = NULL;void adb_set_transport(transport_type type, const char* serial){    __adb_transport = type;    __adb_serial = serial;}int  adb_get_emulator_console_port(void){    const char*   serial = __adb_serial;    int           port;    if (serial == NULL) {        /* if no specific device was specified, we need to look at */        /* the list of connected devices, and extract an emulator  */        /* name from it. two emulators is an error                 */        char*  tmp = adb_query("host:devices");        char*  p   = tmp;        if(!tmp) {            printf("no emulator connected\n");            return -1;        }        while (*p) {            char*  q = strchr(p, '\n');            if (q != NULL)                *q++ = 0;            else                q = p + strlen(p);            if (!memcmp(p, LOCAL_CLIENT_PREFIX, sizeof(LOCAL_CLIENT_PREFIX)-1)) {                if (serial != NULL) {  /* more than one emulator listed */                    free(tmp);                    return -2;                }                serial = p;            }            p = q;        }        free(tmp);        if (serial == NULL)            return -1;  /* no emulator found */    }    else {        if (memcmp(serial, LOCAL_CLIENT_PREFIX, sizeof(LOCAL_CLIENT_PREFIX)-1) != 0)            return -1;  /* not an emulator */    }    serial += sizeof(LOCAL_CLIENT_PREFIX)-1;    port    = strtol(serial, NULL, 10);    return port;}static char __adb_error[256] = { 0 };const char *adb_error(void){    return __adb_error;}static int switch_socket_transport(int fd){    char service[64];    char tmp[5];    int len;    if (__adb_serial)        snprintf(service, sizeof service, "host:transport:%s", __adb_serial);    else {        char* transport_type = "???";         switch (__adb_transport) {            case kTransportUsb:                transport_type = "transport-usb";                break;            case kTransportLocal:                transport_type = "transport-local";                break;            case kTransportAny:                transport_type = "transport-any";                break;            case kTransportHost:                // no switch necessary                return 0;                break;        }        snprintf(service, sizeof service, "host:%s", transport_type);    }    len = strlen(service);    snprintf(tmp, sizeof tmp, "%04x", len);    if(writex(fd, tmp, 4) || writex(fd, service, len)) {        strcpy(__adb_error, "write failure during connection");        adb_close(fd);        return -1;    }    D("Switch transport in progress\n");    if(adb_status(fd)) {        adb_close(fd);        D("Switch transport failed\n");        return -1;    }    D("Switch transport success\n");    return 0;}int adb_status(int fd){    unsigned char buf[5];    unsigned len;    if(readx(fd, buf, 4)) {        strcpy(__adb_error, "protocol fault (no status)");        return -1;    }    if(!memcmp(buf, "OKAY", 4)) {        return 0;    }    if(memcmp(buf, "FAIL", 4)) {        sprintf(__adb_error,                "protocol fault (status %02x %02x %02x %02x?!)",                buf[0], buf[1], buf[2], buf[3]);        return -1;    }    if(readx(fd, buf, 4)) {        strcpy(__adb_error, "protocol fault (status len)");        return -1;    }    buf[4] = 0;    len = strtoul((char*)buf, 0, 16);    if(len > 255) len = 255;    if(readx(fd, __adb_error, len)) {        strcpy(__adb_error, "protocol fault (status read)");        return -1;    }    __adb_error[len] = 0;    return -1;}int _adb_connect(const char *service){    char tmp[5];    int len;    int fd;    D("_adb_connect: %s\n", service);    len = strlen(service);    if((len < 1) || (len > 1024)) {        strcpy(__adb_error, "service name too long");        return -1;    }    snprintf(tmp, sizeof tmp, "%04x", len);    fd = socket_loopback_client(ADB_PORT, SOCK_STREAM);    if(fd < 0) {        strcpy(__adb_error, "cannot connect to daemon");        return -2;    }    if (memcmp(service,"host",4) != 0 && switch_socket_transport(fd)) {        return -1;    }    if(writex(fd, tmp, 4) || writex(fd, service, len)) {        strcpy(__adb_error, "write failure during connection");        adb_close(fd);        return -1;    }    if(adb_status(fd)) {        adb_close(fd);        return -1;    }    return fd;}int adb_connect(const char *service){    // first query the adb server's version    int fd = _adb_connect("host:version");    if(fd == -2) {        fprintf(stdout,"* daemon not running. starting it now *\n");    start_server:        if(launch_server(0)) {            fprintf(stderr,"* failed to start daemon *\n");            return -1;        } else {            fprintf(stdout,"* daemon started successfully *\n");		}        /* give the server some time to start properly and detect devices */        adb_sleep_ms(2000);        // fall through to _adb_connect    } else {        // if server was running, check its version to make sure it is not out of date        char buf[100];        int n;        int version = ADB_SERVER_VERSION - 1;        // if we have a file descriptor, then parse version result        if(fd >= 0) {	        if(readx(fd, buf, 4)) goto error;		    buf[4] = 0;		    n = strtoul(buf, 0, 16);		    if(n > (int)sizeof(buf)) goto error;		    if(readx(fd, buf, n)) goto error;		    adb_close(fd);            if (sscanf(buf, "%04x", &version) != 1) goto error;        } else {            // if fd is -1, then check for "unknown host service",            // which would indicate a version of adb that does not support the version command            if (strcmp(__adb_error, "unknown host service") != 0)                return fd;        }        if(version != ADB_SERVER_VERSION) {	        printf("adb server is out of date.  killing...\n");	        fd = _adb_connect("host:kill");	        adb_close(fd);                /* XXX can we better detect its death? */	        adb_sleep_ms(2000);            goto start_server;	    }    }    // if the command is start-server, we are done.    if (!strcmp(service, "host:start-server"))        return 0;    fd = _adb_connect(service);    if(fd == -2) {        fprintf(stderr,"** daemon still not running");    }    return fd;error:    adb_close(fd);    return -1;}int adb_command(const char *service){    int fd = adb_connect(service);    if(fd < 0) {        return -1;    }    if(adb_status(fd)) {        adb_close(fd);        return -1;    }    return 0;}char *adb_query(const char *service){    char buf[5];    unsigned n;    char *tmp;    D("adb_query: %s\n", service);    int fd = adb_connect(service);    if(fd < 0) {        fprintf(stderr,"error: %s\n", __adb_error);        return 0;    }    if(readx(fd, buf, 4)) goto oops;    buf[4] = 0;    n = strtoul(buf, 0, 16);    if(n > 1024) goto oops;    tmp = malloc(n + 1);    if(tmp == 0) goto oops;    if(readx(fd, tmp, n) == 0) {        tmp[n] = 0;        adb_close(fd);        return tmp;    }    free(tmp);oops:    adb_close(fd);    return 0;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?