Skip to content

Commit 3922dc7

Browse files
committed
cdba: Add keys to remotely press power or fastboot key
Add special keys to allow triggering power and fastboot key presses from the cdba client. There is an option to send a short key "pulse" (press followed by release after 100ms) or to press/release keys separately: - ctrl+a -> o: Send power key pulse - ctrl+a -> O: Toggle power key (first use: press, next use: release) - ctrl+a -> f: Send fastboot key pulse - ctrl+a -> F: Toggle fastboot key (first use: press, next use: release) In most cases you want to send the "pulse" (short key press), so it's helpful to have this mapped to a single key. This avoids forgetting to release the key again after pressing it. The protocol between CDBA client and server is: (MSG_KEY_PRESS <key:u8, state:u8>) where key is either DEVICE_KEY_FASTBOOT (0) or DEVICE_KEY_POWER (1) and state is either KEY_PRESS_RELEASE (0), KEY_PRESS_PRESS (1) or KEY_PRESS_PULSE (2). The reason for implementing the "pulse" on the server side is that it's hard to guarantee the timing on the client side. We don't know exactly when the packets will arrive on the server. Also, "state" is a full byte anyway, so might as well use some of the extra bits. :-)
1 parent 61babbf commit 3922dc7

File tree

5 files changed

+75
-6
lines changed

5 files changed

+75
-6
lines changed

cdba-server.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,28 @@ static void msg_fastboot_continue(void)
9999
cdba_send(MSG_FASTBOOT_CONTINUE);
100100
}
101101

102+
static void msg_key_release(void *data)
103+
{
104+
int key = (int)(uintptr_t)data;
105+
106+
device_key(selected_device, key, false);
107+
}
108+
109+
static void msg_key_press(const void *data, size_t len)
110+
{
111+
const struct key_press *press = data;
112+
113+
if (len != sizeof(*press))
114+
return;
115+
116+
if (press->state == KEY_PRESS_PULSE) {
117+
device_key(selected_device, press->key, true);
118+
watch_timer_add(100, msg_key_release, (void*)(uintptr_t)press->key);
119+
} else {
120+
device_key(selected_device, press->key, !!press->state);
121+
}
122+
}
123+
102124
void cdba_send_buf(int type, size_t len, const void *buf)
103125
{
104126
struct msg msg = {
@@ -185,6 +207,9 @@ static int handle_stdin(int fd, void *buf)
185207
case MSG_FASTBOOT_CONTINUE:
186208
msg_fastboot_continue();
187209
break;
210+
case MSG_KEY_PRESS:
211+
msg_key_press(msg->data, msg->len);
212+
break;
188213
default:
189214
fprintf(stderr, "unk %d len %d\n", msg->type, msg->len);
190215
exit(1);

cdba.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,25 @@ static int cdba_send_buf(int fd, int type, size_t len, const void *buf)
143143
return ret < 0 ? ret : 0;
144144
}
145145

146+
static int cdba_send_key(int fd, int key, uint8_t state)
147+
{
148+
struct key_press press = {
149+
.key = key,
150+
.state = state,
151+
};
152+
153+
return cdba_send_buf(fd, MSG_KEY_PRESS, sizeof(press), &press);
154+
}
155+
156+
static int cdba_toggle_key(int fd, int key, bool key_state[DEVICE_KEY_COUNT])
157+
{
158+
key_state[key] = !key_state[key];
159+
return cdba_send_key(fd, key, key_state[key]);
160+
}
161+
146162
static int tty_callback(int *ssh_fds)
147163
{
164+
static bool key_state[DEVICE_KEY_COUNT];
148165
static const char ctrl_a = 0x1;
149166
static bool special;
150167
char buf[32];
@@ -184,6 +201,18 @@ static int tty_callback(int *ssh_fds)
184201
case 'B':
185202
cdba_send(ssh_fds[0], MSG_SEND_BREAK);
186203
break;
204+
case 'o':
205+
cdba_send_key(ssh_fds[0], DEVICE_KEY_POWER, KEY_PRESS_PULSE);
206+
break;
207+
case 'O':
208+
cdba_toggle_key(ssh_fds[0], DEVICE_KEY_POWER, key_state);
209+
break;
210+
case 'f':
211+
cdba_send_key(ssh_fds[0], DEVICE_KEY_FASTBOOT, KEY_PRESS_PULSE);
212+
break;
213+
case 'F':
214+
cdba_toggle_key(ssh_fds[0], DEVICE_KEY_FASTBOOT, key_state);
215+
break;
187216
}
188217

189218
special = false;

cdba.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,24 @@ enum {
3131
MSG_LIST_DEVICES,
3232
MSG_BOARD_INFO,
3333
MSG_FASTBOOT_CONTINUE,
34+
MSG_KEY_PRESS,
35+
};
36+
37+
struct key_press {
38+
uint8_t key;
39+
uint8_t state;
40+
} __packed;
41+
42+
enum {
43+
DEVICE_KEY_FASTBOOT,
44+
DEVICE_KEY_POWER,
45+
DEVICE_KEY_COUNT
46+
};
47+
48+
enum {
49+
KEY_PRESS_RELEASE,
50+
KEY_PRESS_PRESS,
51+
KEY_PRESS_PULSE,
3452
};
3553

3654
#endif

device.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ static void device_impl_power(struct device *device, bool on)
163163
device_control(device, power, on);
164164
}
165165

166-
static void device_key(struct device *device, int key, bool asserted)
166+
void device_key(struct device *device, int key, bool asserted)
167167
{
168168
if (device_has_control(device, key))
169169
device_control(device, key, key, asserted);

device.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define __DEVICE_H__
33

44
#include <termios.h>
5+
#include "cdba.h"
56
#include "list.h"
67

78
struct cdb_assist;
@@ -76,6 +77,7 @@ struct device *device_open(const char *board,
7677
const char *username);
7778
void device_close(struct device *dev);
7879
int device_power(struct device *device, bool on);
80+
void device_key(struct device *device, int key, bool asserted);
7981

8082
void device_status_enable(struct device *device);
8183
void device_usb(struct device *device, bool on);
@@ -93,11 +95,6 @@ void device_info(const char *username, const void *data, size_t dlen);
9395
void device_fastboot_continue(struct device *device);
9496
bool device_is_running(struct device *device);
9597

96-
enum {
97-
DEVICE_KEY_FASTBOOT,
98-
DEVICE_KEY_POWER,
99-
};
100-
10198
extern const struct control_ops alpaca_ops;
10299
extern const struct control_ops cdb_assist_ops;
103100
extern const struct control_ops conmux_ops;

0 commit comments

Comments
 (0)