mirror of
https://github.com/linux-msm/cdba.git
synced 2026-02-25 13:11:56 -08:00
Compare commits
35 Commits
topic/prot
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b6c766db1f | ||
|
|
031948ff19 | ||
|
|
30c30ce84c | ||
|
|
95a40706be | ||
|
|
4320c482d3 | ||
|
|
cdee00d9a4 | ||
|
|
5bade34946 | ||
|
|
3c1e7cc886 | ||
|
|
bad935cbf2 | ||
|
|
9335390898 | ||
|
|
b6d70e8b0c | ||
|
|
06531f3db1 | ||
|
|
828d76df63 | ||
|
|
e799564f44 | ||
|
|
720922913c | ||
|
|
8bd8eeda33 | ||
|
|
f801448422 | ||
|
|
3922dc793a | ||
|
|
61babbf9ac | ||
|
|
358fea7207 | ||
|
|
b0df12edc0 | ||
|
|
59db2941f5 | ||
|
|
8715e3b74d | ||
|
|
aa0e50bb1d | ||
|
|
0852da5424 | ||
|
|
2f3e661f4d | ||
|
|
2899fbcbb1 | ||
|
|
61139604fb | ||
|
|
cbad92a838 | ||
|
|
95ff3049f8 | ||
|
|
5db3df360a | ||
|
|
02210fe6e2 | ||
|
|
b3b50a7441 | ||
|
|
c86932d361 | ||
|
|
d77816052d |
9
.github/workflows/ci.yml
vendored
9
.github/workflows/ci.yml
vendored
@@ -43,10 +43,15 @@ jobs:
|
|||||||
# Fails on configure on GCC and clang (process restrictions?)
|
# Fails on configure on GCC and clang (process restrictions?)
|
||||||
# - fedora:rawhide
|
# - fedora:rawhide
|
||||||
- fedora:latest
|
- fedora:latest
|
||||||
|
- fedora:42
|
||||||
|
- fedora:41
|
||||||
|
- fedora:40
|
||||||
- fedora:39
|
- fedora:39
|
||||||
- fedora:38
|
- fedora:38
|
||||||
- fedora:37
|
- fedora:37
|
||||||
- ubuntu:lunar # EOL 01.2024
|
- ubuntu:latest
|
||||||
|
- ubuntu:oracular
|
||||||
|
- ubuntu:noble
|
||||||
- ubuntu:jammy
|
- ubuntu:jammy
|
||||||
- ubuntu:focal
|
- ubuntu:focal
|
||||||
# On Ubuntu Bionic the Meson doesn't support feature options
|
# On Ubuntu Bionic the Meson doesn't support feature options
|
||||||
@@ -178,7 +183,7 @@ jobs:
|
|||||||
echo "PKG_CONFIG_PATH: $PKG_CONFIG_PATH"
|
echo "PKG_CONFIG_PATH: $PKG_CONFIG_PATH"
|
||||||
|
|
||||||
- name: Git checkout
|
- name: Git checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Install additional packages
|
- name: Install additional packages
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
2
.github/workflows/codeql-analysis.yml
vendored
2
.github/workflows/codeql-analysis.yml
vendored
@@ -24,7 +24,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@v2
|
uses: github/codeql-action/init@v2
|
||||||
|
|||||||
2
.github/workflows/yaml.yml
vendored
2
.github/workflows/yaml.yml
vendored
@@ -27,7 +27,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Git checkout
|
- name: Git checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Install additional packages
|
- name: Install additional packages
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
8
README
8
README
@@ -19,11 +19,13 @@ from sandbox/cdba/cdba-server. Available devices are read from $HOME/.cdba
|
|||||||
= Client side
|
= Client side
|
||||||
The client is invoked as:
|
The client is invoked as:
|
||||||
|
|
||||||
cdba -b <board> -h <host> [-c <power-cylce-count>] [-s <status-fifo>] boot.img
|
cdba -b <board> [-h <host>] [-c <power-cylce-count>] [-s <status-fifo>] [boot.img]
|
||||||
|
|
||||||
<host> will be connected to using ssh and <board> will be selected for
|
<host> will be connected to using ssh and <board> will be selected for
|
||||||
operation. As the board's fastboot interface shows up the given boot.img will
|
operation. As the board's fastboot interface shows up the given boot.img
|
||||||
be transfered and booted on the device.
|
will be transfered and booted on the device. If <host> is omitted, the
|
||||||
|
cdba-server is started locally without using ssh. If [boot.img] is omitted,
|
||||||
|
"fastboot continue" is run to boot the installed operating system.
|
||||||
|
|
||||||
The board will execute until the key sequence ^A q is invoked or the board
|
The board will execute until the key sequence ^A q is invoked or the board
|
||||||
outputs a sequence of 20 ~ (tilde) chards in a row.
|
outputs a sequence of 20 ~ (tilde) chards in a row.
|
||||||
|
|||||||
@@ -59,9 +59,9 @@ static void msg_select_board(const void *param)
|
|||||||
if (!selected_device) {
|
if (!selected_device) {
|
||||||
fprintf(stderr, "failed to open %s\n", (const char *)param);
|
fprintf(stderr, "failed to open %s\n", (const char *)param);
|
||||||
watch_quit();
|
watch_quit();
|
||||||
}
|
} else {
|
||||||
|
|
||||||
device_fastboot_open(selected_device, &fastboot_ops);
|
device_fastboot_open(selected_device, &fastboot_ops);
|
||||||
|
}
|
||||||
|
|
||||||
cdba_send(MSG_SELECT_BOARD);
|
cdba_send(MSG_SELECT_BOARD);
|
||||||
}
|
}
|
||||||
@@ -99,6 +99,28 @@ static void msg_fastboot_continue(void)
|
|||||||
cdba_send(MSG_FASTBOOT_CONTINUE);
|
cdba_send(MSG_FASTBOOT_CONTINUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void msg_key_release(void *data)
|
||||||
|
{
|
||||||
|
int key = (int)(uintptr_t)data;
|
||||||
|
|
||||||
|
device_key(selected_device, key, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void msg_key_press(const void *data, size_t len)
|
||||||
|
{
|
||||||
|
const struct key_press *press = data;
|
||||||
|
|
||||||
|
if (len != sizeof(*press))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (press->state == KEY_PRESS_PULSE) {
|
||||||
|
device_key(selected_device, press->key, true);
|
||||||
|
watch_timer_add(100, msg_key_release, (void*)(uintptr_t)press->key);
|
||||||
|
} else {
|
||||||
|
device_key(selected_device, press->key, !!press->state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void cdba_send_buf(int type, size_t len, const void *buf)
|
void cdba_send_buf(int type, size_t len, const void *buf)
|
||||||
{
|
{
|
||||||
struct msg msg = {
|
struct msg msg = {
|
||||||
@@ -185,6 +207,9 @@ static int handle_stdin(int fd, void *buf)
|
|||||||
case MSG_FASTBOOT_CONTINUE:
|
case MSG_FASTBOOT_CONTINUE:
|
||||||
msg_fastboot_continue();
|
msg_fastboot_continue();
|
||||||
break;
|
break;
|
||||||
|
case MSG_KEY_PRESS:
|
||||||
|
msg_key_press(msg->data, msg->len);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "unk %d len %d\n", msg->type, msg->len);
|
fprintf(stderr, "unk %d len %d\n", msg->type, msg->len);
|
||||||
exit(1);
|
exit(1);
|
||||||
@@ -201,6 +226,11 @@ static void sigpipe_handler(int signo)
|
|||||||
watch_quit();
|
watch_quit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void atexit_handler(void)
|
||||||
|
{
|
||||||
|
syslog(LOG_INFO, "exiting");
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int flags;
|
int flags;
|
||||||
@@ -216,7 +246,8 @@ int main(int argc, char **argv)
|
|||||||
if (!username)
|
if (!username)
|
||||||
username = "nobody";
|
username = "nobody";
|
||||||
|
|
||||||
openlog("cdba-server", 0, LOG_DAEMON);
|
openlog("cdba-server", LOG_PID, LOG_DAEMON);
|
||||||
|
atexit(atexit_handler);
|
||||||
|
|
||||||
ret = device_parser(".cdba");
|
ret = device_parser(".cdba");
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
|||||||
67
cdba.c
67
cdba.c
@@ -103,8 +103,13 @@ static int fork_ssh(const char *host, const char *cmd, int *pipes)
|
|||||||
close(piped_stderr[0]);
|
close(piped_stderr[0]);
|
||||||
close(piped_stderr[1]);
|
close(piped_stderr[1]);
|
||||||
|
|
||||||
execl("/usr/bin/ssh", "ssh", host, cmd, NULL);
|
if (host) {
|
||||||
|
execlp("ssh", "ssh", host, cmd, NULL);
|
||||||
err(1, "launching ssh failed");
|
err(1, "launching ssh failed");
|
||||||
|
} else {
|
||||||
|
execlp(cmd, cmd, NULL);
|
||||||
|
err(1, "launching cdba-server failed");
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
close(piped_stdin[0]);
|
close(piped_stdin[0]);
|
||||||
close(piped_stdout[1]);
|
close(piped_stdout[1]);
|
||||||
@@ -143,8 +148,25 @@ static int cdba_send_buf(int fd, int type, size_t len, const void *buf)
|
|||||||
return ret < 0 ? ret : 0;
|
return ret < 0 ? ret : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int cdba_send_key(int fd, int key, uint8_t state)
|
||||||
|
{
|
||||||
|
struct key_press press = {
|
||||||
|
.key = key,
|
||||||
|
.state = state,
|
||||||
|
};
|
||||||
|
|
||||||
|
return cdba_send_buf(fd, MSG_KEY_PRESS, sizeof(press), &press);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cdba_toggle_key(int fd, int key, bool key_state[DEVICE_KEY_COUNT])
|
||||||
|
{
|
||||||
|
key_state[key] = !key_state[key];
|
||||||
|
return cdba_send_key(fd, key, key_state[key]);
|
||||||
|
}
|
||||||
|
|
||||||
static int tty_callback(int *ssh_fds)
|
static int tty_callback(int *ssh_fds)
|
||||||
{
|
{
|
||||||
|
static bool key_state[DEVICE_KEY_COUNT];
|
||||||
static const char ctrl_a = 0x1;
|
static const char ctrl_a = 0x1;
|
||||||
static bool special;
|
static bool special;
|
||||||
char buf[32];
|
char buf[32];
|
||||||
@@ -184,6 +206,18 @@ static int tty_callback(int *ssh_fds)
|
|||||||
case 'B':
|
case 'B':
|
||||||
cdba_send(ssh_fds[0], MSG_SEND_BREAK);
|
cdba_send(ssh_fds[0], MSG_SEND_BREAK);
|
||||||
break;
|
break;
|
||||||
|
case 'o':
|
||||||
|
cdba_send_key(ssh_fds[0], DEVICE_KEY_POWER, KEY_PRESS_PULSE);
|
||||||
|
break;
|
||||||
|
case 'O':
|
||||||
|
cdba_toggle_key(ssh_fds[0], DEVICE_KEY_POWER, key_state);
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
cdba_send_key(ssh_fds[0], DEVICE_KEY_FASTBOOT, KEY_PRESS_PULSE);
|
||||||
|
break;
|
||||||
|
case 'F':
|
||||||
|
cdba_toggle_key(ssh_fds[0], DEVICE_KEY_FASTBOOT, key_state);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
special = false;
|
special = false;
|
||||||
@@ -533,13 +567,11 @@ static int handle_message(struct circ_buf *buf)
|
|||||||
} else {
|
} else {
|
||||||
quit = true;
|
quit = true;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
fastboot_done = true;
|
|
||||||
// printf("======================================== MSG_FASTBOOT_PRESENT(off)\n");
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MSG_FASTBOOT_DOWNLOAD:
|
case MSG_FASTBOOT_DOWNLOAD:
|
||||||
// printf("======================================== MSG_FASTBOOT_DOWNLOAD\n");
|
// printf("======================================== MSG_FASTBOOT_DOWNLOAD\n");
|
||||||
|
fastboot_done = true;
|
||||||
break;
|
break;
|
||||||
case MSG_FASTBOOT_BOOT:
|
case MSG_FASTBOOT_BOOT:
|
||||||
// printf("======================================== MSG_FASTBOOT_BOOT\n");
|
// printf("======================================== MSG_FASTBOOT_BOOT\n");
|
||||||
@@ -556,6 +588,7 @@ static int handle_message(struct circ_buf *buf)
|
|||||||
break;
|
break;
|
||||||
case MSG_FASTBOOT_CONTINUE:
|
case MSG_FASTBOOT_CONTINUE:
|
||||||
// printf("======================================== MSG_FASTBOOT_CONTINUE\n");
|
// printf("======================================== MSG_FASTBOOT_CONTINUE\n");
|
||||||
|
fastboot_done = true;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "unk %d len %d\n", msg->type, msg->len);
|
fprintf(stderr, "unk %d len %d\n", msg->type, msg->len);
|
||||||
@@ -584,12 +617,12 @@ static void usage(void)
|
|||||||
{
|
{
|
||||||
extern const char *__progname;
|
extern const char *__progname;
|
||||||
|
|
||||||
fprintf(stderr, "usage: %s -b <board> -h <host> [-t <timeout>] "
|
fprintf(stderr, "usage: %s -b <board> [-h <host>] [-t <timeout>] "
|
||||||
"[-T <inactivity-timeout>] <boot.img>\n",
|
"[-T <inactivity-timeout>] [boot.img]\n",
|
||||||
__progname);
|
__progname);
|
||||||
fprintf(stderr, "usage: %s -i -b <board> -h <host>\n",
|
fprintf(stderr, "usage: %s -i -b <board> [-h <host>]\n",
|
||||||
__progname);
|
__progname);
|
||||||
fprintf(stderr, "usage: %s -l -h <host>\n",
|
fprintf(stderr, "usage: %s -l [-h <host>]\n",
|
||||||
__progname);
|
__progname);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
@@ -605,6 +638,7 @@ int main(int argc, char **argv)
|
|||||||
bool power_cycle_on_timeout = true;
|
bool power_cycle_on_timeout = true;
|
||||||
struct timeval timeout_inactivity_tv;
|
struct timeval timeout_inactivity_tv;
|
||||||
struct timeval timeout_total_tv;
|
struct timeval timeout_total_tv;
|
||||||
|
struct timeval *timeout = NULL;
|
||||||
struct termios *orig_tios;
|
struct termios *orig_tios;
|
||||||
const char *server_binary = "cdba-server";
|
const char *server_binary = "cdba-server";
|
||||||
const char *status_pipe = NULL;
|
const char *status_pipe = NULL;
|
||||||
@@ -668,9 +702,6 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!host)
|
|
||||||
usage();
|
|
||||||
|
|
||||||
switch (verb) {
|
switch (verb) {
|
||||||
case CDBA_BOOT:
|
case CDBA_BOOT:
|
||||||
if (optind > argc || !board)
|
if (optind > argc || !board)
|
||||||
@@ -708,6 +739,8 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
timeout_total_tv = get_timeout(timeout_total);
|
timeout_total_tv = get_timeout(timeout_total);
|
||||||
timeout_inactivity_tv = get_timeout(timeout_inactivity);
|
timeout_inactivity_tv = get_timeout(timeout_inactivity);
|
||||||
|
if (timeout_total || timeout_inactivity)
|
||||||
|
timeout = &tv;
|
||||||
|
|
||||||
while (!quit) {
|
while (!quit) {
|
||||||
if (received_power_off || reached_timeout) {
|
if (received_power_off || reached_timeout) {
|
||||||
@@ -745,14 +778,16 @@ int main(int argc, char **argv)
|
|||||||
if (!list_empty(&work_items))
|
if (!list_empty(&work_items))
|
||||||
FD_SET(ssh_fds[0], &wfds);
|
FD_SET(ssh_fds[0], &wfds);
|
||||||
|
|
||||||
|
if (timeout) {
|
||||||
gettimeofday(&now, NULL);
|
gettimeofday(&now, NULL);
|
||||||
if (timeout_inactivity && timercmp(&timeout_inactivity_tv, &timeout_total_tv, <)) {
|
if (timeout_inactivity && (!timeout_total ||
|
||||||
timersub(&timeout_inactivity_tv, &now, &tv);
|
timercmp(&timeout_inactivity_tv, &timeout_total_tv, <))) {
|
||||||
|
timersub(&timeout_inactivity_tv, &now, timeout);
|
||||||
} else {
|
} else {
|
||||||
timersub(&timeout_total_tv, &now, &tv);
|
timersub(&timeout_total_tv, &now, timeout);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
ret = select(nfds + 1, &rfds, &wfds, NULL, &tv);
|
ret = select(nfds + 1, &rfds, &wfds, NULL, timeout);
|
||||||
#if 0
|
#if 0
|
||||||
printf("select: %d (%c%c%c)\n", ret, FD_ISSET(STDIN_FILENO, &rfds) ? 'X' : '-',
|
printf("select: %d (%c%c%c)\n", ret, FD_ISSET(STDIN_FILENO, &rfds) ? 'X' : '-',
|
||||||
FD_ISSET(ssh_fds[1], &rfds) ? 'X' : '-',
|
FD_ISSET(ssh_fds[1], &rfds) ? 'X' : '-',
|
||||||
|
|||||||
18
cdba.h
18
cdba.h
@@ -31,6 +31,24 @@ enum {
|
|||||||
MSG_LIST_DEVICES,
|
MSG_LIST_DEVICES,
|
||||||
MSG_BOARD_INFO,
|
MSG_BOARD_INFO,
|
||||||
MSG_FASTBOOT_CONTINUE,
|
MSG_FASTBOOT_CONTINUE,
|
||||||
|
MSG_KEY_PRESS,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct key_press {
|
||||||
|
uint8_t key;
|
||||||
|
uint8_t state;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
DEVICE_KEY_FASTBOOT,
|
||||||
|
DEVICE_KEY_POWER,
|
||||||
|
DEVICE_KEY_COUNT
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
KEY_PRESS_RELEASE,
|
||||||
|
KEY_PRESS_PRESS,
|
||||||
|
KEY_PRESS_PULSE,
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -73,3 +73,32 @@ devices:
|
|||||||
power:
|
power:
|
||||||
interface: D
|
interface: D
|
||||||
line: 6
|
line: 6
|
||||||
|
- board: myboard-5
|
||||||
|
name: "My Board 5"
|
||||||
|
description: |
|
||||||
|
My super awesome board Number 5
|
||||||
|
console: /dev/ttyABC1
|
||||||
|
fastboot: cacafada
|
||||||
|
ftdi_gpio:
|
||||||
|
vendor: "0x0403"
|
||||||
|
product: "0x6011"
|
||||||
|
index: 0
|
||||||
|
power:
|
||||||
|
interface: B
|
||||||
|
line: 1
|
||||||
|
active_low: true
|
||||||
|
fastboot_key:
|
||||||
|
interface: B
|
||||||
|
line: 0
|
||||||
|
active_low: true
|
||||||
|
power_key:
|
||||||
|
interface: B
|
||||||
|
line: 2
|
||||||
|
usb0_disconnect:
|
||||||
|
interface: C
|
||||||
|
line: 7
|
||||||
|
active_low: true
|
||||||
|
usb1_disconnect:
|
||||||
|
interface: A
|
||||||
|
line: 4
|
||||||
|
active_low: true
|
||||||
|
|||||||
16
device.c
16
device.c
@@ -64,15 +64,21 @@ static void device_lock(struct device *device)
|
|||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
err(1, "failed to open lockfile %s", lock);
|
err(1, "failed to open lockfile %s", lock);
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
char c;
|
||||||
|
|
||||||
n = flock(fd, LOCK_EX | LOCK_NB);
|
n = flock(fd, LOCK_EX | LOCK_NB);
|
||||||
if (!n)
|
if (!n)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
warnx("board is in use, waiting...");
|
warnx("board is in use, waiting...");
|
||||||
|
|
||||||
n = flock(fd, LOCK_EX);
|
sleep(3);
|
||||||
if (n < 0)
|
|
||||||
err(1, "failed to lock lockfile %s", lock);
|
/* check that connection isn't gone */
|
||||||
|
if (read(STDIN_FILENO, &c, 1) == 0)
|
||||||
|
errx(1, "connection is gone");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool device_check_access(struct device *device,
|
static bool device_check_access(struct device *device,
|
||||||
@@ -157,7 +163,7 @@ static void device_impl_power(struct device *device, bool on)
|
|||||||
device_control(device, power, on);
|
device_control(device, power, on);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void device_key(struct device *device, int key, bool asserted)
|
void device_key(struct device *device, int key, bool asserted)
|
||||||
{
|
{
|
||||||
if (device_has_control(device, key))
|
if (device_has_control(device, key))
|
||||||
device_control(device, key, key, asserted);
|
device_control(device, key, key, asserted);
|
||||||
@@ -279,7 +285,7 @@ void device_usb(struct device *device, bool on)
|
|||||||
{
|
{
|
||||||
if (device->ppps_path)
|
if (device->ppps_path)
|
||||||
ppps_power(device, on);
|
ppps_power(device, on);
|
||||||
else if (device_has_control(device, usb))
|
if (device_has_control(device, usb))
|
||||||
device_control(device, usb, on);
|
device_control(device, usb, on);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
7
device.h
7
device.h
@@ -2,6 +2,7 @@
|
|||||||
#define __DEVICE_H__
|
#define __DEVICE_H__
|
||||||
|
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
|
#include "cdba.h"
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
|
|
||||||
struct cdb_assist;
|
struct cdb_assist;
|
||||||
@@ -76,6 +77,7 @@ struct device *device_open(const char *board,
|
|||||||
const char *username);
|
const char *username);
|
||||||
void device_close(struct device *dev);
|
void device_close(struct device *dev);
|
||||||
int device_power(struct device *device, bool on);
|
int device_power(struct device *device, bool on);
|
||||||
|
void device_key(struct device *device, int key, bool asserted);
|
||||||
|
|
||||||
void device_status_enable(struct device *device);
|
void device_status_enable(struct device *device);
|
||||||
void device_usb(struct device *device, bool on);
|
void device_usb(struct device *device, bool on);
|
||||||
@@ -93,11 +95,6 @@ void device_info(const char *username, const void *data, size_t dlen);
|
|||||||
void device_fastboot_continue(struct device *device);
|
void device_fastboot_continue(struct device *device);
|
||||||
bool device_is_running(struct device *device);
|
bool device_is_running(struct device *device);
|
||||||
|
|
||||||
enum {
|
|
||||||
DEVICE_KEY_FASTBOOT,
|
|
||||||
DEVICE_KEY_POWER,
|
|
||||||
};
|
|
||||||
|
|
||||||
extern const struct control_ops alpaca_ops;
|
extern const struct control_ops alpaca_ops;
|
||||||
extern const struct control_ops cdb_assist_ops;
|
extern const struct control_ops cdb_assist_ops;
|
||||||
extern const struct control_ops conmux_ops;
|
extern const struct control_ops conmux_ops;
|
||||||
|
|||||||
@@ -22,6 +22,11 @@ static void nextsym(struct device_parser *dp)
|
|||||||
{
|
{
|
||||||
if (!yaml_parser_parse(&dp->parser, &dp->event)) {
|
if (!yaml_parser_parse(&dp->parser, &dp->event)) {
|
||||||
fprintf(stderr, "device parser: error %u\n", dp->parser.error);
|
fprintf(stderr, "device parser: error %u\n", dp->parser.error);
|
||||||
|
fprintf(stderr,
|
||||||
|
"device parser: index %zu, line %zu, column %zu\n",
|
||||||
|
dp->parser.context_mark.index,
|
||||||
|
dp->parser.context_mark.line,
|
||||||
|
dp->parser.context_mark.column);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -43,6 +48,33 @@ int device_parser_accept(struct device_parser *dp, int type,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void decode_yaml_type_error(struct device_parser *dp, int type)
|
||||||
|
{
|
||||||
|
char event_type[11][26] = {
|
||||||
|
"YAML_NO_EVENT",
|
||||||
|
"YAML_STREAM_START_EVENT",
|
||||||
|
"YAML_STREAM_END_EVENT",
|
||||||
|
"YAML_DOCUMENT_START_EVENT",
|
||||||
|
"YAML_DOCUMENT_END_EVENT",
|
||||||
|
"YAML_ALIAS_EVENT",
|
||||||
|
"YAML_SCALAR_EVENT",
|
||||||
|
"YAML_SEQUENCE_START_EVENT",
|
||||||
|
"YAML_SEQUENCE_END_EVENT",
|
||||||
|
"YAML_MAPPING_START_EVENT",
|
||||||
|
"YAML_MAPPING_END_EVENT"
|
||||||
|
};
|
||||||
|
|
||||||
|
fprintf(stderr,
|
||||||
|
"device parser: expected %s got %s\n",
|
||||||
|
event_type[type],
|
||||||
|
event_type[dp->event.type]);
|
||||||
|
fprintf(stderr,
|
||||||
|
"device parser: index %zu, line %zu, column %zu\n",
|
||||||
|
dp->parser.mark.index,
|
||||||
|
dp->parser.mark.line,
|
||||||
|
dp->parser.mark.column);
|
||||||
|
}
|
||||||
|
|
||||||
bool device_parser_expect(struct device_parser *dp, int type,
|
bool device_parser_expect(struct device_parser *dp, int type,
|
||||||
char *scalar, size_t scalar_len)
|
char *scalar, size_t scalar_len)
|
||||||
{
|
{
|
||||||
@@ -50,7 +82,7 @@ bool device_parser_expect(struct device_parser *dp, int type,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stderr, "device parser: expected %d got %u\n", type, dp->event.type);
|
decode_yaml_type_error(dp, type);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,8 @@ enum {
|
|||||||
GPIO_POWER = 0, // Power input enable
|
GPIO_POWER = 0, // Power input enable
|
||||||
GPIO_FASTBOOT_KEY, // Usually volume key
|
GPIO_FASTBOOT_KEY, // Usually volume key
|
||||||
GPIO_POWER_KEY, // Key to power the device
|
GPIO_POWER_KEY, // Key to power the device
|
||||||
GPIO_USB_DISCONNECT, // Simulate main USB connection
|
GPIO_USB0_DISCONNECT, // Simulate main USB connection
|
||||||
|
GPIO_USB1_DISCONNECT, // Simulate secondary USB connection
|
||||||
GPIO_OUTPUT_ENABLE, // Enable FTDI signals to flow to the board
|
GPIO_OUTPUT_ENABLE, // Enable FTDI signals to flow to the board
|
||||||
GPIO_COUNT
|
GPIO_COUNT
|
||||||
};
|
};
|
||||||
@@ -131,7 +132,7 @@ static void ftdi_gpio_parse_config(struct ftdi_gpio_options *options, char *valu
|
|||||||
else if (strncmp("POWER_KEY", name, off - name - 1) == 0)
|
else if (strncmp("POWER_KEY", name, off - name - 1) == 0)
|
||||||
gpio_type = GPIO_POWER_KEY;
|
gpio_type = GPIO_POWER_KEY;
|
||||||
else if (strncmp("USB_DISCONNECT", name, off - name - 1) == 0)
|
else if (strncmp("USB_DISCONNECT", name, off - name - 1) == 0)
|
||||||
gpio_type = GPIO_USB_DISCONNECT;
|
gpio_type = GPIO_USB0_DISCONNECT;
|
||||||
else if (strncmp("OUTPUT_ENABLE", name, off - name - 1) == 0)
|
else if (strncmp("OUTPUT_ENABLE", name, off - name - 1) == 0)
|
||||||
gpio_type = GPIO_OUTPUT_ENABLE;
|
gpio_type = GPIO_OUTPUT_ENABLE;
|
||||||
else
|
else
|
||||||
@@ -182,7 +183,11 @@ void *ftdi_gpio_parse_options(struct device_parser *dp)
|
|||||||
} else if (!strcmp(key, "power_key")) {
|
} else if (!strcmp(key, "power_key")) {
|
||||||
gpio_id = GPIO_POWER_KEY;
|
gpio_id = GPIO_POWER_KEY;
|
||||||
} else if (!strcmp(key, "usb_disconnect")) {
|
} else if (!strcmp(key, "usb_disconnect")) {
|
||||||
gpio_id = GPIO_USB_DISCONNECT;
|
gpio_id = GPIO_USB0_DISCONNECT;
|
||||||
|
} else if (!strcmp(key, "usb0_disconnect")) {
|
||||||
|
gpio_id = GPIO_USB0_DISCONNECT;
|
||||||
|
} else if (!strcmp(key, "usb1_disconnect")) {
|
||||||
|
gpio_id = GPIO_USB1_DISCONNECT;
|
||||||
} else if (!strcmp(key, "output_enable")) {
|
} else if (!strcmp(key, "output_enable")) {
|
||||||
gpio_id = GPIO_OUTPUT_ENABLE;
|
gpio_id = GPIO_OUTPUT_ENABLE;
|
||||||
} else {
|
} else {
|
||||||
@@ -311,6 +316,9 @@ static void *ftdi_gpio_open(struct device *dev)
|
|||||||
if (ftdi_gpio->options->gpios[GPIO_POWER_KEY].present)
|
if (ftdi_gpio->options->gpios[GPIO_POWER_KEY].present)
|
||||||
dev->has_power_key = true;
|
dev->has_power_key = true;
|
||||||
|
|
||||||
|
if (ftdi_gpio->options->gpios[GPIO_OUTPUT_ENABLE].present)
|
||||||
|
ftdi_gpio_toggle_io(ftdi_gpio, GPIO_OUTPUT_ENABLE, 1);
|
||||||
|
|
||||||
ftdi_gpio_device_power(ftdi_gpio, 0);
|
ftdi_gpio_device_power(ftdi_gpio, 0);
|
||||||
|
|
||||||
if (dev->usb_always_on)
|
if (dev->usb_always_on)
|
||||||
@@ -318,9 +326,6 @@ static void *ftdi_gpio_open(struct device *dev)
|
|||||||
else
|
else
|
||||||
ftdi_gpio_device_usb(ftdi_gpio, 0);
|
ftdi_gpio_device_usb(ftdi_gpio, 0);
|
||||||
|
|
||||||
if (ftdi_gpio->options->gpios[GPIO_OUTPUT_ENABLE].present)
|
|
||||||
ftdi_gpio_toggle_io(ftdi_gpio, GPIO_OUTPUT_ENABLE, 1);
|
|
||||||
|
|
||||||
usleep(500000);
|
usleep(500000);
|
||||||
|
|
||||||
return ftdi_gpio;
|
return ftdi_gpio;
|
||||||
@@ -357,7 +362,8 @@ static int ftdi_gpio_device_power(struct ftdi_gpio *ftdi_gpio, bool on)
|
|||||||
|
|
||||||
static void ftdi_gpio_device_usb(struct ftdi_gpio *ftdi_gpio, bool on)
|
static void ftdi_gpio_device_usb(struct ftdi_gpio *ftdi_gpio, bool on)
|
||||||
{
|
{
|
||||||
ftdi_gpio_toggle_io(ftdi_gpio, GPIO_USB_DISCONNECT, on);
|
ftdi_gpio_toggle_io(ftdi_gpio, GPIO_USB0_DISCONNECT, on);
|
||||||
|
ftdi_gpio_toggle_io(ftdi_gpio, GPIO_USB1_DISCONNECT, on);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ftdi_gpio_power(struct device *dev, bool on)
|
static int ftdi_gpio_power(struct device *dev, bool on)
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ struct laurent_options {
|
|||||||
const char *server;
|
const char *server;
|
||||||
const char *password;
|
const char *password;
|
||||||
unsigned int relay;
|
unsigned int relay;
|
||||||
|
int usb_relay;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct laurent {
|
struct laurent {
|
||||||
@@ -42,6 +43,7 @@ void *laurent_parse_options(struct device_parser *dp)
|
|||||||
|
|
||||||
options = calloc(1, sizeof(*options));
|
options = calloc(1, sizeof(*options));
|
||||||
options->password = DEFAULT_PASSWORD;
|
options->password = DEFAULT_PASSWORD;
|
||||||
|
options->usb_relay = -1;
|
||||||
|
|
||||||
device_parser_accept(dp, YAML_MAPPING_START_EVENT, NULL, 0);
|
device_parser_accept(dp, YAML_MAPPING_START_EVENT, NULL, 0);
|
||||||
while (device_parser_accept(dp, YAML_SCALAR_EVENT, key, TOKEN_LENGTH)) {
|
while (device_parser_accept(dp, YAML_SCALAR_EVENT, key, TOKEN_LENGTH)) {
|
||||||
@@ -54,6 +56,8 @@ void *laurent_parse_options(struct device_parser *dp)
|
|||||||
options->password = strdup(value);
|
options->password = strdup(value);
|
||||||
else if (!strcmp(key, "relay"))
|
else if (!strcmp(key, "relay"))
|
||||||
options->relay = strtoul(value, NULL, 0);
|
options->relay = strtoul(value, NULL, 0);
|
||||||
|
else if (!strcmp(key, "usb_relay"))
|
||||||
|
options->usb_relay = strtoul(value, NULL, 0);
|
||||||
else
|
else
|
||||||
errx(1, "%s: unknown option \"%s\"", __func__, key);
|
errx(1, "%s: unknown option \"%s\"", __func__, key);
|
||||||
}
|
}
|
||||||
@@ -124,7 +128,7 @@ static void *laurent_open(struct device *dev)
|
|||||||
return laurent;
|
return laurent;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int laurent_power(struct device *dev, bool on)
|
static int laurent_control(struct device *dev, unsigned int relay, bool on)
|
||||||
{
|
{
|
||||||
struct laurent *laurent = dev->cdb;
|
struct laurent *laurent = dev->cdb;
|
||||||
char buf[BUFSIZ];
|
char buf[BUFSIZ];
|
||||||
@@ -145,7 +149,7 @@ static int laurent_power(struct device *dev, bool on)
|
|||||||
|
|
||||||
len = snprintf(buf, sizeof(buf), "GET /cmd.cgi?psw=%s&cmd=REL,%u,%d HTTP/1.0\r\n\r\n",
|
len = snprintf(buf, sizeof(buf), "GET /cmd.cgi?psw=%s&cmd=REL,%u,%d HTTP/1.0\r\n\r\n",
|
||||||
laurent->options->password,
|
laurent->options->password,
|
||||||
laurent->options->relay,
|
relay,
|
||||||
on);
|
on);
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
warn("asprintf failed\n");
|
warn("asprintf failed\n");
|
||||||
@@ -190,8 +194,30 @@ err:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int laurent_power(struct device *dev, bool on)
|
||||||
|
{
|
||||||
|
struct laurent *laurent = dev->cdb;
|
||||||
|
|
||||||
|
return laurent_control(dev,
|
||||||
|
laurent->options->relay,
|
||||||
|
on);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void laurent_usb(struct device *dev, bool on)
|
||||||
|
{
|
||||||
|
struct laurent *laurent = dev->cdb;
|
||||||
|
|
||||||
|
if (laurent->options->usb_relay < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
laurent_control(dev,
|
||||||
|
laurent->options->usb_relay,
|
||||||
|
on);
|
||||||
|
}
|
||||||
|
|
||||||
const struct control_ops laurent_ops = {
|
const struct control_ops laurent_ops = {
|
||||||
.parse_options = laurent_parse_options,
|
.parse_options = laurent_parse_options,
|
||||||
.open = laurent_open,
|
.open = laurent_open,
|
||||||
.power = laurent_power,
|
.power = laurent_power,
|
||||||
|
.usb = laurent_usb,
|
||||||
};
|
};
|
||||||
|
|||||||
11
schema.yaml
11
schema.yaml
@@ -26,7 +26,7 @@ properties:
|
|||||||
fastboot:
|
fastboot:
|
||||||
description: fastboot id
|
description: fastboot id
|
||||||
type: string
|
type: string
|
||||||
pattern: "^[0-9a-f]{8}$"
|
pattern: "^[0-9a-f]{8,16}$"
|
||||||
|
|
||||||
fastboot_set_active:
|
fastboot_set_active:
|
||||||
description: run fastboot set active before each boot, slot can be selected
|
description: run fastboot set active before each boot, slot can be selected
|
||||||
@@ -124,8 +124,9 @@ properties:
|
|||||||
devicenode:
|
devicenode:
|
||||||
$ref: "#/$defs/device_path"
|
$ref: "#/$defs/device_path"
|
||||||
patternProperties:
|
patternProperties:
|
||||||
"^power|fastboot_key|power_key|usb_disconnect|output_enable$":
|
"^power|fastboot_key|power_key|usb[01]?_disconnect|output_enable$":
|
||||||
$ref: "#/$defs/ftdi_gpio"
|
$ref: "#/$defs/ftdi_gpio"
|
||||||
|
additionalProperties: false
|
||||||
|
|
||||||
dependentRequired:
|
dependentRequired:
|
||||||
index:
|
index:
|
||||||
@@ -138,7 +139,7 @@ properties:
|
|||||||
local_gpio:
|
local_gpio:
|
||||||
description: Local GPIO
|
description: Local GPIO
|
||||||
type: object
|
type: object
|
||||||
unevaluatedItems: false
|
additionalProperties: false
|
||||||
patternProperties:
|
patternProperties:
|
||||||
"^power|fastboot_key|power_key|usb_disconnect$":
|
"^power|fastboot_key|power_key|usb_disconnect$":
|
||||||
$ref: "#/$defs/local_gpio"
|
$ref: "#/$defs/local_gpio"
|
||||||
@@ -146,12 +147,14 @@ properties:
|
|||||||
laurent:
|
laurent:
|
||||||
description: KernelChip Laurent relays
|
description: KernelChip Laurent relays
|
||||||
type: object
|
type: object
|
||||||
unevaluatedItems: false
|
additionalProperties: false
|
||||||
properties:
|
properties:
|
||||||
server:
|
server:
|
||||||
type: string
|
type: string
|
||||||
relay:
|
relay:
|
||||||
type: integer
|
type: integer
|
||||||
|
usb_relay:
|
||||||
|
type: integer
|
||||||
password:
|
password:
|
||||||
description: password to access the relays, defaults to 'Laurent'
|
description: password to access the relays, defaults to 'Laurent'
|
||||||
type: string
|
type: string
|
||||||
|
|||||||
3
status.c
3
status.c
@@ -43,7 +43,8 @@ void status_send_values(const char *id, struct status_value *values)
|
|||||||
|
|
||||||
status_get_ts(&ts);
|
status_get_ts(&ts);
|
||||||
|
|
||||||
len = snprintf(buf, sizeof(buf), "{\"ts\":%ld.%03ld, \"%s\":{ ", ts.tv_sec, ts.tv_nsec / 1000000, id);
|
len = snprintf(buf, sizeof(buf), "{\"ts\":%lld.%03ld, \"%s\":{ ",
|
||||||
|
(long long int)ts.tv_sec, ts.tv_nsec / 1000000, id);
|
||||||
|
|
||||||
for (value = values; value->unit; value++) {
|
for (value = values; value->unit; value++) {
|
||||||
if (value != values) {
|
if (value != values) {
|
||||||
|
|||||||
Reference in New Issue
Block a user