diff --git a/cdba-server.c b/cdba-server.c index c463f19..72b00eb 100644 --- a/cdba-server.c +++ b/cdba-server.c @@ -99,6 +99,28 @@ static void msg_fastboot_continue(void) 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) { struct msg msg = { @@ -185,6 +207,9 @@ static int handle_stdin(int fd, void *buf) case MSG_FASTBOOT_CONTINUE: msg_fastboot_continue(); break; + case MSG_KEY_PRESS: + msg_key_press(msg->data, msg->len); + break; default: fprintf(stderr, "unk %d len %d\n", msg->type, msg->len); exit(1); diff --git a/cdba.c b/cdba.c index ee3809f..d1589cd 100644 --- a/cdba.c +++ b/cdba.c @@ -143,8 +143,25 @@ static int cdba_send_buf(int fd, int type, size_t len, const void *buf) 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 bool key_state[DEVICE_KEY_COUNT]; static const char ctrl_a = 0x1; static bool special; char buf[32]; @@ -184,6 +201,18 @@ static int tty_callback(int *ssh_fds) case 'B': cdba_send(ssh_fds[0], MSG_SEND_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; diff --git a/cdba.h b/cdba.h index 0264c40..e70c998 100644 --- a/cdba.h +++ b/cdba.h @@ -31,6 +31,24 @@ enum { MSG_LIST_DEVICES, MSG_BOARD_INFO, 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 diff --git a/device.c b/device.c index 79856bb..fa81940 100644 --- a/device.c +++ b/device.c @@ -163,7 +163,7 @@ static void device_impl_power(struct device *device, bool 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)) device_control(device, key, key, asserted); diff --git a/device.h b/device.h index 75a780a..e465ea5 100644 --- a/device.h +++ b/device.h @@ -2,6 +2,7 @@ #define __DEVICE_H__ #include +#include "cdba.h" #include "list.h" struct cdb_assist; @@ -76,6 +77,7 @@ struct device *device_open(const char *board, const char *username); void device_close(struct device *dev); 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_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); 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 cdb_assist_ops; extern const struct control_ops conmux_ops;