diff --git a/app/src/command.c b/app/src/command.c index b5bb9572..bf7d8539 100644 --- a/app/src/command.c +++ b/app/src/command.c @@ -34,10 +34,8 @@ static void show_adb_err_msg(enum process_result err) { } } -process_t adb_execute(const char *serial, const char *const adb_cmd[], int len) { - const char *cmd[len + 4]; +static void fill_cmd(const char *cmd[], const char *serial, const char *const adb_cmd[], int len) { int i; - process_t process; cmd[0] = get_adb_command(); if (serial) { cmd[1] = "-s"; @@ -49,6 +47,12 @@ process_t adb_execute(const char *serial, const char *const adb_cmd[], int len) memcpy(&cmd[i], adb_cmd, len * sizeof(const char *)); cmd[len + i] = NULL; +} + +process_t adb_execute(const char *serial, const char *const adb_cmd[], int len) { + const char *cmd[len + 4]; + fill_cmd(cmd, serial, adb_cmd, len); + process_t process; enum process_result r = cmd_execute(cmd[0], cmd, &process); if (r != PROCESS_SUCCESS) { show_adb_err_msg(r); @@ -57,6 +61,19 @@ process_t adb_execute(const char *serial, const char *const adb_cmd[], int len) return process; } +process_t adb_execute_redirect(const char *serial, const char *const adb_cmd[], int len, + pipe_t *pipe_stdin, pipe_t *pipe_stdout, pipe_t *pipe_stderr) { + const char *cmd[len + 4]; + fill_cmd(cmd, serial, adb_cmd, len); + process_t process; + enum process_result r = cmd_execute_redirect(cmd[0], cmd, &process, pipe_stdin, pipe_stdout, pipe_stderr); + if (r != PROCESS_SUCCESS) { + show_adb_err_msg(r); + return PROCESS_NONE; + } + return process; +} + process_t adb_forward(const char *serial, uint16_t local_port, const char *device_socket_name) { char local[4 + 5 + 1]; // tcp:PORT char remote[108 + 14 + 1]; // localabstract:NAME @@ -140,6 +157,40 @@ process_t adb_remove_path(const char *serial, const char *path) { return adb_execute(serial, adb_cmd, ARRAY_LEN(adb_cmd)); } +static int adb_execute_get_output(const char *serial, const char *const adb_cmd[], int adb_cmd_len, + char *data, size_t data_len, const char *name) { + pipe_t pipe_stdout; + process_t proc = adb_execute_redirect(serial, adb_cmd, adb_cmd_len, NULL, &pipe_stdout, NULL); + if (!process_check_success(proc, name)) { + return -1; + } + int r = read_pipe(pipe_stdout, data, data_len); + close_pipe(pipe_stdout); + return r; +} + +static int truncate_first_line(char *data, int len) { + data[len - 1] = '\0'; + char *eol = strpbrk(data, "\r\n"); + if (eol) { + *eol = '\0'; + len = eol - data; + } + return len; +} + +int adb_read_serialno(const char *serial, char *data, size_t len) { + const char *const adb_cmd[] = {"get-serialno"}; + int r = adb_execute_get_output(serial, adb_cmd, ARRAY_LEN(adb_cmd), data, len, "get-serialno"); + return r <= 0 ? r : truncate_first_line(data, r); +} + +int adb_read_model(const char *serial, char *data, size_t len) { + const char *const adb_cmd[] = {"shell", "getprop", "ro.product.model"}; + int r = adb_execute_get_output(serial, adb_cmd, ARRAY_LEN(adb_cmd), data, len, "getprop model"); + return r <= 0 ? r : truncate_first_line(data, r); +} + SDL_bool process_check_success(process_t proc, const char *name) { if (proc == PROCESS_NONE) { LOGE("Could not execute \"%s\"", name); diff --git a/app/src/command.h b/app/src/command.h index 385d09d7..3e7483f1 100644 --- a/app/src/command.h +++ b/app/src/command.h @@ -47,6 +47,8 @@ SDL_bool cmd_terminate(process_t pid); SDL_bool cmd_simple_wait(process_t pid, exit_code_t *exit_code); process_t adb_execute(const char *serial, const char *const adb_cmd[], int len); +process_t adb_execute_redirect(const char *serial, const char *const adb_cmd[], int len, + pipe_t *pipe_stdin, pipe_t *pipe_stdout, pipe_t *pipe_stderr); process_t adb_forward(const char *serial, uint16_t local_port, const char *device_socket_name); process_t adb_forward_remove(const char *serial, uint16_t local_port); process_t adb_reverse(const char *serial, const char *device_socket_name, uint16_t local_port); @@ -55,6 +57,10 @@ process_t adb_push(const char *serial, const char *local, const char *remote); process_t adb_install(const char *serial, const char *local); process_t adb_remove_path(const char *serial, const char *path); +// return number of bytes read (-1 on error) +int adb_read_serialno(const char *serial, char *data, size_t len); +int adb_read_model(const char *serial, char *data, size_t len); + // convenience function to wait for a successful process execution // automatically log process errors with the provided process name SDL_bool process_check_success(process_t process, const char *name);