diff --git a/device.c b/device.c index 1b1fb8a..469237e 100644 --- a/device.c +++ b/device.c @@ -45,6 +45,7 @@ #include "fastboot.h" #include "list.h" #include "ppps.h" +#include "status-cmd.h" #define ARRAY_SIZE(x) ((sizeof(x)/sizeof((x)[0]))) @@ -268,6 +269,9 @@ void device_status_enable(struct device *device) if (device_has_control(device, status_enable)) device_control(device, status_enable); + if (device->status_cmd) + status_cmd_open(device); + device->status_enabled = true; } diff --git a/device.h b/device.h index 66e260f..600cbe5 100644 --- a/device.h +++ b/device.h @@ -58,6 +58,8 @@ struct device { void *cdb; void *console; + char *status_cmd; + struct list_head node; }; diff --git a/device_parser.c b/device_parser.c index a137628..fd65816 100644 --- a/device_parser.c +++ b/device_parser.c @@ -193,6 +193,8 @@ static void parse_board(struct device_parser *dp) dev->ppps_path = strdup(value); } else if (!strcmp(key, "ppps3_path")) { dev->ppps3_path = strdup(value); + } else if (!strcmp(key, "status-cmd")) { + dev->status_cmd = strdup(value); } else { fprintf(stderr, "device parser: unknown key \"%s\"\n", key); exit(1); diff --git a/meson.build b/meson.build index 317d9d3..f1d12bd 100644 --- a/meson.build +++ b/meson.build @@ -58,6 +58,13 @@ server_deps = [dependency('libudev', required: server_opt), dependency('yaml-0.1', required: server_opt), gpiod_dep, ftdi_dep] + +# E.g. Debian reuires -lutil for forkpty +if not compiler.has_function('forkpty') + util_dep = compiler.find_library('util') + server_deps += util_dep +endif + server_srcs = ['cdba-server.c', 'cdb_assist.c', 'circ_buf.c', @@ -72,7 +79,8 @@ server_srcs = ['cdba-server.c', 'console.c', 'qcomlt_dbg.c', 'ppps.c', - 'status.c'] + 'status.c', + 'status-cmd.c'] if gpiod_dep.version().version_compare('>=2.0') server_srcs += ['local-gpio-v2.c'] diff --git a/schema.yaml b/schema.yaml index caf0860..d4c0338 100644 --- a/schema.yaml +++ b/schema.yaml @@ -73,6 +73,10 @@ properties: description: USB device name, like 2-2:1.0/2-2-port2 type: string + status-cmd: + description: Command to execute for generating status updates + type: string + qcomlt_debug_board: description: Qlt Debug Board control tty device path $ref: "#/$defs/device_path" diff --git a/status-cmd.c b/status-cmd.c new file mode 100644 index 0000000..3529a63 --- /dev/null +++ b/status-cmd.c @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2023, Qualcomm Innovaction Center, Inc + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "cdba-server.h" +#include "device.h" +#include "status.h" +#include "status-cmd.h" + +static void launch_status_cmd(struct device *dev) +{ + char *tokens[100]; + char *p; + int t = 0; + + p = strtok(dev->status_cmd, " "); + while (p) { + tokens[t++] = p; + p = strtok(NULL, " "); + if (t == 100) + exit(1); + } + tokens[t] = NULL; + + execvp(tokens[0], tokens); + exit(1); +} + +static int status_data(int fd, void *data) +{ + char buf[128]; + ssize_t n; + + n = read(fd, buf, sizeof(buf)); + if (n <= 0) + return n; + + status_send_raw(buf, n); + return 0; +} + +int status_cmd_open(struct device *dev) +{ + pid_t status_pid; + int fd; + + status_pid = forkpty(&fd, NULL, NULL, NULL); + if (status_pid < 0) + err(1, "failed to fork"); + + if(status_pid == 0) { + launch_status_cmd(dev); + /* Notreached */ + } + + watch_add_readfd(fd, status_data, dev); + + return 0; +} diff --git a/status-cmd.h b/status-cmd.h new file mode 100644 index 0000000..5dc9c24 --- /dev/null +++ b/status-cmd.h @@ -0,0 +1,8 @@ +#ifndef __STATUS_CMD_H__ +#define __STATUS_CMD_H__ + +struct device; + +int status_cmd_open(struct device *dev); + +#endif diff --git a/status.c b/status.c index dfa0357..431c04f 100644 --- a/status.c +++ b/status.c @@ -77,3 +77,8 @@ void status_send_values(const char *id, struct status_value *values) cdba_send_buf(MSG_STATUS_UPDATE, len, buf); } + +void status_send_raw(const char *data, size_t len) +{ + cdba_send_buf(MSG_STATUS_UPDATE, len, data); +} diff --git a/status.h b/status.h index 4a12b1d..4838b51 100644 --- a/status.h +++ b/status.h @@ -16,5 +16,6 @@ struct status_value { }; void status_send_values(const char *id, struct status_value *values); +void status_send_raw(const char *data, size_t len); #endif