feat(legacy/emulator): avoid busy loop when waiting for messages

pull/1750/head
matejcik 3 years ago committed by matejcik
parent 1d4c061e3e
commit 33a9a14eab

@ -30,7 +30,8 @@ void emulatorPoll(void);
void emulatorRandom(void *buffer, size_t size); void emulatorRandom(void *buffer, size_t size);
void emulatorSocketInit(void); void emulatorSocketInit(void);
size_t emulatorSocketRead(int *iface, void *buffer, size_t size); size_t emulatorSocketRead(int *iface, void *buffer, size_t size,
int timeout_ms);
size_t emulatorSocketWrite(int iface, const void *buffer, size_t size); size_t emulatorSocketWrite(int iface, const void *buffer, size_t size);
#endif #endif

@ -19,6 +19,7 @@
#include <arpa/inet.h> #include <arpa/inet.h>
#include <errno.h> #include <errno.h>
#include <poll.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -35,6 +36,8 @@ struct usb_socket {
static struct usb_socket usb_main; static struct usb_socket usb_main;
static struct usb_socket usb_debug; static struct usb_socket usb_debug;
static struct pollfd usb_fds[2];
static int socket_setup(int port) { static int socket_setup(int port) {
int fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); int fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (fd < 0) { if (fd < 0) {
@ -96,23 +99,26 @@ static size_t socket_read(struct usb_socket *sock, void *buffer, size_t size) {
void emulatorSocketInit(void) { void emulatorSocketInit(void) {
usb_main.fd = socket_setup(TREZOR_UDP_PORT); usb_main.fd = socket_setup(TREZOR_UDP_PORT);
usb_main.fromlen = 0; usb_main.fromlen = 0;
usb_fds[0].fd = usb_main.fd;
usb_fds[0].events = POLLIN;
usb_debug.fd = socket_setup(TREZOR_UDP_PORT + 1); usb_debug.fd = socket_setup(TREZOR_UDP_PORT + 1);
usb_debug.fromlen = 0; usb_debug.fromlen = 0;
usb_fds[1].fd = usb_debug.fd;
usb_fds[1].events = POLLIN;
} }
size_t emulatorSocketRead(int *iface, void *buffer, size_t size) { size_t emulatorSocketRead(int *iface, void *buffer, size_t size,
size_t n = socket_read(&usb_main, buffer, size); int timeout_ms) {
if (n > 0) { if (poll(usb_fds, 2, timeout_ms) > 0) {
*iface = 0; if (usb_fds[0].revents & POLLIN) {
return n; *iface = 0;
} return socket_read(&usb_main, buffer, size);
} else if (usb_fds[1].revents & POLLIN) {
n = socket_read(&usb_debug, buffer, size); *iface = 1;
if (n > 0) { return socket_read(&usb_debug, buffer, size);
*iface = 1; }
return n;
} }
return 0; return 0;
} }

@ -0,0 +1 @@
Emulator properly waits for IO without busy loop

@ -157,7 +157,11 @@ int main(void) {
layoutHome(); layoutHome();
usbInit(); usbInit();
for (;;) { for (;;) {
#if EMULATOR
usbSleep(10);
#else
usbPoll(); usbPoll();
#endif
check_lock_screen(); check_lock_screen();
} }

@ -35,43 +35,38 @@ void usbInit(void) { emulatorSocketInit(); }
#define _ISDBG ('n') #define _ISDBG ('n')
#endif #endif
void usbPoll(void) { void usbSleep(uint32_t millis) {
emulatorPoll(); emulatorPoll();
static uint8_t buffer[USB_PACKET_SIZE]; static uint8_t buffer[USB_PACKET_SIZE];
int iface = 0; int iface = 0;
if (emulatorSocketRead(&iface, buffer, sizeof(buffer)) > 0) { if (emulatorSocketRead(&iface, buffer, sizeof(buffer), millis) > 0) {
if (!tiny) { if (!tiny) {
msg_read_common(_ISDBG, buffer, sizeof(buffer)); do {
msg_read_common(_ISDBG, buffer, sizeof(buffer));
} while (emulatorSocketRead(&iface, buffer, sizeof(buffer), 0) > 0);
} else { } else {
msg_read_tiny(buffer, sizeof(buffer)); msg_read_tiny(buffer, sizeof(buffer));
} }
} }
const uint8_t *data = msg_out_data(); const uint8_t *data;
if (data != NULL) { while ((data = msg_out_data()) != NULL) {
emulatorSocketWrite(0, data, USB_PACKET_SIZE); emulatorSocketWrite(0, data, USB_PACKET_SIZE);
} }
#if DEBUG_LINK #if DEBUG_LINK
data = msg_debug_out_data(); while ((data = msg_debug_out_data()) != NULL) {
if (data != NULL) {
emulatorSocketWrite(1, data, USB_PACKET_SIZE); emulatorSocketWrite(1, data, USB_PACKET_SIZE);
} }
#endif #endif
} }
void usbPoll(void) { usbSleep(0); }
char usbTiny(char set) { char usbTiny(char set) {
char old = tiny; char old = tiny;
tiny = set; tiny = set;
return old; return old;
} }
void usbSleep(uint32_t millis) {
uint32_t start = timer_ms();
while ((timer_ms() - start) < millis) {
usbPoll();
}
}

Loading…
Cancel
Save